diff --git a/river/CircularBuffer.cpp b/river/CircularBuffer.cpp index 37decca..c648eda 100644 --- a/river/CircularBuffer.cpp +++ b/river/CircularBuffer.cpp @@ -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(); } diff --git a/river/Manager.cpp b/river/Manager.cpp index 05f05fe..1008a9c 100644 --- a/river/Manager.cpp +++ b/river/Manager.cpp @@ -153,3 +153,13 @@ std::shared_ptr 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 manager = river::io::Manager::getInstance(); + if (manager == nullptr) { + RIVER_ERROR("Can not get the harware manager"); + return; + } + manager->generateDot(_filename); +} \ No newline at end of file diff --git a/river/Manager.h b/river/Manager.h index d208d96..1931e79 100644 --- a/river/Manager.h +++ b/river/Manager.h @@ -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); }; }; diff --git a/river/io/Manager.cpp b/river/io/Manager.cpp index 65baf39..68456a0 100644 --- a/river/io/Manager.cpp +++ b/river/io/Manager.cpp @@ -10,6 +10,7 @@ #include "Node.h" #include "NodeAEC.h" #include "NodeAirTAudio.h" +#include #undef __class__ #define __class__ "io::Manager" @@ -142,3 +143,24 @@ float river::io::Manager::getVolume(const std::string& _volumeName) { std::pair river::io::Manager::getVolumeRange(const std::string& _volumeName) const { return std::make_pair(-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 val = it2.lock(); + if (val != nullptr) { + val->generateDot(node); + id++; + } + } + node << "}" << "\n"; + node.fileClose(); + RIVER_INFO("Generate the DOT files: " << node << " (DONE)"); +} diff --git a/river/io/Manager.h b/river/io/Manager.h index 4e0fdd2..bcecdbe 100644 --- a/river/io/Manager.h +++ b/river/io/Manager.h @@ -68,6 +68,11 @@ namespace river { * @example ret = getVolumeRange("MASTER"); can return something like ret=(-120.0f,0.0f) */ virtual std::pair 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); }; } } diff --git a/river/io/Node.cpp b/river/io/Node.cpp index 4ba8bac..11c4f15 100644 --- a/river/io/Node.cpp +++ b/river/io/Node.cpp @@ -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"; +} + diff --git a/river/io/Node.h b/river/io/Node.h index d622b27..8d134d2 100644 --- a/river/io/Node.h +++ b/river/io/Node.h @@ -21,6 +21,7 @@ #include #include #include +#include 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); }; } } diff --git a/river/io/NodeAEC.cpp b/river/io/NodeAEC.cpp index 15f3cfe..38b59bb 100644 --- a/river/io/NodeAEC.cpp +++ b/river/io/NodeAEC.cpp @@ -127,6 +127,7 @@ river::io::NodeAEC::NodeAEC(const std::string& _name, const std::shared_ptr 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; } diff --git a/river/io/NodeAEC.h b/river/io/NodeAEC.h index 1d6d562..e63dc2d 100644 --- a/river/io/NodeAEC.h +++ b/river/io/NodeAEC.h @@ -50,6 +50,7 @@ namespace river { const std::vector& _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); }; diff --git a/test/main.cpp b/test/main.cpp index bbc888c..3735292 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -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(); }