2015-01-25 22:17:06 +01:00
|
|
|
/** @file
|
|
|
|
* @author Edouard DUPIN
|
|
|
|
* @copyright 2015, Edouard DUPIN, all right reserved
|
|
|
|
* @license APACHE v2.0 (see license file)
|
|
|
|
*/
|
|
|
|
|
2015-01-26 22:04:29 +01:00
|
|
|
#include "debug.h"
|
2015-01-25 22:17:06 +01:00
|
|
|
#include "Interface.h"
|
2015-01-26 22:04:29 +01:00
|
|
|
#include "io/Node.h"
|
2015-01-25 22:17:06 +01:00
|
|
|
#include <airtalgo/ChannelReorder.h>
|
|
|
|
#include <airtalgo/FormatUpdate.h>
|
|
|
|
#include <airtalgo/Resampler.h>
|
|
|
|
#include <airtalgo/EndPointCallback.h>
|
|
|
|
#include <airtalgo/EndPointWrite.h>
|
|
|
|
#include <airtalgo/EndPointRead.h>
|
|
|
|
|
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
#undef __class__
|
|
|
|
#define __class__ "Interface"
|
|
|
|
|
2015-01-25 22:17:06 +01:00
|
|
|
airtio::Interface::Interface(void) :
|
|
|
|
m_node(nullptr),
|
|
|
|
m_freq(8000),
|
|
|
|
m_map(),
|
|
|
|
m_format(airtalgo::format_int16),
|
2015-01-26 22:04:29 +01:00
|
|
|
m_name(""),
|
2015-01-25 22:17:06 +01:00
|
|
|
m_volume(0.0f) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool airtio::Interface::init(const std::string& _name,
|
|
|
|
float _freq,
|
|
|
|
const std::vector<airtalgo::channel>& _map,
|
|
|
|
airtalgo::format _format,
|
|
|
|
const std::shared_ptr<airtio::io::Node>& _node) {
|
|
|
|
m_name = _name;
|
|
|
|
m_node = _node;
|
|
|
|
m_freq = _freq;
|
|
|
|
m_map = _map;
|
|
|
|
m_format = _format;
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process = std::make_shared<airtalgo::Process>();
|
2015-01-25 22:17:06 +01:00
|
|
|
m_volume = 0.0f;
|
|
|
|
|
|
|
|
// Create convertion interface
|
|
|
|
if (m_node->isInput() == true) {
|
2015-01-28 22:07:11 +01:00
|
|
|
// TODO : Set an auto update of IO
|
2015-01-25 22:17:06 +01:00
|
|
|
if (m_map != m_node->getMap()) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::ChannelReorder> algo = airtalgo::ChannelReorder::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_node->getMap(), m_node->getFormat(), m_node->getFrequency()));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_node->getFrequency()));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("convert " << m_node->getMap() << " -> " << m_map);
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
if (m_freq != m_node->getFrequency()) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::Resampler> algo = airtalgo::Resampler::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_node->getFrequency()));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_freq));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("convert " << m_node->getFrequency() << " -> " << m_freq);
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
if (m_format != m_node->getFormat()) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::FormatUpdate> algo = airtalgo::FormatUpdate::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_freq));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("convert " << m_node->getFormat() << " -> " << m_format);
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
// by default we add a read node
|
|
|
|
if (true) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::EndPointRead> algo = airtalgo::EndPointRead::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("add default read node ...");
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// by default we add a write node:
|
|
|
|
if (true) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::EndPointWrite> algo = airtalgo::EndPointWrite::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("add default write node ...");
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
2015-01-28 22:07:11 +01:00
|
|
|
// TODO : Set an auto update of IO
|
2015-01-25 22:17:06 +01:00
|
|
|
if (m_format != m_node->getFormat()) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::FormatUpdate> algo = airtalgo::FormatUpdate::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_freq));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("convert " << m_format << " -> " << m_node->getFormat());
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
if (m_freq != m_node->getFrequency()) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::Resampler> algo = airtalgo::Resampler::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_freq));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_node->getFrequency()));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("convert " << m_freq << " -> " << m_node->getFrequency());
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
if (m_map != m_node->getMap()) {
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::ChannelReorder> algo = airtalgo::ChannelReorder::create();
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_node->getFormat(), m_node->getFrequency()));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_node->getMap(), m_node->getFormat(), m_node->getFrequency()));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
|
|
|
AIRTIO_INFO("convert " << m_map << " -> " << m_node->getMap());
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
//m_node->interfaceAdd(shared_from_this());
|
2015-01-26 22:04:29 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<airtio::Interface> airtio::Interface::create(const std::string& _name,
|
|
|
|
float _freq,
|
|
|
|
const std::vector<airtalgo::channel>& _map,
|
|
|
|
airtalgo::format _format,
|
|
|
|
const std::shared_ptr<airtio::io::Node>& _node) {
|
|
|
|
std::shared_ptr<airtio::Interface> out = std::shared_ptr<airtio::Interface>(new airtio::Interface());
|
|
|
|
out->init(_name, _freq, _map, _format, _node);
|
|
|
|
return out;
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
airtio::Interface::~Interface() {
|
2015-01-28 22:07:11 +01:00
|
|
|
//stop(true, true);
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
//m_node->interfaceRemove(shared_from_this());
|
2015-01-28 22:07:11 +01:00
|
|
|
m_process.reset();
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
void airtio::Interface::setOutputCallback(size_t _chunkSize, airtalgo::needDataFunction _function) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->removeIfFirst<airtalgo::EndPoint>();
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::Algo> algo = airtalgo::EndPointCallback::create(_function);
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_INFO("set property: " << m_map << " " << m_format << " " << m_freq);
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushFront(algo);
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
void airtio::Interface::setInputCallback(size_t _chunkSize, airtalgo::haveNewDataFunction _function) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->removeIfLast<airtalgo::EndPoint>();
|
2015-01-29 21:46:01 +01:00
|
|
|
std::shared_ptr<airtalgo::Algo> algo = airtalgo::EndPointCallback::create(_function);
|
2015-01-25 22:17:06 +01:00
|
|
|
algo->setInputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
|
|
|
algo->setOutputFormat(airtalgo::IOFormatInterface(m_map, m_format, m_freq));
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->pushBack(algo);
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
2015-01-27 22:47:09 +01:00
|
|
|
void airtio::Interface::setWriteCallback(airtalgo::needDataFunctionWrite _function) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-27 22:47:09 +01:00
|
|
|
std::shared_ptr<airtalgo::EndPointWrite> algo = m_process->get<airtalgo::EndPointWrite>(0);
|
|
|
|
if (algo == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
algo->setCallback(_function);
|
|
|
|
}
|
2015-01-25 22:17:06 +01:00
|
|
|
|
|
|
|
void airtio::Interface::start(const std::chrono::system_clock::time_point& _time) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("start [BEGIN]");
|
2015-01-25 22:17:06 +01:00
|
|
|
m_node->interfaceAdd(shared_from_this());
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("start [ END ]");
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void airtio::Interface::stop(bool _fast, bool _abort) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("stop [BEGIN]");
|
2015-01-25 22:17:06 +01:00
|
|
|
m_node->interfaceRemove(shared_from_this());
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("stop [ END]");
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void airtio::Interface::abort() {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("abort [BEGIN]");
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("abort [ END ]");
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void airtio::Interface::setVolume(float _gainDB) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("setVolume [BEGIN]");
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("setVolume [ END ]");
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
float airtio::Interface::getVolume() const {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("getVolume [BEGIN]");
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
2015-01-26 22:04:29 +01:00
|
|
|
AIRTIO_DEBUG("getVolume [ END ]");
|
2015-01-25 22:17:06 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<float,float> airtio::Interface::getVolumeRange() const {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
return std::make_pair(-120.0f, 0.0f);
|
|
|
|
}
|
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
void airtio::Interface::write(const void* _value, size_t _nbChunk) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
std::shared_ptr<airtalgo::EndPointWrite> algo = m_process->get<airtalgo::EndPointWrite>(0);
|
2015-01-25 22:17:06 +01:00
|
|
|
if (algo == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
algo->write(_value, _nbChunk);
|
|
|
|
}
|
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
#if 0
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO : add API aCCess mutex for Read and write...
|
|
|
|
std::vector<int16_t> airtio::Interface::read(size_t _nbChunk) {
|
|
|
|
// TODO :...
|
|
|
|
std::vector<int16_t> data;
|
|
|
|
/*
|
|
|
|
data.resize(_nbChunk*m_map.size(), 0);
|
|
|
|
m_mutex.lock();
|
|
|
|
int32_t nbChunkBuffer = m_circularBuffer.size() / m_map.size();
|
|
|
|
m_mutex.unlock();
|
|
|
|
while (nbChunkBuffer < _nbChunk) {
|
|
|
|
usleep(1000);
|
|
|
|
nbChunkBuffer = m_circularBuffer.size() / m_map.size();
|
|
|
|
}
|
|
|
|
m_mutex.lock();
|
|
|
|
for (size_t iii = 0; iii<data.size(); ++iii) {
|
|
|
|
data[iii] = m_circularBuffer[iii];
|
|
|
|
}
|
|
|
|
m_circularBuffer.erase(m_circularBuffer.begin(), m_circularBuffer.begin()+data.size());
|
|
|
|
m_mutex.unlock();
|
|
|
|
*/
|
|
|
|
return data;
|
|
|
|
}
|
2015-01-27 21:01:52 +01:00
|
|
|
#endif
|
2015-01-25 22:17:06 +01:00
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
void airtio::Interface::read(void* _value, size_t _nbChunk) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t airtio::Interface::size() const {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void airtio::Interface::setBufferSize(size_t _nbChunk) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-01-26 22:04:29 +01:00
|
|
|
void airtio::Interface::setBufferSize(const std::chrono::duration<int64_t, std::micro>& _time) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void airtio::Interface::clearInternalBuffer() {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::chrono::system_clock::time_point airtio::Interface::getCurrentTime() const {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
2015-01-25 22:17:06 +01:00
|
|
|
// TODO :...
|
|
|
|
return std::chrono::system_clock::time_point();
|
|
|
|
return std::chrono::system_clock::now();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
void airtio::Interface::systemNewInputData(std::chrono::system_clock::time_point _time, void* _data, size_t _nbChunk) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lockProcess(m_mutex);
|
2015-01-26 22:04:29 +01:00
|
|
|
m_process->push(_time, _data, _nbChunk);
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|
|
|
|
|
2015-01-27 21:01:52 +01:00
|
|
|
void airtio::Interface::systemNeedOutputData(std::chrono::system_clock::time_point _time, void*& _data, size_t& _nbChunk, size_t _chunkSize) {
|
2015-01-29 23:10:26 +01:00
|
|
|
std::unique_lock<std::recursive_mutex> lockProcess(m_mutex);
|
2015-01-27 21:01:52 +01:00
|
|
|
m_process->pull(_time, _data, _nbChunk);//, _chunkSize);
|
2015-01-25 22:17:06 +01:00
|
|
|
}
|