[DEV] Correct synchonizer
This commit is contained in:
parent
4832570448
commit
d0bcaed9db
@ -239,10 +239,11 @@ void river::CircularBuffer::setReadPosition(const std::chrono::system_clock::tim
|
||||
size_t usedSizeBeforeEnd = getUsedSizeBeforEnd();
|
||||
if (0 < m_size) {
|
||||
// check the time of the read :
|
||||
std::chrono::nanoseconds deltaTime = m_timeRead - _time;
|
||||
size_t nbSampleToRemove = m_frequency*-deltaTime.count()/100000000;
|
||||
std::chrono::nanoseconds deltaTime = _time - m_timeRead;
|
||||
size_t nbSampleToRemove = m_frequency*deltaTime.count()/1000000000;
|
||||
nbSampleToRemove = std::min(nbSampleToRemove, m_size);
|
||||
RIVER_WARNING("Remove sample in the buffer " << nbSampleToRemove << " / " << m_size);
|
||||
std::chrono::nanoseconds updateTime((nbSampleToRemove*1000000000)/int64_t(m_frequency));
|
||||
if (usedSizeBeforeEnd >= nbSampleToRemove) {
|
||||
usedSizeBeforeEnd -= nbSampleToRemove;
|
||||
m_size -= nbSampleToRemove;
|
||||
@ -252,7 +253,8 @@ void river::CircularBuffer::setReadPosition(const std::chrono::system_clock::tim
|
||||
m_size -= nbSampleToRemove;
|
||||
m_read = &m_data[0] + nbSampleToRemove*m_sizeChunk;
|
||||
}
|
||||
m_timeRead += deltaTime;
|
||||
m_timeRead += updateTime;
|
||||
//m_timeRead += deltaTime;
|
||||
} else {
|
||||
m_timeRead = std::chrono::system_clock::time_point();
|
||||
}
|
||||
|
@ -153,3 +153,13 @@ std::shared_ptr<river::Interface> river::Manager::createInput(float _freq,
|
||||
m_listOpenInterface.push_back(interface);
|
||||
return interface;
|
||||
}
|
||||
|
||||
void river::Manager::generateDotAll(const std::string& _filename) {
|
||||
// get global hardware interface:
|
||||
std::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
|
||||
if (manager == nullptr) {
|
||||
RIVER_ERROR("Can not get the harware manager");
|
||||
return;
|
||||
}
|
||||
manager->generateDot(_filename);
|
||||
}
|
@ -99,6 +99,11 @@ namespace river {
|
||||
audio::format _format,
|
||||
const std::string& _streamName = "",
|
||||
const std::string& _name = "");
|
||||
/**
|
||||
* @brief Generate the dot file corresponding at all the actif nodes.
|
||||
* @param[in] _filename Name of the file to write data.
|
||||
*/
|
||||
virtual void generateDotAll(const std::string& _filename);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "Node.h"
|
||||
#include "NodeAEC.h"
|
||||
#include "NodeAirTAudio.h"
|
||||
#include <etk/os/FSNode.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "io::Manager"
|
||||
@ -142,3 +143,24 @@ float river::io::Manager::getVolume(const std::string& _volumeName) {
|
||||
std::pair<float,float> river::io::Manager::getVolumeRange(const std::string& _volumeName) const {
|
||||
return std::make_pair<float,float>(-300, 300);
|
||||
}
|
||||
|
||||
void river::io::Manager::generateDot(const std::string& _filename) {
|
||||
etk::FSNode node(_filename);
|
||||
RIVER_INFO("Generate the DOT files: " << node);
|
||||
if (node.fileOpenWrite() == false) {
|
||||
RIVER_ERROR("Can not Write the dot file (fail to open) : " << node);
|
||||
return;
|
||||
}
|
||||
node << "digraph G {" << "\n";
|
||||
int32_t id = 0;
|
||||
for (auto &it2 : m_list) {
|
||||
std::shared_ptr<river::io::Node> val = it2.lock();
|
||||
if (val != nullptr) {
|
||||
val->generateDot(node);
|
||||
id++;
|
||||
}
|
||||
}
|
||||
node << "}" << "\n";
|
||||
node.fileClose();
|
||||
RIVER_INFO("Generate the DOT files: " << node << " (DONE)");
|
||||
}
|
||||
|
@ -68,6 +68,11 @@ namespace river {
|
||||
* @example ret = getVolumeRange("MASTER"); can return something like ret=(-120.0f,0.0f)
|
||||
*/
|
||||
virtual std::pair<float,float> getVolumeRange(const std::string& _volumeName) const;
|
||||
/**
|
||||
* @brief Generate the dot file corresponding at the actif nodes.
|
||||
* @param[in] _filename Name of the file to write data.
|
||||
*/
|
||||
virtual void generateDot(const std::string& _filename);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -223,3 +223,25 @@ int32_t river::io::Node::newOutput(void* _outputBuffer,
|
||||
RIVER_VERBOSE("data Output size request :" << _nbChunk << " [ END ]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void river::io::Node::generateDot(etk::FSNode& _node) {
|
||||
_node << "subgraph cluster_0 {\n";
|
||||
// configure display:
|
||||
_node << " node [shape=record, fontname=Helvetica, fontsize=10, color=lightsteelblue1, style=filled];\n";
|
||||
//_node << " node [shape=diamond, fontname=Helvetica, fontsize=10, color=orangered, style=filled];\n"
|
||||
//_node << " node [shape=ellipse, fontname=Helvetica, fontsize=8, color=aquamarine2, style=filled];\n";
|
||||
// add elements
|
||||
int32_t idNode = 0;
|
||||
_node << " NODE_" << idNode << " [ label=\"name=" << m_name << "\" ];\n";
|
||||
// add IO
|
||||
_node << " node [shape=ellipse, fontname=Helvetica, fontsize=8, color=aquamarine2, style=filled];\n";
|
||||
int32_t id = 0;
|
||||
for (auto &it : m_list) {
|
||||
if (it != nullptr) {
|
||||
_node << " interface_" << id << " [ label=\"name=" << it->getName() << "\" ];\n";
|
||||
_node << " NODE_" << idNode << " -> interface_" << id << " [ arrowhead=\"open\"];\n";
|
||||
}
|
||||
}
|
||||
_node << "}\n";
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <airtaudio/Interface.h>
|
||||
#include <drain/IOFormatInterface.h>
|
||||
#include <drain/Volume.h>
|
||||
#include <etk/os/FSNode.h>
|
||||
|
||||
namespace river {
|
||||
namespace io {
|
||||
@ -99,6 +100,9 @@ namespace river {
|
||||
int32_t newOutput(void* _outputBuffer,
|
||||
uint32_t _nbChunk,
|
||||
const std::chrono::system_clock::time_point& _time);
|
||||
|
||||
public:
|
||||
virtual void generateDot(etk::FSNode& _node);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ river::io::NodeAEC::NodeAEC(const std::string& _name, const std::shared_ptr<cons
|
||||
Node(_name, _config) {
|
||||
drain::IOFormatInterface interfaceFormat = getInterfaceFormat();
|
||||
drain::IOFormatInterface hardwareFormat = getHarwareFormat();
|
||||
m_sampleTime = std::chrono::nanoseconds(1000000000*int64_t(hardwareFormat.getFrequency()));
|
||||
/**
|
||||
# connect in input mode
|
||||
map-on-microphone:{
|
||||
@ -311,20 +312,21 @@ void river::io::NodeAEC::process() {
|
||||
std::chrono::system_clock::time_point MicTime = m_bufferMicrophone.getReadTimeStamp();
|
||||
std::chrono::system_clock::time_point fbTime = m_bufferFeedBack.getReadTimeStamp();
|
||||
|
||||
// Synchronize if possible
|
||||
if (MicTime < fbTime) {
|
||||
RIVER_INFO("micTime < fbTime : Change Microphone time start " << fbTime);
|
||||
RIVER_INFO(" old time stamp=" << m_bufferMicrophone.getReadTimeStamp());
|
||||
m_bufferMicrophone.setReadPosition(fbTime);
|
||||
RIVER_INFO(" new time stamp=" << m_bufferMicrophone.getReadTimeStamp());
|
||||
if (MicTime-fbTime > m_sampleTime) {
|
||||
// Synchronize if possible
|
||||
if (MicTime < fbTime) {
|
||||
RIVER_INFO("micTime < fbTime : Change Microphone time start " << fbTime);
|
||||
RIVER_INFO(" old time stamp=" << m_bufferMicrophone.getReadTimeStamp());
|
||||
m_bufferMicrophone.setReadPosition(fbTime);
|
||||
RIVER_INFO(" new time stamp=" << m_bufferMicrophone.getReadTimeStamp());
|
||||
}
|
||||
if (MicTime > fbTime) {
|
||||
RIVER_INFO("micTime > fbTime : Change FeedBack time start " << MicTime);
|
||||
RIVER_INFO(" old time stamp=" << m_bufferFeedBack.getReadTimeStamp());
|
||||
m_bufferFeedBack.setReadPosition(MicTime);
|
||||
RIVER_INFO(" new time stamp=" << m_bufferFeedBack.getReadTimeStamp());
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (MicTime > fbTime) {
|
||||
RIVER_INFO("micTime > fbTime : Change FeedBack time start " << fbTime);
|
||||
RIVER_INFO(" old time stamp=" << m_bufferFeedBack.getReadTimeStamp());
|
||||
m_bufferFeedBack.setReadPosition(MicTime);
|
||||
RIVER_INFO(" new time stamp=" << m_bufferFeedBack.getReadTimeStamp());
|
||||
}*/
|
||||
// check if enought time after synchronisation ...
|
||||
if (m_bufferMicrophone.getSize() <= 256) {
|
||||
return;
|
||||
@ -336,7 +338,7 @@ void river::io::NodeAEC::process() {
|
||||
MicTime = m_bufferMicrophone.getReadTimeStamp();
|
||||
fbTime = m_bufferFeedBack.getReadTimeStamp();
|
||||
|
||||
if (MicTime != fbTime) {
|
||||
if (MicTime-fbTime > m_sampleTime) {
|
||||
RIVER_ERROR("Can not synchronize flow ... : " << MicTime << " != " << fbTime << " delta = " << (MicTime-fbTime).count()/1000 << " µs");
|
||||
return;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ namespace river {
|
||||
const std::vector<audio::channel>& _map);
|
||||
river::CircularBuffer m_bufferMicrophone;
|
||||
river::CircularBuffer m_bufferFeedBack;
|
||||
std::chrono::nanoseconds m_sampleTime; //!< represent the sample time at the specify frequency.
|
||||
void process();
|
||||
void processAEC(void* _dataMic, void* _dataFB, uint32_t _nbChunk, const std::chrono::system_clock::time_point& _time);
|
||||
};
|
||||
|
@ -339,6 +339,8 @@ class testInCallback {
|
||||
m_interface->start();
|
||||
// wait 2 second ...
|
||||
usleep(2000000);
|
||||
|
||||
m_manager->generateDotAll("activeProcess.dot");
|
||||
m_interface->stop();
|
||||
}
|
||||
};
|
||||
@ -625,6 +627,7 @@ TEST(TestALL, testInputCallBackMicClean) {
|
||||
process->run();
|
||||
process.reset();
|
||||
usleep(500000);
|
||||
tmpThread.join();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user