From d6cc8fce3b4ee2002cfb6a01f85dec57619f6582 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 3 Feb 2015 21:29:23 +0100 Subject: [PATCH] [DEV] add parameter set and file hardware config file read --- airtio/Interface.cpp | 50 ++++++++++++++++-- airtio/Interface.h | 4 +- airtio/Manager.cpp | 4 +- airtio/io/Manager.cpp | 46 +++++++++++++--- airtio/io/Manager.h | 15 ++++-- airtio/io/Node.cpp | 119 ++++++++++++++++++++++++++++++++++-------- airtio/io/Node.h | 15 ++++-- data/hardware.json | 5 +- lutin_airtio.py | 2 +- lutin_airtio_test.py | 1 + test/main.cpp | 96 +++++++++++++++++++++++++++++++--- 11 files changed, 302 insertions(+), 55 deletions(-) diff --git a/airtio/Interface.cpp b/airtio/Interface.cpp index 6e4e942..f1bcf7f 100644 --- a/airtio/Interface.cpp +++ b/airtio/Interface.cpp @@ -47,6 +47,11 @@ bool airtio::Interface::init(const std::string& _name, algo->setName("volume"); m_process->pushBack(algo); AIRTIO_INFO("add basic volume stage (1)"); + std::shared_ptr tmpVolume = m_node->getVolume(); + if (tmpVolume != nullptr) { + AIRTIO_INFO(" add volume for node"); + algo->addVolumeStage(tmpVolume); + } } else { // add all time the volume stage : std::shared_ptr algo = airtalgo::Volume::create(); @@ -54,6 +59,11 @@ bool airtio::Interface::init(const std::string& _name, algo->setName("volume"); m_process->pushBack(algo); AIRTIO_INFO("add basic volume stage (2)"); + std::shared_ptr tmpVolume = m_node->getVolume(); + if (tmpVolume != nullptr) { + AIRTIO_INFO(" add volume for node"); + algo->addVolumeStage(tmpVolume); + } } return true; } @@ -160,22 +170,38 @@ bool airtio::Interface::setParameter(const std::string& _filter, const std::stri if ( _filter == "volume" && _parameter != "FLOW") { AIRTIO_ERROR("Interface is not allowed to modify '" << _parameter << "' Volume just allowed to modify 'FLOW' volume"); + return false; } - AIRTIO_TODO(" IMPLEMENT"); + std::shared_ptr algo = m_process->get(_filter); + if (algo == nullptr) { + AIRTIO_ERROR("setParameter(" << _filter << ") ==> no filter named like this ..."); + return false; + } + out = algo->setParameter(_parameter, _value); AIRTIO_DEBUG("setParameter [ END ] : '" << out << "'"); return out; } std::string airtio::Interface::getParameter(const std::string& _filter, const std::string& _parameter) const { AIRTIO_DEBUG("getParameter [BEGIN] : '" << _filter << "':'" << _parameter << "'"); std::string out; - AIRTIO_TODO(" IMPLEMENT"); + std::shared_ptr algo = m_process->get(_filter); + if (algo == nullptr) { + AIRTIO_ERROR("setParameter(" << _filter << ") ==> no filter named like this ..."); + return "[ERROR]"; + } + out = algo->getParameter(_parameter); AIRTIO_DEBUG("getParameter [ END ] : '" << out << "'"); return out; } std::string airtio::Interface::getParameterProperty(const std::string& _filter, const std::string& _parameter) const { AIRTIO_DEBUG("getParameterProperty [BEGIN] : '" << _filter << "':'" << _parameter << "'"); std::string out; - AIRTIO_TODO(" IMPLEMENT"); + std::shared_ptr algo = m_process->get(_filter); + if (algo == nullptr) { + AIRTIO_ERROR("setParameter(" << _filter << ") ==> no filter named like this ..."); + return "[ERROR]"; + } + out = algo->getParameterProperty(_parameter); AIRTIO_DEBUG("getParameterProperty [ END ] : '" << out << "'"); return out; } @@ -256,7 +282,23 @@ std::chrono::system_clock::time_point airtio::Interface::getCurrentTime() const return std::chrono::system_clock::now(); } - +void airtio::Interface::addVolumeGroup(const std::string& _name) { + std::unique_lock lock(m_mutex); + AIRTIO_DEBUG("addVolumeGroup(" << _name << ")"); + std::shared_ptr algo = m_process->get("volume"); + if (algo == nullptr) { + AIRTIO_ERROR("addVolumeGroup(" << _name << ") ==> no volume stage ... can not add it ..."); + return; + } + if (_name == "FLOW") { + // Local volume name + algo->addVolumeStage(std::make_shared(_name)); + } else { + // get manager unique instance: + std::shared_ptr mng = airtio::io::Manager::getInstance(); + algo->addVolumeStage(mng->getVolumeGroup(_name)); + } +} void airtio::Interface::systemNewInputData(std::chrono::system_clock::time_point _time, void* _data, size_t _nbChunk) { std::unique_lock lockProcess(m_mutex); diff --git a/airtio/Interface.h b/airtio/Interface.h index 7d0b62d..cfc278e 100644 --- a/airtio/Interface.h +++ b/airtio/Interface.h @@ -81,9 +81,9 @@ namespace airtio { * - TTS for Test-to-speech volume control. * - COMMUNICATION for user communication volume control. * - NOTIFICATION for urgent notification volume control. - * - NOISE for small nose volume control. + * - NOISE for small noise volume control. */ - virtual void addVolumeGroup(const std::string& _name) {} + virtual void addVolumeGroup(const std::string& _name); public: /** * @brief Start the Audio interface flow. diff --git a/airtio/Manager.cpp b/airtio/Manager.cpp index d520a9f..14c6796 100644 --- a/airtio/Manager.cpp +++ b/airtio/Manager.cpp @@ -80,7 +80,7 @@ airtio::Manager::createOutput(float _freq, // get global hardware interface: std::shared_ptr manager = airtio::io::Manager::getInstance(); // get the output or input channel : - std::shared_ptr node = manager->getNode(_streamName, false); + std::shared_ptr node = manager->getNode(_streamName);//, false); // create user iterface: std::shared_ptr interface; interface = airtio::Interface::create(_name, _freq, _map, _format, node); @@ -100,7 +100,7 @@ airtio::Manager::createInput(float _freq, // get global hardware interface: std::shared_ptr manager = airtio::io::Manager::getInstance(); // get the output or input channel : - std::shared_ptr node = manager->getNode(_streamName, true); + std::shared_ptr node = manager->getNode(_streamName);//, true); // create user iterface: std::shared_ptr interface; interface = airtio::Interface::create(_name, _freq, _map, _format, node); diff --git a/airtio/io/Manager.cpp b/airtio/io/Manager.cpp index 47ab7da..fb1e6f9 100644 --- a/airtio/io/Manager.cpp +++ b/airtio/io/Manager.cpp @@ -6,26 +6,58 @@ #include "Manager.h" #include +#include #include "Node.h" #undef __class__ #define __class__ "io::Manager" +airtio::io::Manager::Manager() { + if (m_config.load("DATA:hardware.json") == false) { + AIRTIO_ERROR("you must set a basic configuration file for harware configuration: DATA:hardware.json"); + } +}; + + std::shared_ptr airtio::io::Manager::getInstance() { static std::shared_ptr manager(new Manager()); return manager; } -std::shared_ptr airtio::io::Manager::getNode(const std::string& _streamName, bool _isInput) { +std::shared_ptr airtio::io::Manager::getNode(const std::string& _name) { for (size_t iii=0; iii< m_list.size(); ++iii) { std::shared_ptr tmppp = m_list[iii].lock(); - if ( tmppp!=nullptr - && _streamName == tmppp->getName() - && _isInput == tmppp->isInput()) { + if ( tmppp != nullptr + && _name == tmppp->getName()) { return tmppp; } } - std::shared_ptr tmp = airtio::io::Node::create(_streamName, _isInput); - m_list.push_back(tmp); - return tmp; + // check if the node can be open : + const std::shared_ptr tmpObject = m_config.getObject(_name); + if (tmpObject != nullptr) { + std::shared_ptr tmp = airtio::io::Node::create(_name, tmpObject); + m_list.push_back(tmp); + return tmp; + } + AIRTIO_ERROR("Can not create the interface : '" << _name << "' the node is not DEFINED in the configuration file availlable : " << m_config.getKeys()); + return nullptr; +} + +std::shared_ptr airtio::io::Manager::getVolumeGroup(const std::string& _name) { + if (_name == "") { + AIRTIO_ERROR("Try to create an audio group with no name ..."); + return nullptr; + } + for (auto &it : m_volumeGroup) { + if (it == nullptr) { + continue; + } + if (it->getName() == _name) { + return nullptr; + } + } + AIRTIO_DEBUG("Add a new volume group : '" << _name << "'"); + std::shared_ptr tmpVolume = std::make_shared(_name); + m_volumeGroup.push_back(tmpVolume); + return tmpVolume; } \ No newline at end of file diff --git a/airtio/io/Manager.h b/airtio/io/Manager.h index 5f9cee0..570f85f 100644 --- a/airtio/io/Manager.h +++ b/airtio/io/Manager.h @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include namespace airtio { namespace io { @@ -25,7 +27,7 @@ namespace airtio { /** * @brief Constructor */ - Manager() {}; + Manager(); public: static std::shared_ptr getInstance(); /** @@ -33,10 +35,15 @@ namespace airtio { */ virtual ~Manager() {}; private: - std::vector > m_list; + ejson::Document m_config; // harware configuration + std::vector > m_listKeepAlive; //!< list of all Node that might be keep alive sone time + std::vector > m_list; //!< List of all IO node public: - std::shared_ptr getNode(const std::string& _streamName, bool _isInput); - + std::shared_ptr getNode(const std::string& _name); + private: + std::vector> m_volumeGroup; + public: + std::shared_ptr getVolumeGroup(const std::string& _name); }; } } diff --git a/airtio/io/Node.cpp b/airtio/io/Node.cpp index b31ab1b..016b56c 100644 --- a/airtio/io/Node.cpp +++ b/airtio/io/Node.cpp @@ -74,39 +74,115 @@ int32_t airtio::io::Node::rtAudioCallback(void* _outputBuffer, } -std::shared_ptr airtio::io::Node::create(const std::string& _streamName, bool _isInput) { - return std::shared_ptr(new airtio::io::Node(_streamName, _isInput)); +std::shared_ptr airtio::io::Node::create(const std::string& _name, const std::shared_ptr& _config) { + return std::shared_ptr(new airtio::io::Node(_name, _config)); } -airtio::io::Node::Node(const std::string& _streamName, bool _isInput) : - m_streamName(_streamName), - m_isInput(_isInput) { +airtio::io::Node::Node(const std::string& _name, const std::shared_ptr& _config) : + m_config(_config), + m_name(_name), + m_isInput(false) { AIRTIO_INFO("-----------------------------------------------------------------"); AIRTIO_INFO("-- CREATE NODE --"); AIRTIO_INFO("-----------------------------------------------------------------"); - // intanciate specific API ... - m_adac.instanciate(); + /** + io:"input", # input or output + map-on:{ # select hardware interface and name + interface:"alsa", # interface : "alsa", "pulse", "core", ... + name:"default", # name of the interface + }, + frequency:48000, # frequency to open device + channel-map:[ # mapping of the harware device (to change map if needed) + "front-left", "front-right", + "read-left", "rear-right", + ], + type:"int16", # format to open device (int8, int16, int16-on-ont32, int24, int32, float) + nb-chunk:1024 # number of chunk to open device (create the latency anf the frequency to call user) + */ + m_isInput = m_config->getStringValue("io") == "input"; + enum airtaudio::api::type typeInterface = airtaudio::api::LINUX_ALSA; + std::string streamName = "default"; + const std::shared_ptr tmpObject = m_config->getObject("map-on"); + if (tmpObject == nullptr) { + AIRTIO_WARNING("missing node : 'map-on' ==> auto map : 'alsa:default'"); + } else { + std::string value = tmpObject->getStringValue("interface", "default"); + if (value == "alsa") { + typeInterface = airtaudio::api::LINUX_ALSA; + } else if (value == "pulse") { + typeInterface = airtaudio::api::LINUX_PULSE; + } else if (value == "b") { + typeInterface = airtaudio::api::LINUX_OSS; + } else if (value == "jack") { + typeInterface = airtaudio::api::UNIX_JACK; + } else if (value == "mac-core") { + typeInterface = airtaudio::api::MACOSX_CORE; + } else if (value == "ios-core") { + typeInterface = airtaudio::api::IOS_CORE; + } else if (value == "asio") { + typeInterface = airtaudio::api::WINDOWS_ASIO; + } else if (value == "ds") { + typeInterface = airtaudio::api::WINDOWS_DS; + } else if (value == "dummy") { + typeInterface = airtaudio::api::RTAUDIO_DUMMY; + } else if (value == "java") { + typeInterface = airtaudio::api::ANDROID_JAVA; + } else if (value == "user-1") { + typeInterface = airtaudio::api::USER_INTERFACE_1; + } else if (value == "user-2") { + typeInterface = airtaudio::api::USER_INTERFACE_2; + } else if (value == "user-3") { + typeInterface = airtaudio::api::USER_INTERFACE_3; + } else if (value == "user-4") { + typeInterface = airtaudio::api::USER_INTERFACE_4; + } else { + AIRTIO_WARNING("Unknow interface : '" << value << "'"); + } + streamName = tmpObject->getStringValue("name", "default"); + } + int32_t frequency = m_config->getNumberValue("frequency", 48000); + std::string type = m_config->getStringValue("type", "int16"); + int32_t nbChunk = m_config->getNumberValue("nb-chunk", 1024); + std::string volumeName = m_config->getStringValue("volume-name", ""); + if (volumeName != "") { + AIRTIO_INFO("add node volume stage : '" << volumeName << "'"); + m_volume = std::make_shared(volumeName); + } - if (m_streamName == "") { - m_streamName = "default"; + + enum airtalgo::format formatType = airtalgo::format_int16; + if (type == "int16") { + formatType = airtalgo::format_int16; + } else { + AIRTIO_WARNING("not managed type : '" << type << "'"); + } + // TODO : MAP ... + + // intanciate specific API ... + m_adac.instanciate(typeInterface); + // TODO : Check return ... + + if (streamName == "") { + streamName = "default"; } std::vector map; // set default channel property : map.push_back(airtalgo::channel_frontLeft); map.push_back(airtalgo::channel_frontRight); - m_hardwareFormat.set(map, airtalgo::format_int16, 48000); + m_hardwareFormat.set(map, formatType, frequency); + // TODO : Better view of interface type float -> float, int16 -> int16/int32, ... if (m_isInput == true) { // for input we just transfert audio with no transformation - m_interfaceFormat.set(map, airtalgo::format_int16, 48000); + m_interfaceFormat.set(map, airtalgo::format_int16, frequency); } else { // for output we will do a mix ... - m_interfaceFormat.set(map, airtalgo::format_int16_on_int32, 48000); + m_interfaceFormat.set(map, airtalgo::format_int16_on_int32, frequency); } // search device ID : AIRTIO_INFO("Open :"); - AIRTIO_INFO(" m_streamName=" << m_streamName); + AIRTIO_INFO(" m_streamName=" << streamName); AIRTIO_INFO(" m_freq=" << m_hardwareFormat.getFrequency()); AIRTIO_INFO(" m_map=" << m_hardwareFormat.getMap()); AIRTIO_INFO(" m_format=" << m_hardwareFormat.getFormat()); @@ -116,7 +192,7 @@ airtio::io::Node::Node(const std::string& _streamName, bool _isInput) : for (int32_t iii=0; iii lock(m_mutex); - AIRTIO_INFO("Start stream : '" << m_streamName << "' mode=" << (m_isInput?"input":"output") ); + AIRTIO_INFO("Start stream : '" << m_name << "' mode=" << (m_isInput?"input":"output") ); enum airtaudio::errorType err = m_adac.startStream(); if (err != airtaudio::errorNone) { - AIRTIO_ERROR("Start stream : '" << m_streamName << "' mode=" << (m_isInput?"input":"output") << " can not start stream ... " << err); + AIRTIO_ERROR("Start stream : '" << m_name << "' mode=" << (m_isInput?"input":"output") << " can not start stream ... " << err); } } void airtio::io::Node::stop() { std::unique_lock lock(m_mutex); - AIRTIO_INFO("Stop stream : '" << m_streamName << "' mode=" << (m_isInput?"input":"output") ); + AIRTIO_INFO("Stop stream : '" << m_name << "' mode=" << (m_isInput?"input":"output") ); enum airtaudio::errorType err = m_adac.stopStream(); if (err != airtaudio::errorNone) { - AIRTIO_ERROR("Stop stream : '" << m_streamName << "' mode=" << (m_isInput?"input":"output") << " can not stop stream ... " << err); + AIRTIO_ERROR("Stop stream : '" << m_name << "' mode=" << (m_isInput?"input":"output") << " can not stop stream ... " << err); } } @@ -244,7 +319,7 @@ void airtio::io::Node::interfaceAdd(const std::shared_ptr& _i return; } } - AIRTIO_INFO("ADD interface for stream : '" << m_streamName << "' mode=" << (m_isInput?"input":"output") ); + AIRTIO_INFO("ADD interface for stream : '" << m_name << "' mode=" << (m_isInput?"input":"output") ); m_list.push_back(_interface); } if (m_list.size() == 1) { @@ -258,7 +333,7 @@ void airtio::io::Node::interfaceRemove(const std::shared_ptr& for (size_t iii=0; iii< m_list.size(); ++iii) { if (_interface == m_list[iii]) { m_list.erase(m_list.begin()+iii); - AIRTIO_INFO("RM interface for stream : '" << m_streamName << "' mode=" << (m_isInput?"input":"output") ); + AIRTIO_INFO("RM interface for stream : '" << m_name << "' mode=" << (m_isInput?"input":"output") ); break; } } diff --git a/airtio/io/Node.h b/airtio/io/Node.h index 9604712..0c84867 100644 --- a/airtio/io/Node.h +++ b/airtio/io/Node.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace airtio { namespace io { @@ -27,13 +28,15 @@ namespace airtio { class Node { private: mutable std::mutex m_mutex; + std::shared_ptr m_config; + std::shared_ptr m_volume; //!< if a volume is set it is set here ... private: /** * @brief Constructor */ - Node(const std::string& _streamName, bool _isInput); + Node(const std::string& _name, const std::shared_ptr& _config); public: - static std::shared_ptr create(const std::string& _streamName, bool _isInput); + static std::shared_ptr create(const std::string& _name, const std::shared_ptr& _config); /** * @brief Destructor */ @@ -54,10 +57,10 @@ namespace airtio { double _streamTime, airtaudio::streamStatus _status); private: - std::string m_streamName; + std::string m_name; public: const std::string& getName() { - return m_streamName; + return m_name; } private: airtalgo::IOFormatInterface m_interfaceFormat; @@ -79,6 +82,10 @@ namespace airtio { private: void start(); void stop(); + public: + const std::shared_ptr& getVolume() { + return m_volume; + } }; } } diff --git a/data/hardware.json b/data/hardware.json index dc18811..4e4bed2 100644 --- a/data/hardware.json +++ b/data/hardware.json @@ -6,9 +6,8 @@ name:"default", # name of the interface }, frequency:48000, # frequency to open device - channel-map:[ # mapping of the harware device (to change map if needed) - "front-left", "front-right", - "read-left", "rear-right", + channel-map:[ # mapping of the harware device (mapping is not get under) + "front-left", "front-right" ], type:"int16", # format to open device (int8, int16, int16-on-ont32, int24, int32, float) nb-chunk:1024 # number of chunk to open device (create the latency anf the frequency to call user) diff --git a/lutin_airtio.py b/lutin_airtio.py index 165c95e..2dfa515 100644 --- a/lutin_airtio.py +++ b/lutin_airtio.py @@ -18,7 +18,7 @@ def create(target): 'airtio/io/Manager.cpp' ]) - myModule.add_module_depend(['airtaudio', 'airtalgo']) + myModule.add_module_depend(['airtaudio', 'airtalgo', 'ejson']) myModule.add_export_path(tools.get_current_path(__file__)) # add the currrent module at the diff --git a/lutin_airtio_test.py b/lutin_airtio_test.py index dada5ab..582b4c9 100644 --- a/lutin_airtio_test.py +++ b/lutin_airtio_test.py @@ -15,6 +15,7 @@ def create(target): 'test/debug.cpp' ]) + myModule.copy_folder('data/*') myModule.add_module_depend(['airtio', 'gtest', 'etk']) # add the currrent module at the diff --git a/test/main.cpp b/test/main.cpp index bd8af19..89c1fa0 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -30,7 +30,7 @@ class testOutWrite { m_interface = m_manager->createOutput(48000, m_channelMap, airtalgo::format_int16, - "default", + "speaker", "WriteMode"); m_interface->setReadwrite(); } @@ -99,7 +99,7 @@ class testOutWriteCallback { m_interface = m_manager->createOutput(48000, channelMap, airtalgo::format_int16, - "default", + "speaker", "WriteMode+Callback"); m_interface->setReadwrite(); m_interface->setWriteCallback(std::bind(&testOutWriteCallback::onDataNeeded, @@ -166,7 +166,7 @@ class testOutCallback { m_interface = m_manager->createOutput(48000, channelMap, airtalgo::format_int16, - "default", + "speaker", "WriteModeCallback"); // set callback mode ... m_interface->setOutputCallback(1024, @@ -232,7 +232,7 @@ class testInRead { m_interface = m_manager->createInput(48000, m_channelMap, airtalgo::format_int16, - "default", + "microphone", "WriteMode"); m_interface->setReadwrite(); } @@ -279,7 +279,7 @@ class testInCallback { m_interface = m_manager->createInput(48000, channelMap, airtalgo::format_int16, - "default", + "microphone", "WriteModeCallback"); // set callback mode ... m_interface->setInputCallback(1024, @@ -364,7 +364,7 @@ class testOutCallbackType { m_interface = m_manager->createOutput(m_freq, channelMap, _format, - "default", + "speaker", "WriteModeCallbackType"); // set callback mode ... m_interface->setOutputCallback(1024, @@ -487,6 +487,90 @@ INSTANTIATE_TEST_CASE_P(InstantiationName, +class testCallbackVolume { + private: + std::shared_ptr m_manager; + std::shared_ptr m_interface; + double m_phase; + public: + testCallbackVolume(std::shared_ptr _manager) : + m_manager(_manager), + m_phase(0) { + //Set stereo output: + std::vector channelMap; + channelMap.push_back(airtalgo::channel_frontLeft); + channelMap.push_back(airtalgo::channel_frontRight); + m_interface = m_manager->createOutput(48000, + channelMap, + airtalgo::format_int16, + "speaker", + "WriteModeCallback"); + // set callback mode ... + m_interface->setOutputCallback(1024, + std::bind(&testCallbackVolume::onDataNeeded, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4, + std::placeholders::_5)); + m_interface->addVolumeGroup("MEDIA"); + m_interface->addVolumeGroup("FLOW"); + } + void onDataNeeded(const std::chrono::system_clock::time_point& _playTime, + const size_t& _nbChunk, + const std::vector& _map, + void* _data, + enum airtalgo::format _type) { + if (_type != airtalgo::format_int16) { + APPL_ERROR("call wrong type ... (need int16_t)"); + } + int16_t* data = static_cast(_data); + double baseCycle = 2.0*M_PI/(double)48000 * (double)550; + for (int32_t iii=0; iii<_nbChunk; iii++) { + for (int32_t jjj=0; jjj<_map.size(); jjj++) { + data[_map.size()*iii+jjj] = cos(m_phase) * 30000; + } + m_phase += baseCycle; + if (m_phase >= 2*M_PI) { + m_phase -= 2*M_PI; + } + } + } + void run() { + m_interface->start(); + usleep(1000000); + m_interface->setParameter("volume", "FLOW", "-3dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "-6dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "-9dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "-12dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "-3dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "3dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "6dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "9dB"); + usleep(500000); + m_interface->setParameter("volume", "FLOW", "0dB"); + usleep(1000000); + m_interface->stop(); + } +}; + + +TEST(testALL, testVolume) { + std::shared_ptr manager; + manager = airtio::Manager::create("testApplication"); + std::shared_ptr process = std::make_shared(manager); + process->run(); + process.reset(); + usleep(500000); +} TEST(TestALL, testChannelsFormatResampling) { std::shared_ptr manager;