/** @file * @author Edouard DUPIN * @copyright 2015, Edouard DUPIN, all right reserved * @license APACHE v2.0 (see license file) */ #include "Node.h" #include #include #undef __class__ #define __class__ "io::Node" #ifndef INT16_MAX #define INT16_MAX 0x7fff #endif #ifndef INT16_MIN #define INT16_MIN (-INT16_MAX - 1) #endif #ifndef INT32_MAX #define INT32_MAX 0x7fffffffL #endif #ifndef INT32_MIN #define INT32_MIN (-INT32_MAX - 1L) #endif int32_t airtio::io::Node::rtAudioCallback(void* _outputBuffer, void* _inputBuffer, unsigned int _nBufferFrames, double _streamTime, airtaudio::streamStatus _status) { std::unique_lock lock(m_mutex); std::chrono::system_clock::time_point ttime = std::chrono::system_clock::time_point();//std::chrono::system_clock::now(); if (_outputBuffer != nullptr) { AIRTIO_VERBOSE("data Output"); std::vector output; output.resize(_nBufferFrames*m_map.size(), 0); const int16_t* outputTmp = nullptr; std::vector outputTmp2; outputTmp2.resize(sizeof(int16_t)*m_map.size()*_nBufferFrames, 0); for (auto &it : m_list) { if (it != nullptr) { // clear datas ... memset(&outputTmp2[0], 0, sizeof(int16_t)*m_map.size()*_nBufferFrames); AIRTIO_VERBOSE(" IO : " /* << std::distance(m_list.begin(), it)*/ << "/" << m_list.size() << " name="<< it->getName()); it->systemNeedOutputData(ttime, &outputTmp2[0], _nBufferFrames, sizeof(int16_t)*m_map.size()); outputTmp = reinterpret_cast(&outputTmp2[0]); //it->systemNeedOutputData(ttime, _outputBuffer, _nBufferFrames, sizeof(int16_t)*m_map.size()); // Add data to the output tmp buffer : for (size_t kkk=0; kkk(outputTmp[kkk]); } break; } } int16_t* outputBuffer = static_cast(_outputBuffer); for (size_t kkk=0; kkk(std::min(std::max(INT16_MIN, output[kkk]), INT16_MAX)); } } if (_inputBuffer != nullptr) { AIRTIO_INFO("data Input"); int16_t* inputBuffer = static_cast(_inputBuffer); for (size_t iii=0; iii< m_list.size(); ++iii) { if (m_list[iii] != nullptr) { AIRTIO_INFO(" IO : " << iii+1 << "/" << m_list.size() << " name="<< m_list[iii]->getName()); m_list[iii]->systemNewInputData(ttime, inputBuffer, _nBufferFrames); } } } return 0; } std::shared_ptr airtio::io::Node::create(const std::string& _streamName, bool _isInput) { return std::shared_ptr(new airtio::io::Node(_streamName, _isInput)); } airtio::io::Node::Node(const std::string& _streamName, bool _isInput) : m_streamName(_streamName), m_frequency(48000), m_format(airtalgo::format_int16), m_isInput(_isInput) { AIRTIO_INFO("-----------------------------------------------------------------"); AIRTIO_INFO("-- CREATE NODE --"); AIRTIO_INFO("-----------------------------------------------------------------"); // intanciate specific API ... m_adac.instanciate(); if (m_streamName == "") { m_streamName = "default"; } // set default channel property : m_map.push_back(airtalgo::channel_frontLeft); m_map.push_back(airtalgo::channel_frontRight); // search device ID : AIRTIO_INFO("Open :"); AIRTIO_INFO(" m_streamName=" << m_streamName); AIRTIO_INFO(" m_freq=" << m_frequency); AIRTIO_INFO(" m_map=" << m_map); AIRTIO_INFO(" m_format=" << m_format); AIRTIO_INFO(" m_isInput=" << m_isInput); int32_t deviceId = 0; AIRTIO_INFO("Device list:"); for (int32_t iii=0; iii lock(m_mutex); AIRTIO_INFO("-----------------------------------------------------------------"); AIRTIO_INFO("-- DESTROY NODE --"); AIRTIO_INFO("-----------------------------------------------------------------"); AIRTIO_INFO("close input stream"); if (m_adac.isStreamOpen() ) { m_adac.closeStream(); } }; void airtio::io::Node::start() { std::unique_lock lock(m_mutex); AIRTIO_INFO("Start stream : '" << m_streamName << "' 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); } } void airtio::io::Node::stop() { std::unique_lock lock(m_mutex); AIRTIO_INFO("Stop stream : '" << m_streamName << "' 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); } } void airtio::io::Node::interfaceAdd(const std::shared_ptr& _interface) { { std::unique_lock lock(m_mutex); for (size_t iii=0; iii< m_list.size(); ++iii) { if (_interface == m_list[iii]) { return; } } AIRTIO_INFO("ADD interface for stream : '" << m_streamName << "' mode=" << (m_isInput?"input":"output") ); m_list.push_back(_interface); } if (m_list.size() == 1) { start(); } } void airtio::io::Node::interfaceRemove(const std::shared_ptr& _interface) { { std::unique_lock lock(m_mutex); 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") ); break; } } } if (m_list.size() == 0) { stop(); } return; }