[DEV] create algo basic interface for simple audio flow
This commit is contained in:
commit
51d16858c5
80
airtalgo/Algo.cpp
Normal file
80
airtalgo/Algo.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <airtalgo/Algo.h>
|
||||
#include <functional>
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
airtalgo::Algo::Algo() :
|
||||
m_outputData(),
|
||||
m_formatSize(0),
|
||||
m_needProcess(false) {
|
||||
// set notification callback :
|
||||
m_input.setCallback(std::bind(&airtalgo::Algo::configurationChange, this));
|
||||
m_output.setCallback(std::bind(&airtalgo::Algo::configurationChange, this));
|
||||
// first configure ==> update the internal parameters
|
||||
configurationChange();
|
||||
}
|
||||
|
||||
void airtalgo::Algo::configurationChange() {
|
||||
m_needProcess = false;
|
||||
if (m_input.getFormat() != m_output.getFormat()) {
|
||||
m_needProcess = true;
|
||||
}
|
||||
if (m_input.getMap() != m_output.getMap()) {
|
||||
m_needProcess = true;
|
||||
}
|
||||
if (m_input.getFrequency() != m_output.getFrequency()) {
|
||||
m_needProcess = true;
|
||||
}
|
||||
switch (m_output.getFormat()) {
|
||||
case format_int16:
|
||||
m_formatSize = sizeof(int16_t);
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
case format_int32:
|
||||
m_formatSize = sizeof(int32_t);
|
||||
break;
|
||||
case format_float:
|
||||
m_formatSize = sizeof(float);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t airtalgo::Algo::needInputData(size_t _output) {
|
||||
size_t input = _output;
|
||||
if (m_input.getFormat() != m_output.getFormat()) {
|
||||
int32_t inputSize = 3;
|
||||
switch (m_input.getFormat()) {
|
||||
case format_int16:
|
||||
inputSize = sizeof(int16_t);
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
case format_int32:
|
||||
inputSize = sizeof(int32_t);
|
||||
break;
|
||||
case format_float:
|
||||
inputSize = sizeof(float);
|
||||
break;
|
||||
}
|
||||
if (inputSize != m_formatSize) {
|
||||
input *= inputSize;
|
||||
input /= m_formatSize;
|
||||
}
|
||||
}
|
||||
if (m_input.getMap().size() != m_output.getMap().size()) {
|
||||
input *= m_input.getMap().size();
|
||||
input /= m_output.getMap().size();
|
||||
}
|
||||
|
||||
if (m_input.getFrequency() != m_output.getFrequency()) {
|
||||
input *= m_input.getFrequency();
|
||||
input /= m_output.getFrequency();
|
||||
// to prevent missing data in the resampler
|
||||
input += 2;
|
||||
}
|
||||
return input;
|
||||
}
|
197
airtalgo/Algo.h
Normal file
197
airtalgo/Algo.h
Normal file
@ -0,0 +1,197 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __AIRT_ALGO_CORE_ALGO_H__
|
||||
#define __AIRT_ALGO_CORE_ALGO_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <airtalgo/format.h>
|
||||
#include <airtalgo/channel.h>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include "debug.h"
|
||||
|
||||
namespace airtalgo{
|
||||
class autoLogInOut {
|
||||
private:
|
||||
std::string m_value;
|
||||
public:
|
||||
autoLogInOut(const std::string& _value) :
|
||||
m_value(_value) {
|
||||
AIRTALGO_DEBUG(" '" << m_value << "' [START]");
|
||||
}
|
||||
~autoLogInOut() {
|
||||
AIRTALGO_DEBUG(" '" << m_value << "' [STOP]");
|
||||
}
|
||||
};
|
||||
class IOFormatInterface {
|
||||
public:
|
||||
IOFormatInterface() :
|
||||
m_format(airtalgo::format_int16),
|
||||
m_map(),
|
||||
m_frequency(48000) {
|
||||
m_map.push_back(airtalgo::channel_frontLeft);
|
||||
m_map.push_back(airtalgo::channel_frontRight);
|
||||
}
|
||||
IOFormatInterface(std::vector<airtalgo::channel> _map, airtalgo::format _format=airtalgo::format_int16, float _frequency=48000) :
|
||||
m_format(_format),
|
||||
m_map(_map),
|
||||
m_frequency(_frequency) {
|
||||
|
||||
}
|
||||
protected:
|
||||
airtalgo::format m_format; //!< input Algo Format
|
||||
public:
|
||||
/**
|
||||
* @brief Get the algo format.
|
||||
* @return the current Format.
|
||||
*/
|
||||
airtalgo::format getFormat() const {
|
||||
return m_format;
|
||||
}
|
||||
/**
|
||||
* @brief Set the algo format.
|
||||
* @param[in] _value New Format.
|
||||
*/
|
||||
void setFormat(airtalgo::format _value) {
|
||||
if (m_format == _value) {
|
||||
return;
|
||||
}
|
||||
m_format = _value;
|
||||
configurationChange();
|
||||
}
|
||||
protected:
|
||||
std::vector<airtalgo::channel> m_map; //!< input channel Map
|
||||
public:
|
||||
/**
|
||||
* @brief Get the algo channel Map.
|
||||
* @return the current channel Map.
|
||||
*/
|
||||
const std::vector<airtalgo::channel>& getMap() const{
|
||||
return m_map;
|
||||
}
|
||||
/**
|
||||
* @brief Set the algo channel Map.
|
||||
* @param[in] _value New channel Map.
|
||||
*/
|
||||
void setMap(const std::vector<airtalgo::channel>& _value) {
|
||||
AIRTALGO_DEBUG(" base : " << m_map << " " << _value);
|
||||
if (m_map == _value) {
|
||||
return;
|
||||
}
|
||||
m_map = _value;
|
||||
AIRTALGO_DEBUG(" base2 : " << m_map);
|
||||
configurationChange();
|
||||
}
|
||||
protected:
|
||||
float m_frequency; //!< input Algo Format
|
||||
public:
|
||||
/**
|
||||
* @brief Get the algo frequency.
|
||||
* @return the current frequency.
|
||||
*/
|
||||
float getFrequency() const{
|
||||
return m_frequency;
|
||||
}
|
||||
/**
|
||||
* @brief Set the algo frequency.
|
||||
* @param[in] _value New frequency.
|
||||
*/
|
||||
void setFrequency(float _value) {
|
||||
if (m_frequency == _value) {
|
||||
return;
|
||||
}
|
||||
m_frequency = _value;
|
||||
configurationChange();
|
||||
}
|
||||
protected:
|
||||
std::function<void()> m_ioChangeFunctor; //!< function pointer on the upper class
|
||||
void configurationChange() {
|
||||
if (m_ioChangeFunctor != NULL) {
|
||||
m_ioChangeFunctor();
|
||||
}
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Set the callback function to be notify when the arameter change.
|
||||
* @param[in] _functor Function to call.
|
||||
*/
|
||||
void setCallback(const std::function<void()>& _functor) {
|
||||
m_ioChangeFunctor = _functor;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Algo {
|
||||
protected:
|
||||
std::vector<int8_t> m_outputData;
|
||||
int8_t m_formatSize; //!< sample size
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Algo();
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Algo() {};
|
||||
protected:
|
||||
bool m_needProcess; //!< if no change, then no need to process, just forward buffer...
|
||||
IOFormatInterface m_input; //!< Input audio property
|
||||
public:
|
||||
void setInputFormat(const IOFormatInterface& _format) {
|
||||
m_input.setFormat(_format.getFormat());
|
||||
m_input.setFrequency(_format.getFrequency());
|
||||
m_input.setMap(_format.getMap());
|
||||
}
|
||||
const IOFormatInterface& getInputFormat() const {
|
||||
return m_input;
|
||||
}
|
||||
protected:
|
||||
IOFormatInterface m_output; //!< Output audio property
|
||||
public:
|
||||
void setOutputFormat(const IOFormatInterface& _format) {
|
||||
m_output.setFormat(_format.getFormat());
|
||||
m_output.setFrequency(_format.getFrequency());
|
||||
m_output.setMap(_format.getMap());
|
||||
}
|
||||
const IOFormatInterface& getOutputFormat() const {
|
||||
return m_output;
|
||||
}
|
||||
/**
|
||||
* @brief Called when a parameter change
|
||||
*/
|
||||
virtual void configurationChange();
|
||||
public:
|
||||
/**
|
||||
* @brief Process Algorithm
|
||||
* @param[in] _time Current buffer Time
|
||||
* @param[in] _input input pointer data (not free)
|
||||
* @param[in] _inputNbChunk Number of chunk in the buffer
|
||||
* @param[in] _output Output buffer (provide here) Do not free (can be the input buffer)
|
||||
* @param[in] _outputNbChunk Number of chunk in the output buffer
|
||||
* @return true The process is done corectly
|
||||
* @return false An error occured
|
||||
*/
|
||||
virtual bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk) = 0;
|
||||
/**
|
||||
* @brief To approximatively have the correct input of data of every algo ge call it to have an aproxomation of input data needed.
|
||||
* @param[in] _output number of chunk estimate in output
|
||||
* @return number of sample needed to have nearly the good number of sample
|
||||
*/
|
||||
virtual size_t needInputData(size_t _output);
|
||||
};
|
||||
};
|
||||
#include "debugRemove.h"
|
||||
|
||||
#endif
|
125
airtalgo/ChannelReorder.cpp
Normal file
125
airtalgo/ChannelReorder.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <airtalgo/ChannelReorder.h>
|
||||
#include <iostream>
|
||||
#include "debug.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
|
||||
airtalgo::ChannelReorder::ChannelReorder() {
|
||||
|
||||
}
|
||||
|
||||
void airtalgo::ChannelReorder::configurationChange() {
|
||||
airtalgo::autoLogInOut("ChannelReorder (config)");
|
||||
airtalgo::Algo::configurationChange();
|
||||
if (m_input.getFormat() != m_output.getFormat()) {
|
||||
AIRTALGO_ERROR("can not support Format Change ...");
|
||||
m_needProcess = false;
|
||||
}
|
||||
if (m_input.getFrequency() != m_output.getFrequency()) {
|
||||
AIRTALGO_ERROR("can not support frequency Change ...");
|
||||
m_needProcess = false;
|
||||
}
|
||||
if (m_input.getMap() == m_output.getMap()) {
|
||||
// nothing to process...
|
||||
m_needProcess = false;
|
||||
AIRTALGO_INFO(" no need to convert ... " << m_input.getMap() << " ==> " << m_output.getMap());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool airtalgo::ChannelReorder::process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk) {
|
||||
//airtalgo::autoLogInOut("ChannelReorder");
|
||||
_outputNbChunk = _inputNbChunk;
|
||||
// chack if we need to process:
|
||||
if (m_needProcess == false) {
|
||||
_output = _input;
|
||||
return true;
|
||||
}
|
||||
if (_input == nullptr) {
|
||||
_output = &(m_outputData[0]);
|
||||
_outputNbChunk = 0;
|
||||
AIRTALGO_ERROR("null pointer input ... ");
|
||||
return false;
|
||||
}
|
||||
m_outputData.resize(_outputNbChunk*m_output.getMap().size()*m_formatSize);
|
||||
_output = &(m_outputData[0]);
|
||||
// real process: (only depend of data size):
|
||||
switch (m_output.getFormat()) {
|
||||
default:
|
||||
case format_int16:
|
||||
{
|
||||
AIRTALGO_INFO("convert " << m_input.getMap() << " ==> " << m_output.getMap());
|
||||
int16_t* in = static_cast<int16_t*>(_input);
|
||||
int16_t* out = static_cast<int16_t*>(_output);
|
||||
for (size_t kkk=0; kkk<m_output.getMap().size(); ++kkk) {
|
||||
int32_t convertId = -1;
|
||||
if ( m_input.getMap().size() == 1
|
||||
&& m_input.getMap()[0] == airtalgo::channel_frontCenter) {
|
||||
convertId = 0;
|
||||
} else {
|
||||
for (size_t jjj=0; jjj<m_input.getMap().size(); ++jjj) {
|
||||
if (m_output.getMap()[kkk] == m_input.getMap()[jjj]) {
|
||||
convertId = jjj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (convertId == -1) {
|
||||
for (size_t iii=0; iii<_outputNbChunk; ++iii) {
|
||||
out[iii*m_output.getMap().size()+kkk] = 0;
|
||||
}
|
||||
} else {
|
||||
for (size_t iii=0; iii<_outputNbChunk; ++iii) {
|
||||
out[iii*m_output.getMap().size()+kkk] = in[iii*m_input.getMap().size()+convertId];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
case format_int32:
|
||||
case format_float:
|
||||
{
|
||||
AIRTALGO_INFO("convert (2) " << m_input.getMap() << " ==> " << m_output.getMap());
|
||||
uint32_t* in = static_cast<uint32_t*>(_input);
|
||||
uint32_t* out = static_cast<uint32_t*>(_output);
|
||||
for (size_t kkk=0; kkk<m_output.getMap().size(); ++kkk) {
|
||||
int32_t convertId = -1;
|
||||
if ( m_input.getMap().size() == 1
|
||||
&& m_input.getMap()[0] == airtalgo::channel_frontCenter) {
|
||||
convertId = 0;
|
||||
} else {
|
||||
for (size_t jjj=0; jjj<m_input.getMap().size(); ++jjj) {
|
||||
if (m_output.getMap()[kkk] == m_input.getMap()[jjj]) {
|
||||
convertId = jjj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (convertId == -1) {
|
||||
for (size_t iii=0; iii<_outputNbChunk; ++iii) {
|
||||
out[iii*m_output.getMap().size()+kkk] = 0;
|
||||
}
|
||||
} else {
|
||||
for (size_t iii=0; iii<_outputNbChunk; ++iii) {
|
||||
out[iii*m_output.getMap().size()+kkk] = in[iii*m_input.getMap().size()+convertId];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
34
airtalgo/ChannelReorder.h
Normal file
34
airtalgo/ChannelReorder.h
Normal file
@ -0,0 +1,34 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_CHANNEL_REORDER_H__
|
||||
#define __AIRT_ALGO_CHANNEL_REORDER_H__
|
||||
|
||||
#include <airtalgo/Algo.h>
|
||||
|
||||
namespace airtalgo{
|
||||
class ChannelReorder : public Algo {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
ChannelReorder();
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~ChannelReorder() {};
|
||||
protected:
|
||||
virtual void configurationChange();
|
||||
public:
|
||||
virtual bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
0
airtalgo/EndPoint.cpp
Normal file
0
airtalgo/EndPoint.cpp
Normal file
26
airtalgo/EndPoint.h
Normal file
26
airtalgo/EndPoint.h
Normal file
@ -0,0 +1,26 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_END_POINT_H__
|
||||
#define __AIRT_ALGO_END_POINT_H__
|
||||
|
||||
#include <airtalgo/Algo.h>
|
||||
|
||||
namespace airtalgo{
|
||||
class EndPoint : public Algo {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
EndPoint() {};
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~EndPoint() {};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
65
airtalgo/EndPointCallback.cpp
Normal file
65
airtalgo/EndPointCallback.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include <airtalgo/EndPointCallback.h>
|
||||
|
||||
airtalgo::EndPointCallback::EndPointCallback(needDataFunction _callback, enum formatDataType _dataFormat) :
|
||||
m_dataFormat(_dataFormat),
|
||||
m_output(_callback),
|
||||
m_input(nullptr) {
|
||||
|
||||
}
|
||||
airtalgo::EndPointCallback::EndPointCallback(haveNewDataFunction _callback, enum formatDataType _dataFormat) :
|
||||
m_dataFormat(_dataFormat),
|
||||
m_output(nullptr),
|
||||
m_input(_callback) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void airtalgo::EndPointCallback::configurationChange() {
|
||||
airtalgo::EndPoint::configurationChange();
|
||||
m_needProcess = true;
|
||||
}
|
||||
|
||||
|
||||
bool airtalgo::EndPointCallback::process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input, // uneeded
|
||||
size_t _inputNbChunk, // requested number of sample ...
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk){
|
||||
airtalgo::autoLogInOut("EndPointCallback");
|
||||
/*
|
||||
if (m_output != nullptr) {
|
||||
// call user
|
||||
AIRTALGO_INFO("call user get I16*" << _inputNbChunk << "*" << airtalgo::Algo::m_output.getMap().size() << " " << airtalgo::Algo::m_output.getMap());
|
||||
m_data = m_output(_time, _inputNbChunk, airtalgo::Algo::m_output.getMap());
|
||||
if (m_data.size() != _inputNbChunk*airtalgo::Algo::m_output.getMap().size()) {
|
||||
//ERROR
|
||||
return false;
|
||||
}
|
||||
_output = &m_data[0];
|
||||
_outputNbChunk = _inputNbChunk;
|
||||
return true;
|
||||
}
|
||||
if (m_input != nullptr) {
|
||||
// convert in data :
|
||||
// TODO : ...
|
||||
m_data.resize(_inputNbChunk*airtalgo::Algo::m_input.getMap().size());
|
||||
int16_t* data = static_cast<int16_t*>(_input);
|
||||
for (size_t iii; iii<m_data.size(); ++iii) {
|
||||
m_data[iii] = *data++;
|
||||
}
|
||||
// Call user ...
|
||||
AIRTALGO_INFO("call user set I16*" << _inputNbChunk << "*" << airtalgo::Algo::m_input.getMap().size());
|
||||
m_input(_time, _inputNbChunk, airtalgo::Algo::m_input.getMap(), m_data);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
46
airtalgo/EndPointCallback.h
Normal file
46
airtalgo/EndPointCallback.h
Normal file
@ -0,0 +1,46 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_END_POINT_CALLBACK_H__
|
||||
#define __AIRT_ALGO_END_POINT_CALLBACK_H__
|
||||
|
||||
#include <airtalgo/EndPoint.h>
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace airtalgo {
|
||||
enum formatDataType {
|
||||
formatDataTypeInt16,
|
||||
formatDataTypeInt32,
|
||||
};
|
||||
typedef std::function<void (const std::chrono::system_clock::time_point& _playTime, size_t _nbChunk, const std::vector<airtalgo::channel>& _map, void* _data, enum formatDataType& _type)> needDataFunction;
|
||||
typedef std::function<void (const std::chrono::system_clock::time_point& _readTime, size_t _nbChunk, const std::vector<airtalgo::channel>& _map, const void* _data, enum formatDataType& _type)> haveNewDataFunction;
|
||||
class EndPointCallback : public EndPoint {
|
||||
private:
|
||||
enum formatDataType m_dataFormat;
|
||||
needDataFunction m_output;
|
||||
haveNewDataFunction m_input;
|
||||
std::vector<uint8_t> m_data;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
EndPointCallback(needDataFunction _callback, enum formatDataType _dataFormat);
|
||||
EndPointCallback(haveNewDataFunction _callback, enum formatDataType _dataFormat);
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~EndPointCallback() {};
|
||||
virtual void configurationChange();
|
||||
virtual bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
29
airtalgo/EndPointRead.cpp
Normal file
29
airtalgo/EndPointRead.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include <airtalgo/EndPointRead.h>
|
||||
|
||||
airtalgo::EndPointRead::EndPointRead() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void airtalgo::EndPointRead::configurationChange() {
|
||||
airtalgo::EndPoint::configurationChange();
|
||||
m_needProcess = true;
|
||||
}
|
||||
|
||||
|
||||
bool airtalgo::EndPointRead::process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk){
|
||||
airtalgo::autoLogInOut("EndPointRead");
|
||||
return false;
|
||||
}
|
||||
|
32
airtalgo/EndPointRead.h
Normal file
32
airtalgo/EndPointRead.h
Normal file
@ -0,0 +1,32 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_END_POINT_READ_H__
|
||||
#define __AIRT_ALGO_END_POINT_READ_H__
|
||||
|
||||
#include <airtalgo/EndPoint.h>
|
||||
|
||||
namespace airtalgo{
|
||||
class EndPointRead : public EndPoint {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
EndPointRead();
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~EndPointRead() {};
|
||||
virtual void configurationChange();
|
||||
virtual bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
65
airtalgo/EndPointWrite.cpp
Normal file
65
airtalgo/EndPointWrite.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include "debug.h"
|
||||
#include <airtalgo/EndPointWrite.h>
|
||||
|
||||
airtalgo::EndPointWrite::EndPointWrite() :
|
||||
m_function(nullptr) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void airtalgo::EndPointWrite::configurationChange() {
|
||||
airtalgo::EndPoint::configurationChange();
|
||||
m_needProcess = true;
|
||||
}
|
||||
|
||||
|
||||
bool airtalgo::EndPointWrite::process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk){
|
||||
//airtalgo::autoLogInOut("EndPointWrite");
|
||||
//AIRTALGO_INFO(" nb Sample in buffer : " << m_tmpData.size());
|
||||
if (m_function != nullptr) {
|
||||
if (m_tmpData.size() <= 20000) {
|
||||
m_function(_time, _inputNbChunk, m_output.getMap());
|
||||
}
|
||||
}
|
||||
// resize output buffer:
|
||||
//AIRTALGO_INFO(" resize : " << (int32_t)m_formatSize << "*" << (int32_t)_inputNbChunk << "*" << (int32_t)m_outputMap.size());
|
||||
m_outputData.resize(m_formatSize*_inputNbChunk*m_output.getMap().size());
|
||||
// clear buffer
|
||||
memset(&m_outputData[0], 0, m_outputData.size());
|
||||
// set output pointer:
|
||||
_outputNbChunk = m_outputData.size()/(m_formatSize*m_output.getMap().size());
|
||||
_output = &m_outputData[0];
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
// check if data in the tmpBuffer
|
||||
if (m_tmpData.size() == 0) {
|
||||
AIRTALGO_WARNING("No data in the user buffer (write null data ... " << _outputNbChunk << " chunks)");
|
||||
// just send no data ...
|
||||
return true;
|
||||
}
|
||||
AIRTALGO_INFO("Write " << _outputNbChunk << " chunks");
|
||||
// check if we have enought data:
|
||||
int32_t nbChunkToCopy = std::min(_inputNbChunk, m_outputData.size()/m_output.getMap().size());
|
||||
// copy data to the output:
|
||||
memcpy(_output, &m_tmpData[0], nbChunkToCopy*m_output.getMap().size()*m_formatSize);
|
||||
// remove old data:
|
||||
m_tmpData.erase(m_tmpData.begin(), m_tmpData.begin()+nbChunkToCopy*m_output.getMap().size());
|
||||
//AIRTALGO_INFO(" nb Sample in buffer : " << m_tmpData.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void airtalgo::EndPointWrite::write(const int16_t* _value, size_t _nbValue) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
AIRTALGO_INFO("[ASYNC] Get data : " << _nbValue << " ==> " << _nbValue/m_output.getMap().size() << " chumks");
|
||||
for (size_t iii=0; iii<_nbValue; ++iii) {
|
||||
m_tmpData.push_back(*_value++);
|
||||
}
|
||||
}
|
43
airtalgo/EndPointWrite.h
Normal file
43
airtalgo/EndPointWrite.h
Normal file
@ -0,0 +1,43 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_ALGO_END_POINT_WRITE_H__
|
||||
#define __AIRT_ALGO_ALGO_END_POINT_WRITE_H__
|
||||
|
||||
#include <airtalgo/EndPoint.h>
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
|
||||
namespace airtalgo{
|
||||
typedef std::function<void (const std::chrono::system_clock::time_point& _playTime, const size_t& _nbChunk, const std::vector<airtalgo::channel>& _map)> writeNeedDataFunction_int16_t;
|
||||
class EndPointWrite : public EndPoint {
|
||||
private:
|
||||
std::vector<int16_t> m_tmpData;
|
||||
writeNeedDataFunction_int16_t m_function;
|
||||
std::mutex m_mutex;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
EndPointWrite();
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~EndPointWrite() {};
|
||||
virtual void configurationChange();
|
||||
virtual bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk);
|
||||
virtual void write(const int16_t* _value, size_t _nbValue);
|
||||
virtual void setCallback(writeNeedDataFunction_int16_t _function) {
|
||||
m_function = _function;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
259
airtalgo/FormatUpdate.cpp
Normal file
259
airtalgo/FormatUpdate.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include <airtalgo/FormatUpdate.h>
|
||||
#include <iostream>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
static void convert__int16__to__int16_on_int32(void* _input, void* _output, size_t _nbSample) {
|
||||
int16_t* in = static_cast<int16_t*>(_input);
|
||||
int32_t* out = static_cast<int32_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
out[iii] = in[iii];
|
||||
}
|
||||
}
|
||||
static void convert__int16__to__int32(void* _input, void* _output, size_t _nbSample) {
|
||||
int16_t* in = static_cast<int16_t*>(_input);
|
||||
int32_t* out = static_cast<int32_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
out[iii] = in[iii]<<16;
|
||||
}
|
||||
}
|
||||
static void convert__int16__to__float(void* _input, void* _output, size_t _nbSample) {
|
||||
int16_t* in = static_cast<int16_t*>(_input);
|
||||
float* out = static_cast<float*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
// TODO : Set * intead of /
|
||||
out[iii] = static_cast<float>(in[iii])/static_cast<float>(INT16_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
static void convert__int16_on_int32__to__int16(void* _input, void* _output, size_t _nbSample) {
|
||||
int32_t* in = static_cast<int32_t*>(_input);
|
||||
int16_t* out = static_cast<int16_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
out[iii] = static_cast<int16_t>(std::min(std::max(INT16_MIN, in[iii]), INT16_MAX));
|
||||
}
|
||||
}
|
||||
static void convert__int16_on_int32__to__int32(void* _input, void* _output, size_t _nbSample) {
|
||||
int32_t* in = static_cast<int32_t*>(_input);
|
||||
int32_t* out = static_cast<int32_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
int32_t value = std::min(std::max(INT16_MIN, in[iii]), INT16_MAX);
|
||||
out[iii] = value << 16;
|
||||
}
|
||||
}
|
||||
static void convert__int16_on_int32__to__float(void* _input, void* _output, size_t _nbSample) {
|
||||
int32_t* in = static_cast<int32_t*>(_input);
|
||||
float* out = static_cast<float*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
// TODO : Set * intead of /
|
||||
out[iii] = static_cast<float>(in[iii])/static_cast<float>(INT16_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
static void convert__int32__to__int16(void* _input, void* _output, size_t _nbSample) {
|
||||
int32_t* in = static_cast<int32_t*>(_input);
|
||||
int16_t* out = static_cast<int16_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
int32_t value = in[iii] >> 16;
|
||||
out[iii] = static_cast<int16_t>(std::min(std::max(INT16_MIN, value), INT16_MAX));
|
||||
}
|
||||
}
|
||||
static void convert__int32__to__int16_on_int32(void* _input, void* _output, size_t _nbSample) {
|
||||
int32_t* in = static_cast<int32_t*>(_input);
|
||||
int16_t* out = static_cast<int16_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
out[iii] = in[iii] >> 16;
|
||||
}
|
||||
}
|
||||
static void convert__int32__to__float(void* _input, void* _output, size_t _nbSample) {
|
||||
int32_t* in = static_cast<int32_t*>(_input);
|
||||
float* out = static_cast<float*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
// TODO : Set * intead of /
|
||||
out[iii] = static_cast<float>(in[iii])/static_cast<float>(INT32_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
static void convert__float__to__int16(void* _input, void* _output, size_t _nbSample) {
|
||||
float* in = static_cast<float*>(_input);
|
||||
int16_t* out = static_cast<int16_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
float value = in[iii] * static_cast<float>(INT16_MAX);
|
||||
value = std::min(std::max(static_cast<float>(INT16_MIN), value), static_cast<float>(INT16_MAX));
|
||||
out[iii] = static_cast<int16_t>(value);
|
||||
//AIRTALGO_VERBOSE(" in=" << in[iii] << " out=" << out[iii]);
|
||||
}
|
||||
}
|
||||
static void convert__float__to__int16_on_int32(void* _input, void* _output, size_t _nbSample) {
|
||||
float* in = static_cast<float*>(_input);
|
||||
int32_t* out = static_cast<int32_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
float value = in[iii] * static_cast<float>(INT16_MAX);
|
||||
value = std::min(std::max(static_cast<float>(INT32_MIN), value), static_cast<float>(INT32_MAX));
|
||||
out[iii] = static_cast<int32_t>(value);
|
||||
}
|
||||
}
|
||||
static void convert__float__to__int32(void* _input, void* _output, size_t _nbSample) {
|
||||
float* in = static_cast<float*>(_input);
|
||||
int32_t* out = static_cast<int32_t*>(_output);
|
||||
for (size_t iii=0; iii<_nbSample; ++iii) {
|
||||
float value = in[iii] * static_cast<float>(INT32_MAX);
|
||||
value = std::min(std::max(static_cast<float>(INT32_MIN), value), static_cast<float>(INT32_MAX));
|
||||
out[iii] = static_cast<int32_t>(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
airtalgo::FormatUpdate::FormatUpdate() :
|
||||
m_functionConvert(NULL) {
|
||||
|
||||
}
|
||||
|
||||
void airtalgo::FormatUpdate::configurationChange() {
|
||||
airtalgo::Algo::configurationChange();
|
||||
if (m_input.getMap() != m_output.getMap()) {
|
||||
AIRTALGO_ERROR("can not support Map Change ...");
|
||||
m_needProcess = false;
|
||||
}
|
||||
if (m_input.getFrequency() != m_output.getFrequency()) {
|
||||
AIRTALGO_ERROR("can not support frequency Change ...");
|
||||
m_needProcess = false;
|
||||
}
|
||||
if (m_input.getFormat() == m_output.getFormat()) {
|
||||
// nothing to process...
|
||||
m_needProcess = false;
|
||||
return;
|
||||
}
|
||||
switch (m_input.getFormat()) {
|
||||
default:
|
||||
case format_int16:
|
||||
switch (m_output.getFormat()) {
|
||||
default:
|
||||
case format_int16:
|
||||
AIRTALGO_ERROR(" Impossible case 1");
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
m_functionConvert = &convert__int16__to__int16_on_int32;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int16__to__int16_on_int32' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_int32:
|
||||
m_functionConvert = &convert__int16__to__int32;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int16__to__int32' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_float:
|
||||
m_functionConvert = &convert__int16__to__float;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int16__to__float' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
switch (m_output.getFormat()) {
|
||||
default:
|
||||
case format_int16:
|
||||
m_functionConvert = &convert__int16_on_int32__to__int16;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int16_on_int32__to__int16' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
AIRTALGO_ERROR(" Impossible case 2");
|
||||
break;
|
||||
case format_int32:
|
||||
m_functionConvert = &convert__int16_on_int32__to__int32;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int16_on_int32__to__int32' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_float:
|
||||
m_functionConvert = &convert__int16_on_int32__to__float;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int16_on_int32__to__float' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case format_int32:
|
||||
switch (m_output.getFormat()) {
|
||||
default:
|
||||
case format_int16:
|
||||
m_functionConvert = &convert__int32__to__int16;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int32__to__int16' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
m_functionConvert = &convert__int32__to__int16_on_int32;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int32__to__int16_on_int32' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_int32:
|
||||
AIRTALGO_ERROR(" Impossible case 3");
|
||||
break;
|
||||
case format_float:
|
||||
m_functionConvert = &convert__int32__to__float;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__int32__to__float' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case format_float:
|
||||
switch (m_output.getFormat()) {
|
||||
default:
|
||||
case format_int16:
|
||||
m_functionConvert = &convert__float__to__int16;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__float__to__int16' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
m_functionConvert = &convert__float__to__int16_on_int32;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__float__to__int16_on_int32' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_int32:
|
||||
m_functionConvert = &convert__float__to__int32;
|
||||
AIRTALGO_DEBUG(" use converter : 'convert__float__to__int32' for " << m_input.getFormat() << " to " << m_output.getFormat());
|
||||
break;
|
||||
case format_float:
|
||||
AIRTALGO_ERROR(" Impossible case 4");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool airtalgo::FormatUpdate::process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk) {
|
||||
//airtalgo::autoLogInOut("FormatUpdate");
|
||||
// chack if we need to process:
|
||||
if (m_needProcess == false) {
|
||||
_output = _input;
|
||||
_outputNbChunk = _inputNbChunk;
|
||||
return true;
|
||||
}
|
||||
if (_input == NULL) {
|
||||
_output = &(m_outputData[0]);
|
||||
_outputNbChunk = 0;
|
||||
AIRTALGO_ERROR("null pointer input ... ");
|
||||
return false;
|
||||
}
|
||||
_outputNbChunk = _inputNbChunk;
|
||||
m_outputData.resize(_outputNbChunk*m_input.getMap().size()*m_formatSize);
|
||||
_output = &(m_outputData[0]);
|
||||
if (m_functionConvert == NULL) {
|
||||
AIRTALGO_ERROR("null function ptr");
|
||||
return false;
|
||||
}
|
||||
m_functionConvert(_input, _output, _outputNbChunk*m_input.getMap().size());
|
||||
return true;
|
||||
}
|
35
airtalgo/FormatUpdate.h
Normal file
35
airtalgo/FormatUpdate.h
Normal file
@ -0,0 +1,35 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#ifndef __AIRT_ALGO_FORMAT_UPDATE_H__
|
||||
#define __AIRT_ALGO_FORMAT_UPDATE_H__
|
||||
|
||||
#include <airtalgo/Algo.h>
|
||||
|
||||
namespace airtalgo {
|
||||
class FormatUpdate : public Algo {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
FormatUpdate();
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~FormatUpdate() {};
|
||||
protected:
|
||||
virtual void configurationChange();
|
||||
public:
|
||||
virtual bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk);
|
||||
private:
|
||||
void (*m_functionConvert)(void* _input, void* _output, size_t _nbSample);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
81
airtalgo/Process.cpp
Normal file
81
airtalgo/Process.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <airtalgo/format.h>
|
||||
#include <airtalgo/channel.h>
|
||||
#include <airtalgo/Process.h>
|
||||
#include <chrono>
|
||||
|
||||
airtalgo::Process::Process() {
|
||||
|
||||
}
|
||||
|
||||
bool airtalgo::Process::push(std::chrono::system_clock::time_point& _time,
|
||||
void* _data,
|
||||
size_t _nbChunk) {
|
||||
void* out = nullptr;
|
||||
size_t nbChunkOut;
|
||||
AIRTALGO_VERBOSE(" Interface DIRECT ");
|
||||
process(_time, _data, _nbChunk, out, nbChunkOut);
|
||||
}
|
||||
|
||||
bool airtalgo::Process::pull(std::chrono::system_clock::time_point& _time,
|
||||
void*& _data,
|
||||
size_t& _nbChunk) {
|
||||
void* in = nullptr;
|
||||
size_t nbChunkIn = _nbChunk;
|
||||
void* out = nullptr;
|
||||
size_t nbChunkOut;
|
||||
if (nbChunkIn < 128) {
|
||||
nbChunkIn = 128;
|
||||
}
|
||||
for (int32_t iii=m_listAlgo.size()-1; iii >=0; --iii) {
|
||||
if (m_listAlgo[iii] != nullptr) {
|
||||
nbChunkIn = m_listAlgo[iii]->needInputData(nbChunkIn);
|
||||
}
|
||||
}
|
||||
if (nbChunkIn < 32) {
|
||||
nbChunkIn = 32;
|
||||
}
|
||||
process(_time, in, nbChunkIn, _data, _nbChunk);
|
||||
}
|
||||
|
||||
bool airtalgo::Process::process(std::chrono::system_clock::time_point& _time,
|
||||
void* _inData,
|
||||
size_t _inNbChunk,
|
||||
void*& _outData,
|
||||
size_t& _outNbChunk) {
|
||||
if (m_listAlgo.size() == 0) {
|
||||
_outData = _inData;
|
||||
_outNbChunk = _inNbChunk;
|
||||
return true;
|
||||
}
|
||||
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
|
||||
//std::cout << " Algo " << iii+1 << "/" << m_listAlgo.size() << std::endl;
|
||||
if (m_listAlgo[iii] != nullptr) {
|
||||
m_listAlgo[iii]->process(_time, _inData, _inNbChunk, _outData, _outNbChunk);
|
||||
_inData = _outData;
|
||||
_inNbChunk = _outNbChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void airtalgo::Process::pushBack(const std::shared_ptr<airtalgo::Algo>& _algo) {
|
||||
m_listAlgo.push_back(_algo);
|
||||
}
|
||||
|
||||
void airtalgo::Process::pushFront(const std::shared_ptr<airtalgo::Algo>& _algo) {
|
||||
m_listAlgo.insert(m_listAlgo.begin(), _algo);
|
||||
}
|
||||
|
||||
void airtalgo::Process::updateInterAlgo() {
|
||||
// TODO : ...
|
||||
}
|
74
airtalgo/Process.h
Normal file
74
airtalgo/Process.h
Normal file
@ -0,0 +1,74 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __AIRT_ALGO_PROCESS_H__
|
||||
#define __AIRT_ALGO_PROCESS_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <airtalgo/format.h>
|
||||
#include <airtalgo/channel.h>
|
||||
#include <airtalgo/Algo.h>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
namespace airtalgo{
|
||||
class Process {
|
||||
public:
|
||||
Process();
|
||||
public:
|
||||
/**
|
||||
* @brief Push data in the algo stream.
|
||||
* @param[in] _time Time of the first sample pushed.
|
||||
* @param[in] _data Pointer on the data pushed.
|
||||
* @param[in] _nbChunk Number of chunk present in the pointer.
|
||||
* @return true The procress is done corectly.
|
||||
* @return false An error occured.
|
||||
*/
|
||||
bool push(std::chrono::system_clock::time_point& _time,
|
||||
void* _data,
|
||||
size_t _nbChunk);
|
||||
/**
|
||||
* @brief Push data in the algo stream.
|
||||
* @param[in] _time Time of the first sample requested.
|
||||
* @param[in] _data Pointer on the data pushed.
|
||||
* @param[in,out] _nbChunk Number of chunk present in the pointer (set at the number of chunk requested(hope)).
|
||||
* @return true The procress is done corectly.
|
||||
* @return false An error occured.
|
||||
*/
|
||||
bool pull(std::chrono::system_clock::time_point& _time,
|
||||
void*& _data,
|
||||
size_t& _nbChunk);
|
||||
/**
|
||||
* @brief Push data in the algo stream.
|
||||
* @param[in] _time Time of the first sample pushed.
|
||||
* @param[in] _inData Pointer on the data pushed.
|
||||
* @param[in] _inNbChunk Number of chunk present in the input pointer.
|
||||
* @param[out] _outData Pointer on the data geted.
|
||||
* @param[out] _outNbChunk Number of chunk present in the output pointer.
|
||||
* @return true The procress is done corectly.
|
||||
* @return false An error occured.
|
||||
*/
|
||||
bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _inData,
|
||||
size_t _inNbChunk,
|
||||
void*& _outData,
|
||||
size_t& _outNbChunk);
|
||||
protected:
|
||||
std::vector<std::shared_ptr<airtalgo::Algo> > m_listAlgo;
|
||||
public:
|
||||
void pushBack(const std::shared_ptr<airtalgo::Algo>& _algo);
|
||||
void pushFront(const std::shared_ptr<airtalgo::Algo>& _algo);
|
||||
void updateInterAlgo();
|
||||
void clear() {
|
||||
m_listAlgo.clear();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
129
airtalgo/Resampler.cpp
Normal file
129
airtalgo/Resampler.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include <airtalgo/Resampler.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
airtalgo::Resampler::Resampler() :
|
||||
#ifdef HAVE_SPEEX_DSP_RESAMPLE
|
||||
m_speexResampler(nullptr),
|
||||
#endif
|
||||
m_positionRead(0),
|
||||
m_positionWrite(0) {
|
||||
|
||||
}
|
||||
airtalgo::Resampler::~Resampler() {
|
||||
#ifdef HAVE_SPEEX_DSP_RESAMPLE
|
||||
if (m_speexResampler != nullptr) {
|
||||
speex_resampler_destroy(m_speexResampler);
|
||||
m_speexResampler = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void airtalgo::Resampler::configurationChange() {
|
||||
airtalgo::Algo::configurationChange();
|
||||
if (m_input.getFormat() != m_output.getFormat()) {
|
||||
AIRTALGO_ERROR("can not support Format Change ...");
|
||||
m_needProcess = false;
|
||||
}
|
||||
if (m_input.getFormat() != format_int16) {
|
||||
AIRTALGO_ERROR("can not support Format other than int16_t ...");
|
||||
m_needProcess = false;
|
||||
return;
|
||||
}
|
||||
if (m_output.getMap() != m_output.getMap()) {
|
||||
AIRTALGO_ERROR("can not support map Change ...");
|
||||
m_needProcess = false;
|
||||
}
|
||||
if (m_input.getFrequency() == m_output.getFrequency()) {
|
||||
// nothing to process...
|
||||
m_needProcess = false;
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_SPEEX_DSP_RESAMPLE
|
||||
if (m_speexResampler != nullptr) {
|
||||
speex_resampler_destroy(m_speexResampler);
|
||||
m_speexResampler = nullptr;
|
||||
}
|
||||
int err = 0;
|
||||
m_speexResampler = speex_resampler_init(m_outputMap.size(),
|
||||
m_inputFrequency,
|
||||
m_outputFrequency,
|
||||
10, &err);
|
||||
#else
|
||||
std::cerr << "SPEEX DSP lib not accessible ==> can not resample" << std::endl;
|
||||
m_needProcess = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool airtalgo::Resampler::process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk) {
|
||||
//airtalgo::autoLogInOut("Resampler");
|
||||
_outputNbChunk = 2048;
|
||||
// chack if we need to process:
|
||||
if (m_needProcess == false) {
|
||||
AIRTALGO_WARNING("no process");
|
||||
_output = _input;
|
||||
_outputNbChunk = _inputNbChunk;
|
||||
return true;
|
||||
}
|
||||
if (_input == nullptr) {
|
||||
_output = &(m_outputData[0]);
|
||||
_outputNbChunk = 0;
|
||||
AIRTALGO_ERROR("null pointer input ... ");
|
||||
return false;
|
||||
}
|
||||
#ifdef HAVE_SPEEX_DSP_RESAMPLE
|
||||
float nbInputTime = static_cast<float>(_inputNbChunk)/m_input.getFrequency();
|
||||
float nbOutputSample = nbInputTime*m_output.getFrequency();
|
||||
// we add 10% of the buffer size to have all the time enought data in the output to proceed all the input data...
|
||||
_outputNbChunk = static_cast<size_t>(nbOutputSample*1.5f);
|
||||
AIRTALGO_VERBOSE(" freq in=" << m_inputFrequency << " out=" << m_outputFrequency);
|
||||
AIRTALGO_VERBOSE(" Frame duration=" << nbInputTime);
|
||||
AIRTALGO_VERBOSE(" nbInput chunk=" << _inputNbChunk << " nbOutputChunk=" << nbOutputSample);
|
||||
|
||||
m_outputData.resize(_outputNbChunk*m_input.getMap().size()*m_formatSize);
|
||||
_output = &(m_outputData[0]);
|
||||
if (m_speexResampler == nullptr) {
|
||||
std::cout << " No speex resampler" << std::endl;
|
||||
return false;
|
||||
}
|
||||
uint32_t nbChunkInput = _inputNbChunk;
|
||||
uint32_t nbChunkOutput = _outputNbChunk;
|
||||
AIRTALGO_VERBOSE(" >> input=" << nbChunkInput << " output=" << nbChunkOutput);
|
||||
int ret = speex_resampler_process_interleaved_int(m_speexResampler,
|
||||
static_cast<int16_t*>(_input),
|
||||
&nbChunkInput,
|
||||
static_cast<int16_t*>(_output),
|
||||
&nbChunkOutput);
|
||||
AIRTALGO_VERBOSE(" << input=" << nbChunkInput << " output=" << nbChunkOutput);
|
||||
// update position of data:
|
||||
m_positionWrite += nbChunkOutput;
|
||||
// Check all input and output ...
|
||||
if (nbChunkInput != _inputNbChunk) {
|
||||
AIRTALGO_ERROR(" inputSize (not all read ...) proceed=" << nbChunkInput << " requested=" << _inputNbChunk);
|
||||
// TODO : manage this case ...
|
||||
}
|
||||
if (nbChunkOutput == _outputNbChunk) {
|
||||
AIRTALGO_ERROR(" Might have not enought data in output... output size=" << _outputNbChunk);
|
||||
// TODO : manage this case ...
|
||||
}
|
||||
_outputNbChunk = nbChunkOutput;
|
||||
AIRTALGO_VERBOSE(" process chunk=" << nbChunkInput << " out=" << nbChunkOutput);
|
||||
return true;
|
||||
#else
|
||||
_output = _input;
|
||||
_outputNbChunk = _inputNbChunk;
|
||||
return false;
|
||||
#endif
|
||||
}
|
44
airtalgo/Resampler.h
Normal file
44
airtalgo/Resampler.h
Normal file
@ -0,0 +1,44 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_RESAMPLER_H__
|
||||
#define __AIRT_ALGO_RESAMPLER_H__
|
||||
|
||||
#include <airtalgo/Algo.h>
|
||||
#ifdef HAVE_SPEEX_DSP_RESAMPLE
|
||||
#include <speex/speex_resampler.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
|
||||
namespace airtalgo {
|
||||
class Resampler : public Algo {
|
||||
private:
|
||||
#ifdef HAVE_SPEEX_DSP_RESAMPLE
|
||||
SpeexResamplerState* m_speexResampler;
|
||||
#endif
|
||||
size_t m_positionRead; //!< For residual data in the buffer last read number of chunk
|
||||
size_t m_positionWrite; //!< Current pointer of writing new output data of resampler
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Resampler();
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~Resampler();
|
||||
protected:
|
||||
virtual void configurationChange();
|
||||
public:
|
||||
virtual bool process(std::chrono::system_clock::time_point& _time,
|
||||
void* _input,
|
||||
size_t _inputNbChunk,
|
||||
void*& _output,
|
||||
size_t& _outputNbChunk);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
8
airtalgo/airtalgo.cpp
Normal file
8
airtalgo/airtalgo.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
|
43
airtalgo/airtalgo.h
Normal file
43
airtalgo/airtalgo.h
Normal file
@ -0,0 +1,43 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_CORE_H__
|
||||
#define __AIRT_ALGO_CORE_H__
|
||||
|
||||
#include <string>
|
||||
#include <airtalgo/format.h>
|
||||
#include <airtalgo/channel.h>
|
||||
#include <chrono>
|
||||
|
||||
namespace airtalgo {
|
||||
/**
|
||||
* @brief Init the instance af algorithm (add all internal factory)
|
||||
*/
|
||||
void init();
|
||||
/**
|
||||
* @brief Uninit the instance af algorithm (rm all internal factory)
|
||||
*/
|
||||
void init();
|
||||
/**
|
||||
* @brief Create a process Algo with his name.
|
||||
* @param[in] _name Name of the Algorithm.
|
||||
* @return Instanciate algorithm
|
||||
*/
|
||||
airtalgo::Algo* createAlgo(const std::string& _name);
|
||||
/**
|
||||
* @brief Add a Factory Algorithm in the internal List (static for all instance)
|
||||
* @param[in] _name Name of the Algorithm.
|
||||
* @param[in] _functor Function of the factory
|
||||
*/
|
||||
void addAlgoFactory(const std::string& _name, std::function<airtalgo::Algo*(void)> _functor);
|
||||
/**
|
||||
* @brief Remove a Factory Algorithm in the internal List (static for all instance)
|
||||
* @param[in] _name Name of the Algorithm.
|
||||
*/
|
||||
void RmAlgoFactory(const std::string& _name);
|
||||
};
|
||||
|
||||
#endif
|
119
airtalgo/channel.cpp
Normal file
119
airtalgo/channel.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <airtalgo/channel.h>
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
std::ostream& airtalgo::operator <<(std::ostream& _os, enum airtalgo::channel _obj) {
|
||||
_os << getChannelString(_obj);
|
||||
return _os;
|
||||
}
|
||||
|
||||
std::string airtalgo::getChannelString(enum airtalgo::channel _value) {
|
||||
switch (_value) {
|
||||
case channel_frontLeft:
|
||||
return "front-left";
|
||||
break;
|
||||
case channel_frontCenter:
|
||||
return "front-center";
|
||||
break;
|
||||
case channel_frontRight:
|
||||
return "front-right";
|
||||
break;
|
||||
case channel_rearLeft:
|
||||
return "rear-left";
|
||||
break;
|
||||
case channel_rearCenter:
|
||||
return "rear-center";
|
||||
break;
|
||||
case channel_rearRight:
|
||||
return "rear-right";
|
||||
break;
|
||||
case channel_surroundLeft:
|
||||
return "surround-left";
|
||||
break;
|
||||
case channel_surroundRight:
|
||||
return "surround-right";
|
||||
break;
|
||||
case channel_subWoofer:
|
||||
return "sub-woofer";
|
||||
break;
|
||||
case channel_lfe:
|
||||
return "lfe";
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
std::string airtalgo::getChannelString(const std::vector<enum airtalgo::channel>& _value) {
|
||||
std::string out;
|
||||
for (size_t iii=0; iii<_value.size(); ++iii) {
|
||||
if (iii != 0) {
|
||||
out += ";";
|
||||
}
|
||||
out += getChannelString(_value[iii]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& airtalgo::operator <<(std::ostream& _os, std::vector<enum airtalgo::channel> _obj) {
|
||||
_os << std::string("{");
|
||||
for (size_t iii=0; iii<_obj.size(); ++iii) {
|
||||
if (iii!=0) {
|
||||
_os << std::string(";");
|
||||
}
|
||||
_os << _obj[iii];
|
||||
}
|
||||
_os << std::string("}");
|
||||
return _os;
|
||||
}
|
||||
|
||||
static std::vector<std::string> split(const std::string& _input, char _val) {
|
||||
std::vector<std::string> list;
|
||||
size_t lastStartPos = 0;
|
||||
for(size_t iii=0; iii<_input.size(); iii++) {
|
||||
if (_input[iii]==_val) {
|
||||
list.push_back(std::string(_input, lastStartPos, iii - lastStartPos));
|
||||
lastStartPos = iii+1;
|
||||
}
|
||||
}
|
||||
if (lastStartPos<_input.size()) {
|
||||
list.push_back(std::string(_input, lastStartPos));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
std::vector<enum airtalgo::channel> airtalgo::getChannelFromString(const std::string& _value) {
|
||||
std::vector<enum airtalgo::channel> out;
|
||||
std::vector<std::string> listIO = split(_value, ';');
|
||||
for (size_t iii=0; iii<listIO.size(); ++iii) {
|
||||
if (listIO[iii] == "front-left") {
|
||||
out.push_back(channel_frontLeft);
|
||||
} else if (listIO[iii] == "front-right") {
|
||||
out.push_back(channel_frontRight);
|
||||
} else if (listIO[iii] == "front-center") {
|
||||
out.push_back(channel_frontCenter);
|
||||
} else if (listIO[iii] == "rear-left") {
|
||||
out.push_back(channel_rearLeft);
|
||||
} else if (listIO[iii] == "rear-right") {
|
||||
out.push_back(channel_rearRight);
|
||||
} else if (listIO[iii] == "rear-center") {
|
||||
out.push_back(channel_rearCenter);
|
||||
} else if (listIO[iii] == "surround-right") {
|
||||
out.push_back(channel_surroundLeft);
|
||||
} else if (listIO[iii] == "surround-left") {
|
||||
out.push_back(channel_surroundRight);
|
||||
} else if (listIO[iii] == "lfe") {
|
||||
out.push_back(channel_lfe);
|
||||
} else if (listIO[iii] == "sub-woofer") {
|
||||
out.push_back(channel_subWoofer);
|
||||
} else {
|
||||
//ROS_ERROR("Unknow: '%s' in [front-left;front-right;front-center;rear-left;rear-right;rear-center;surround-right;surround-left;lfe;subwoofer]", listIO[iii].c_str());
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
34
airtalgo/channel.h
Normal file
34
airtalgo/channel.h
Normal file
@ -0,0 +1,34 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_CORE_CHANNEL_H__
|
||||
#define __AIRT_ALGO_CORE_CHANNEL_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace airtalgo{
|
||||
enum channel {
|
||||
channel_frontLeft, //!< channel Front Left
|
||||
channel_frontCenter, //!< channel Front Center
|
||||
channel_frontRight, //!< channel Front Right
|
||||
channel_rearLeft, //!< channel rear Left
|
||||
channel_rearCenter, //!< channel rear Center
|
||||
channel_rearRight, //!< channel rear Right
|
||||
channel_surroundLeft, //!< channel surround Left
|
||||
channel_surroundRight, //!< channel surround Right
|
||||
channel_subWoofer, //!< channel Sub-woofer
|
||||
channel_lfe, //!< channel Low frequency
|
||||
};
|
||||
std::string getChannelString(enum airtalgo::channel);
|
||||
std::string getChannelString(const std::vector<enum airtalgo::channel>&);
|
||||
std::vector<enum airtalgo::channel> getChannelFromString(const std::string& _value);
|
||||
std::ostream& operator <<(std::ostream& _os, enum airtalgo::channel _obj);
|
||||
std::ostream& operator <<(std::ostream& _os, std::vector<enum airtalgo::channel> _obj);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
13
airtalgo/debug.cpp
Normal file
13
airtalgo/debug.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include <airtalgo/debug.h>
|
||||
|
||||
|
||||
int32_t airtalgo::getLogId() {
|
||||
static int32_t g_val = etk::log::registerInstance("airtalgo");
|
||||
return g_val;
|
||||
}
|
50
airtalgo/debug.h
Normal file
50
airtalgo/debug.h
Normal file
@ -0,0 +1,50 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRTALGO_DEBUG_H__
|
||||
#define __AIRTALGO_DEBUG_H__
|
||||
|
||||
#include <etk/log.h>
|
||||
|
||||
namespace airtalgo {
|
||||
int32_t getLogId();
|
||||
};
|
||||
// TODO : Review this problem of multiple intanciation of "std::stringbuf sb"
|
||||
#define AIRTALGO_BASE(info,data) \
|
||||
do { \
|
||||
if (info <= etk::log::getLevel(airtalgo::getLogId())) { \
|
||||
std::stringbuf sb; \
|
||||
std::ostream tmpStream(&sb); \
|
||||
tmpStream << data; \
|
||||
etk::log::logStream(airtalgo::getLogId(), info, __LINE__, __class__, __func__, tmpStream); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define AIRTALGO_CRITICAL(data) AIRTALGO_BASE(1, data)
|
||||
#define AIRTALGO_ERROR(data) AIRTALGO_BASE(2, data)
|
||||
#define AIRTALGO_WARNING(data) AIRTALGO_BASE(3, data)
|
||||
#ifdef DEBUG
|
||||
#define AIRTALGO_INFO(data) AIRTALGO_BASE(4, data)
|
||||
#define AIRTALGO_DEBUG(data) AIRTALGO_BASE(5, data)
|
||||
#define AIRTALGO_VERBOSE(data) AIRTALGO_BASE(6, data)
|
||||
#define AIRTALGO_TODO(data) AIRTALGO_BASE(4, "TODO : " << data)
|
||||
#else
|
||||
#define AIRTALGO_INFO(data) do { } while(false)
|
||||
#define AIRTALGO_DEBUG(data) do { } while(false)
|
||||
#define AIRTALGO_VERBOSE(data) do { } while(false)
|
||||
#define AIRTALGO_TODO(data) do { } while(false)
|
||||
#endif
|
||||
|
||||
#define AIRTALGO_ASSERT(cond,data) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
AIRTALGO_CRITICAL(data); \
|
||||
assert(!#cond); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
22
airtalgo/debugRemove.h
Normal file
22
airtalgo/debugRemove.h
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD 3 clauses (see license file)
|
||||
*/
|
||||
|
||||
#ifdef __AIRTALGOO_DEBUG_H__
|
||||
#undef __AIRTALGOO_DEBUG_H__
|
||||
|
||||
#undef AIRTALGO_BASE
|
||||
#undef AIRTALGO_CRITICAL
|
||||
#undef AIRTALGO_ERROR
|
||||
#undef AIRTALGO_WARNING
|
||||
#undef AIRTALGO_INFO
|
||||
#undef AIRTALGO_DEBUG
|
||||
#undef AIRTALGO_VERBOSE
|
||||
#undef AIRTALGO_TODO
|
||||
#undef AIRTALGO_ASSERT
|
||||
#endif
|
||||
|
46
airtalgo/format.cpp
Normal file
46
airtalgo/format.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include <airtalgo/format.h>
|
||||
|
||||
std::ostream& airtalgo::operator <<(std::ostream& _os, enum airtalgo::format _obj) {
|
||||
_os << getFormatString(_obj);
|
||||
return _os;
|
||||
}
|
||||
|
||||
std::string airtalgo::getFormatString(enum airtalgo::format _value) {
|
||||
switch (_value) {
|
||||
case format_int16:
|
||||
return "format_int16";
|
||||
break;
|
||||
case format_int16_on_int32:
|
||||
return "format_int16_on_int32";
|
||||
break;
|
||||
case format_int32:
|
||||
return "format_int32";
|
||||
break;
|
||||
case format_float:
|
||||
return "format_float";
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
enum airtalgo::format airtalgo::getFormatFromString(const std::string& _value) {
|
||||
if (_value == "format_int16") {
|
||||
return format_int16;
|
||||
}
|
||||
if (_value == "format_int16_on_int32") {
|
||||
return format_int16_on_int32;
|
||||
}
|
||||
if (_value == "format_int32") {
|
||||
return format_int32;
|
||||
}
|
||||
if (_value == "format_float") {
|
||||
return format_float;
|
||||
}
|
||||
return format_int16;
|
||||
}
|
26
airtalgo/format.h
Normal file
26
airtalgo/format.h
Normal file
@ -0,0 +1,26 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __AIRT_ALGO_CORE_FORMAT_H__
|
||||
#define __AIRT_ALGO_CORE_FORMAT_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace airtalgo{
|
||||
enum format {
|
||||
format_int16, //!< Signed 16 bits
|
||||
format_int16_on_int32, //!< Signed 16 bits on 32bits data (16 bit fixpoint value)
|
||||
format_int32, //!< Signed 32 bits
|
||||
format_float, //!< Floating point (single precision)
|
||||
};
|
||||
std::string getFormatString(enum airtalgo::format);
|
||||
enum airtalgo::format getFormatFromString(const std::string& _value);
|
||||
std::ostream& operator <<(std::ostream& _os, enum airtalgo::format _obj);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
43
lutin_airtalgo.py
Normal file
43
lutin_airtalgo.py
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/python
|
||||
import lutinModule as module
|
||||
import lutinTools as tools
|
||||
import lutinDebug as debug
|
||||
|
||||
def get_desc():
|
||||
return "airtalgo : Basic algo interface"
|
||||
|
||||
|
||||
def create(target):
|
||||
myModule = module.Module(__file__, 'airtalgo', 'LIBRARY')
|
||||
|
||||
myModule.add_src_file([
|
||||
'airtalgo/debug.cpp',
|
||||
'airtalgo/airtalgo.cpp',
|
||||
'airtalgo/Algo.cpp',
|
||||
'airtalgo/channel.cpp',
|
||||
'airtalgo/ChannelReorder.cpp',
|
||||
'airtalgo/EndPointCallback.cpp',
|
||||
'airtalgo/EndPoint.cpp',
|
||||
'airtalgo/EndPointRead.cpp',
|
||||
'airtalgo/EndPointWrite.cpp',
|
||||
'airtalgo/format.cpp',
|
||||
'airtalgo/FormatUpdate.cpp',
|
||||
'airtalgo/Process.cpp',
|
||||
'airtalgo/Resampler.cpp'
|
||||
])
|
||||
|
||||
|
||||
myModule.add_module_depend(['etk'])
|
||||
myModule.add_export_path(tools.get_current_path(__file__))
|
||||
|
||||
# add the currrent module at the
|
||||
return myModule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user