[DEV] Correct synchonizer

This commit is contained in:
Edouard DUPIN 2015-02-18 15:22:48 +01:00
parent 4832570448
commit d0bcaed9db
10 changed files with 93 additions and 17 deletions

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
};
};

View File

@ -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)");
}

View File

@ -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);
};
}
}

View File

@ -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";
}

View File

@ -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);
};
}
}

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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();
}