[DEV] rework drain in audio-drain

This commit is contained in:
Edouard DUPIN 2015-04-10 23:00:13 +02:00
parent 98cbaedc2c
commit 62e581f5ae
55 changed files with 1728 additions and 1694 deletions

View File

@ -3,7 +3,7 @@
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <drain/Algo.h>
#include <audio/drain/Algo.h>
#include <functional>
#include "debug.h"
@ -11,7 +11,7 @@
#undef __class__
#define __class__ "Algo"
drain::Algo::Algo() :
audio::drain::Algo::Algo() :
m_temporary(false),
m_outputData(),
m_formatSize(0),
@ -19,15 +19,15 @@ drain::Algo::Algo() :
}
void drain::Algo::init() {
void audio::drain::Algo::init() {
// set notification callback :
m_input.setCallback(std11::bind(&drain::Algo::configurationChangeLocal, this));
m_output.setCallback(std11::bind(&drain::Algo::configurationChangeLocal, this));
m_input.setCallback(std11::bind(&audio::drain::Algo::configurationChangeLocal, this));
m_output.setCallback(std11::bind(&audio::drain::Algo::configurationChangeLocal, this));
// first configure ==> update the internal parameters
configurationChange();
}
void drain::Algo::configurationChange() {
void audio::drain::Algo::configurationChange() {
m_needProcess = false;
if (m_input.getFormat() != m_output.getFormat()) {
m_needProcess = true;
@ -63,7 +63,7 @@ void drain::Algo::configurationChange() {
}
}
size_t drain::Algo::needInputData(size_t _output) {
size_t audio::drain::Algo::needInputData(size_t _output) {
size_t input = _output;
/* NOT good at all ...
if (m_input.getFormat() != m_output.getFormat()) {
@ -102,11 +102,11 @@ size_t drain::Algo::needInputData(size_t _output) {
return input;
}
void drain::Algo::setStatusFunction(algoStatusFunction _newFunction) {
void audio::drain::Algo::setStatusFunction(algoStatusFunction _newFunction) {
m_statusFunction = _newFunction;
}
void drain::Algo::generateStatus(const std::string& _status) {
void audio::drain::Algo::generateStatus(const std::string& _status) {
if (m_statusFunction != nullptr) {
if (m_name.size() == 0) {
m_statusFunction(m_type, _status);

216
audio/drain/Algo.h Normal file
View File

@ -0,0 +1,216 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_CORE_ALGO_H__
#define __AUDIO_DRAIN_ALGO_CORE_ALGO_H__
#include <string>
#include <vector>
#include <stdint.h>
#include <audio/format.h>
#include <audio/channel.h>
#include <etk/chrono.h>
#include <etk/functional.h>
#include <etk/memory.h>
#include "AutoLogInOut.h"
#include "IOFormatInterface.h"
#include "debug.h"
namespace audio {
namespace drain{
typedef std11::function<void (const std::string& _origin, const std::string& _status)> algoStatusFunction;
class Algo : public std11::enable_shared_from_this<Algo> {
private:
std::string m_name;
public:
const std::string& getName() const {
return m_name;
}
void setName(const std::string& _name) {
m_name = _name;
}
protected:
std::string m_type;
public:
const std::string& getType() const {
return m_type;
}
void setType(const std::string& _type) {
m_type = _type;
}
private:
bool m_temporary;
public:
void setTemporary() {
m_temporary = true;
}
bool getTemporary() const {
return m_temporary;
}
private:
algoStatusFunction m_statusFunction;
public:
void setStatusFunction(algoStatusFunction _newFunction);
protected:
void generateStatus(const std::string& _status);
protected:
std::vector<int8_t> m_outputData;
int8_t m_formatSize; //!< sample size
/**
* @brief Constructor
*/
Algo();
void init();
public:
/**
* @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.set(_format.getMap(), _format.getFormat(), _format.getFrequency());
}
const IOFormatInterface& getInputFormat() const {
return m_input;
}
IOFormatInterface& getInputFormat() {
return m_input;
}
protected:
IOFormatInterface m_output; //!< Output audio property
public:
void setOutputFormat(const IOFormatInterface& _format) {
m_output.set(_format.getMap(), _format.getFormat(), _format.getFrequency());
}
const IOFormatInterface& getOutputFormat() const {
return m_output;
}
IOFormatInterface& getOutputFormat() {
return m_output;
}
private:
void configurationChangeLocal() {
if ( m_output.getConfigured() == true
&& m_output.getConfigured() == true) {
configurationChange();
}
}
public:
/**
* @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(std11::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
*/
// TODO : Manage the change of the timestamp ...
virtual size_t needInputData(size_t _output);
protected: // note when nothing ==> support all type
std::vector<audio::format> m_supportedFormat;
public:
virtual std::vector<audio::format> getFormatSupportedInput() {
if (m_output.getConfigured() == true) {
std::vector<audio::format> out;
out.push_back(m_output.getFormat());
return out;
}
return m_supportedFormat;
};
virtual std::vector<audio::format> getFormatSupportedOutput() {
if (m_input.getConfigured() == true) {
std::vector<audio::format> out;
out.push_back(m_input.getFormat());
return out;
}
return m_supportedFormat;
};
protected: // note when nothing ==> support all type
std::vector<std::vector<audio::channel> > m_supportedMap;
public:
virtual std::vector<std::vector<audio::channel> > getMapSupportedInput() {
if (m_output.getConfigured() == true) {
std::vector<std::vector<audio::channel> > out;
out.push_back(m_output.getMap());
return out;
}
return m_supportedMap;
};
virtual std::vector<std::vector<audio::channel> > getMapSupportedOutput() {
if (m_input.getConfigured() == true) {
std::vector<std::vector<audio::channel> > out;
out.push_back(m_input.getMap());
return out;
}
return m_supportedMap;
};
protected: // note when nothing ==> support all type
std::vector<float> m_supportedFrequency;
public:
virtual std::vector<float> getFrequencySupportedInput() {
if (m_output.getConfigured() == true) {
std::vector<float> out;
out.push_back(m_output.getFrequency());
return out;
}
return m_supportedFrequency;
};
virtual std::vector<float> getFrequencySupportedOutput() {
if (m_input.getConfigured() == true) {
std::vector<float> out;
out.push_back(m_input.getFrequency());
return out;
}
return m_supportedFrequency;
};
public:
/**
* @brief Set a parameter in the stream flow
* @param[in] _parameter Parameter name.
* @param[in] _value Value to set.
* @return true set done
* @return false An error occured
*/
virtual bool setParameter(const std::string& _parameter, const std::string& _value) { return false; }
/**
* @brief Get a parameter value
* @param[in] _parameter Parameter name.
* @return The requested value.
*/
virtual std::string getParameter(const std::string& _parameter) const { return "[ERROR]"; }
/**
* @brief Get a parameter value
* @param[in] _parameter Parameter name.
* @return The requested value.
*/
virtual std::string getParameterProperty(const std::string& _parameter) const { return "[ERROR]"; };
};
}
}
#include "debugRemove.h"
#endif

View File

@ -7,11 +7,11 @@
#include "AutoLogInOut.h"
#include "debug.h"
drain::AutoLogInOut::AutoLogInOut(const std::string& _value) :
audio::drain::AutoLogInOut::AutoLogInOut(const std::string& _value) :
m_value(_value) {
DRAIN_VERBOSE(" '" << m_value << "' [START]");
}
drain::AutoLogInOut::~AutoLogInOut() {
audio::drain::AutoLogInOut::~AutoLogInOut() {
DRAIN_VERBOSE(" '" << m_value << "' [STOP]");
}

View File

@ -0,0 +1,29 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_AUTO_LOG_IN_OUT_H__
#define __AUDIO_DRAIN_ALGO_AUTO_LOG_IN_OUT_H__
#include <string>
#include "debug.h"
namespace audio {
namespace drain{
class AutoLogInOut {
private:
std::string m_value;
public:
AutoLogInOut(const std::string& _value);
~AutoLogInOut();
};
}
}
#include "debugRemove.h"
#endif

View File

@ -4,8 +4,8 @@
* @license APACHE v2.0 (see license file)
*/
#include <drain/debug.h>
#include <drain/BiQuadFloat.h>
#include <audio/drain/debug.h>
#include <audio/drain/BiQuadFloat.h>
static const char* listValues[] = {
"none",
@ -21,24 +21,24 @@ static int32_t listValuesSize = sizeof(listValues)/sizeof(char*);
namespace etk {
template<> std::string to_string<enum drain::filterType>(const enum drain::filterType& _variable) {
template<> std::string to_string<enum audio::drain::filterType>(const enum audio::drain::filterType& _variable) {
return listValues[_variable];
}
template <> bool from_string<enum drain::filterType>(enum drain::filterType& _variableRet, const std::string& _value) {
template <> bool from_string<enum audio::drain::filterType>(enum audio::drain::filterType& _variableRet, const std::string& _value) {
for (int32_t iii=0; iii<listValuesSize; ++iii) {
if (_value == listValues[iii]) {
_variableRet = static_cast<enum drain::filterType>(iii);
_variableRet = static_cast<enum audio::drain::filterType>(iii);
return true;
}
}
_variableRet = drain::filterType_none;
_variableRet = audio::drain::filterType_none;
return false;
}
}
drain::BiQuadFloat::BiQuadFloat() {
audio::drain::BiQuadFloat::BiQuadFloat() {
reset();
// reset coefficients
m_a[0] = 1.0;
@ -49,7 +49,7 @@ drain::BiQuadFloat::BiQuadFloat() {
}
float drain::BiQuadFloat::processFloat(float _sample) {
float audio::drain::BiQuadFloat::processFloat(float _sample) {
float result;
// compute
result = m_a[0] * _sample
@ -66,11 +66,11 @@ float drain::BiQuadFloat::processFloat(float _sample) {
return result;
}
void drain::BiQuadFloat::processFloat(float* _input,
float* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset) {
void audio::drain::BiQuadFloat::processFloat(float* _input,
float* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset) {
for (size_t iii=0; iii<_nbChunk; ++iii) {
// process in float the biquad.
*_output = processFloat(*_input);
@ -80,11 +80,11 @@ void drain::BiQuadFloat::processFloat(float* _input,
}
}
void drain::BiQuadFloat::processInt16(int16_t* _input,
int16_t* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset) {
void audio::drain::BiQuadFloat::processInt16(int16_t* _input,
int16_t* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset) {
for (size_t iii=0; iii<_nbChunk; ++iii) {
// process in float the biquad.
float out = processFloat(*_input);
@ -98,7 +98,7 @@ void drain::BiQuadFloat::processInt16(int16_t* _input,
}
void drain::BiQuadFloat::setBiquad(enum drain::filterType _type, double _frequencyCut, double _qualityFactor, double _gain, float _sampleRate) {
void audio::drain::BiQuadFloat::setBiquad(enum audio::drain::filterType _type, double _frequencyCut, double _qualityFactor, double _gain, float _sampleRate) {
reset();
if (_sampleRate < 1) {
m_a[0] = 1.0;
@ -213,14 +213,14 @@ void drain::BiQuadFloat::setBiquad(enum drain::filterType _type, double _frequen
}
}
void drain::BiQuadFloat::reset() {
void audio::drain::BiQuadFloat::reset() {
m_x[0] = 0;
m_y[1] = 0;
m_x[0] = 0;
m_y[1] = 0;
}
void drain::BiQuadFloat::setBiquadCoef(float _a0, float _a1, float _a2, float _b0, float _b1) {
void audio::drain::BiQuadFloat::setBiquadCoef(float _a0, float _a1, float _a2, float _b0, float _b1) {
m_a[0] = _a0;
m_a[1] = _a1;
m_a[2] = _a2;
@ -228,7 +228,7 @@ void drain::BiQuadFloat::setBiquadCoef(float _a0, float _a1, float _a2, float _b
m_b[1] = _b1;
reset();
}
void drain::BiQuadFloat::getBiquadCoef(float& _a0, float& _a1, float& _a2, float& _b0, float& _b1) {
void audio::drain::BiQuadFloat::getBiquadCoef(float& _a0, float& _a1, float& _a2, float& _b0, float& _b1) {
_a0 = m_a[0];
_a1 = m_a[1];
_a2 = m_a[2];
@ -236,7 +236,7 @@ void drain::BiQuadFloat::getBiquadCoef(float& _a0, float& _a1, float& _a2, float
_b1 = m_b[1];
}
std::vector<float> drain::BiQuadFloat::getCoef() {
std::vector<float> audio::drain::BiQuadFloat::getCoef() {
std::vector<float> out;
out.push_back(m_a[0]);
out.push_back(m_a[1]);
@ -247,7 +247,7 @@ std::vector<float> drain::BiQuadFloat::getCoef() {
}
std::vector<std::pair<float,float> > drain::BiQuadFloat::calculateTheory(double _sampleRate) {
std::vector<std::pair<float,float> > audio::drain::BiQuadFloat::calculateTheory(double _sampleRate) {
std::vector<std::pair<float,float> > out;
double norm;

97
audio/drain/BiQuadFloat.h Normal file
View File

@ -0,0 +1,97 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_BIQUAD_FLOAT_H__
#define __AUDIO_DRAIN_ALGO_BIQUAD_FLOAT_H__
#include <audio/drain/Algo.h>
#include <etk/memory.h>
namespace audio {
namespace drain {
enum filterType {
filterType_none, //!< no filter (pass threw...)
filterType_lowPass, //!< low pass filter
filterType_highPass, //!< High pass filter
filterType_bandPass, //!< band pass filter
filterType_notch, //!< Notch Filter
filterType_peak, //!< Peaking band EQ filter
filterType_lowShelf, //!< Low shelf filter
filterType_highShelf, //!< High shelf filter
};
class BiQuadFloat {
public:
BiQuadFloat();
protected:
float m_x[2]; //!< X history
float m_y[2]; //!< Y histiry
float m_a[3]; //!< A bi-Quad coef
float m_b[2]; //!< B bi-Quad coef
public:
/**
* @brief Set the bi-quad value and type
* @param[in] _type Type of biquad.
* @param[in] _frequencyCut Cut Frequency. [0..sampleRate/2]
* @param[in] _qualityFactor Q factor of quality (good value of 0.707 ==> permit to not ower gain) limit [0.01 .. 10]
* @param[in] _gain Gain to apply (for notch, peak, lowShelf and highShelf) limit : -30, +30
* @param[in] _sampleRate Sample rate of the signal
*/
void setBiquad(enum audio::drain::filterType _type, double _frequencyCut, double _qualityFactor, double _gain, float _sampleRate);
/**
* @brief Set direct Coefficients
*/
void setBiquadCoef(float _a0, float _a1, float _a2, float _b0, float _b1);
/**
* @brief Get direct Coefficients
*/
void getBiquadCoef(float& _a0, float& _a1, float& _a2, float& _b0, float& _b1);
/**
* @brief Get direct Coefficients
*/
std::vector<float> getCoef();
/**
* @brief Reset bequad filter (only history not value).
*/
void reset();
protected:
/**
* @brief process single sample in float.
* @param[in] _sample Sample to process
* @return updataed value
*/
float processFloat(float _sample);
public:
/**
* @brief Porcess function.
* param[in] _input Pointer on the input data.
* param[in,out] _output Poirter on the output data (can be the same as input (inplace availlable).
* param[in] _nbChunk Number of qample to process.
* param[in] _inputOffset Offset to add when read input data.
* param[in] _outputOffset Offset to add when write output data.
*/
void processFloat(float* _input,
float* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset);
//! @previous
void processInt16(int16_t* _input,
int16_t* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset);
/**
* @brief calculate respond of the filter:
* @param[in] _sampleRate input qample rate
* @retrun list of frequency/power in dB
*/
std::vector<std::pair<float,float> > calculateTheory(double _sampleRate);
};
}
}
#endif

View File

@ -4,7 +4,7 @@
* @license APACHE v2.0 (see license file)
*/
#include <drain/ChannelReorder.h>
#include <audio/drain/ChannelReorder.h>
#include <iostream>
#include "debug.h"
#include "debug.h"
@ -13,25 +13,25 @@
#undef __class__
#define __class__ "ChannelReorder"
drain::ChannelReorder::ChannelReorder() {
audio::drain::ChannelReorder::ChannelReorder() {
}
void drain::ChannelReorder::init() {
drain::Algo::init();
void audio::drain::ChannelReorder::init() {
audio::drain::Algo::init();
m_type = "ChannelReorder";
}
std11::shared_ptr<drain::ChannelReorder> drain::ChannelReorder::create() {
std11::shared_ptr<drain::ChannelReorder> tmp(new drain::ChannelReorder());
std11::shared_ptr<audio::drain::ChannelReorder> audio::drain::ChannelReorder::create() {
std11::shared_ptr<audio::drain::ChannelReorder> tmp(new audio::drain::ChannelReorder());
tmp->init();
return tmp;
}
void drain::ChannelReorder::configurationChange() {
drain::AutoLogInOut("ChannelReorder (config)");
drain::Algo::configurationChange();
void audio::drain::ChannelReorder::configurationChange() {
audio::drain::AutoLogInOut("ChannelReorder (config)");
audio::drain::Algo::configurationChange();
if (m_input.getFormat() != m_output.getFormat()) {
DRAIN_ERROR("can not support Format Change ...");
m_needProcess = false;
@ -49,12 +49,12 @@ void drain::ChannelReorder::configurationChange() {
}
bool drain::ChannelReorder::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
drain::AutoLogInOut tmpLog("ChannelReorder");
bool audio::drain::ChannelReorder::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
audio::drain::AutoLogInOut tmpLog("ChannelReorder");
_outputNbChunk = _inputNbChunk;
// check if we need to process:
if (m_needProcess == false) {

View File

@ -0,0 +1,39 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_CHANNEL_REORDER_H__
#define __AUDIO_DRAIN_ALGO_CHANNEL_REORDER_H__
#include <audio/drain/Algo.h>
namespace audio {
namespace drain{
class ChannelReorder : public audio::drain::Algo {
protected:
/**
* @brief Constructor
*/
ChannelReorder();
void init();
public:
static std11::shared_ptr<audio::drain::ChannelReorder> create();
/**
* @brief Destructor
*/
virtual ~ChannelReorder() {};
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
};
}
}
#endif

View File

@ -4,10 +4,10 @@
* @license APACHE v2.0 (see license file)
*/
#include <drain/CircularBuffer.h>
#include <drain/debug.h>
#include <audio/drain/CircularBuffer.h>
#include <audio/drain/debug.h>
drain::CircularBuffer::CircularBuffer(const drain::CircularBuffer& _obj) :
audio::drain::CircularBuffer::CircularBuffer(const audio::drain::CircularBuffer& _obj) :
m_data(),
m_write(nullptr),
m_read(nullptr),
@ -20,12 +20,12 @@ drain::CircularBuffer::CircularBuffer(const drain::CircularBuffer& _obj) :
/**
* @brief copy operator.
*/
drain::CircularBuffer& drain::CircularBuffer::operator=(const drain::CircularBuffer& _obj) {
audio::drain::CircularBuffer& audio::drain::CircularBuffer::operator=(const audio::drain::CircularBuffer& _obj) {
DRAIN_CRITICAL("error");
return *this;
};
drain::CircularBuffer::CircularBuffer() :
audio::drain::CircularBuffer::CircularBuffer() :
m_data(),
m_write(nullptr),
m_read(nullptr),
@ -36,13 +36,13 @@ drain::CircularBuffer::CircularBuffer() :
// nothing to do ...
}
drain::CircularBuffer::~CircularBuffer() {
audio::drain::CircularBuffer::~CircularBuffer() {
m_data.clear();
m_read = nullptr;
m_write = nullptr;
}
void drain::CircularBuffer::setCapacity(size_t _capacity, size_t _chunkSize, uint32_t _frequency) {
void audio::drain::CircularBuffer::setCapacity(size_t _capacity, size_t _chunkSize, uint32_t _frequency) {
if ( _chunkSize == m_sizeChunk
&& _capacity == m_capacity) {
clear();
@ -75,14 +75,14 @@ void drain::CircularBuffer::setCapacity(size_t _capacity, size_t _chunkSize, uin
m_write = &m_data[0];
}
void drain::CircularBuffer::setCapacity(std11::chrono::milliseconds _capacity, size_t _chunkSize, uint32_t _frequency) {
void audio::drain::CircularBuffer::setCapacity(std11::chrono::milliseconds _capacity, size_t _chunkSize, uint32_t _frequency) {
uint32_t nbSampleNeeded = _frequency*_capacity.count()/1000;
DRAIN_DEBUG("buffer setCapacity(" << _capacity.count() << "ms ," << _chunkSize << ")");
setCapacity(nbSampleNeeded, _chunkSize, _frequency);
}
size_t drain::CircularBuffer::getUsedSizeBeforEnd() const {
size_t audio::drain::CircularBuffer::getUsedSizeBeforEnd() const {
size_t size;
if (m_read < m_write) {
size = static_cast<uint8_t*>(m_write) - static_cast<uint8_t*>(m_read);
@ -100,7 +100,7 @@ size_t drain::CircularBuffer::getUsedSizeBeforEnd() const {
return size;
}
size_t drain::CircularBuffer::getFreeSizeBeforEnd() const {
size_t audio::drain::CircularBuffer::getFreeSizeBeforEnd() const {
size_t size;
size = &m_data[0]
+ (m_capacity*m_sizeChunk)
@ -109,11 +109,11 @@ size_t drain::CircularBuffer::getFreeSizeBeforEnd() const {
size /= m_sizeChunk;
return size;
}
size_t drain::CircularBuffer::write(const void* _data, size_t _nbChunk) {
size_t audio::drain::CircularBuffer::write(const void* _data, size_t _nbChunk) {
return write(_data, _nbChunk, std11::chrono::system_clock::now());//m_timeRead + )
}
size_t drain::CircularBuffer::write(const void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time) {
size_t audio::drain::CircularBuffer::write(const void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time) {
if (m_data.size() == 0) {
DRAIN_ERROR("EMPTY Buffer");
return _nbChunk;
@ -179,11 +179,11 @@ size_t drain::CircularBuffer::write(const void* _data, size_t _nbChunk, const st
return nbElementDrop;
}
size_t drain::CircularBuffer::read(void* _data, size_t _nbChunk) {
size_t audio::drain::CircularBuffer::read(void* _data, size_t _nbChunk) {
return read(_data, _nbChunk, m_timeRead);
}
size_t drain::CircularBuffer::read(void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time) {
size_t audio::drain::CircularBuffer::read(void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time) {
size_t nbElementDrop = 0;
// Critical section (theoriquely protected by Mutex)
size_t usedSizeBeforeEnd = getUsedSizeBeforEnd();
@ -251,7 +251,7 @@ size_t drain::CircularBuffer::read(void* _data, size_t _nbChunk, const std11::ch
return nbElementDrop;
}
void drain::CircularBuffer::setReadPosition(const std11::chrono::system_clock::time_point& _time) {
void audio::drain::CircularBuffer::setReadPosition(const std11::chrono::system_clock::time_point& _time) {
// Critical section (theoriquely protected by Mutex)
size_t usedSizeBeforeEnd = getUsedSizeBeforEnd();
if (0 < m_size) {
@ -279,11 +279,11 @@ void drain::CircularBuffer::setReadPosition(const std11::chrono::system_clock::t
}
size_t drain::CircularBuffer::getFreeSize() const {
size_t audio::drain::CircularBuffer::getFreeSize() const {
return m_capacity - m_size;
}
void drain::CircularBuffer::clear() {
void audio::drain::CircularBuffer::clear() {
DRAIN_DEBUG("buffer clear()");
// set pointer to the start
m_read = &m_data[0];

View File

@ -0,0 +1,145 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_CIRCULAR_BUFFER_H__
#define __AUDIO_DRAIN_CIRCULAR_BUFFER_H__
#include <etk/types.h>
#include <vector>
#include <etk/chrono.h>
namespace audio {
namespace drain {
/**
* For these functions we have 4 solutions :
* - Free Buffer
* ----------------------------------------------------------
* m_data | | |
* ----------------------------------------------------------
* m_write
* m_read
* - Full Buffer
* ----------------------------------------------------------
* m_data |****************************|***************************|
* ----------------------------------------------------------
* m_write
* m_read
* - Buffer in used
* ----------------------------------------------------------
* m_data | |********************| |
* ----------------------------------------------------------
* m_read m_write
* - Buffer out used
* ----------------------------------------------------------
* m_data |****************| |******************|
* ----------------------------------------------------------
* m_read m_write
*/
class CircularBuffer {
private:
std::vector<uint8_t> m_data; //!< data pointer
void* m_write; //!< write pointer
void* m_read; //!< read pointer
std11::chrono::system_clock::time_point m_timeRead; //!< current read time
uint32_t m_frequency;
// TODO : Remove the m_size ==> this is a bad element to be mutex-less
size_t m_size; //!< number of chunk availlable in this buffer
size_t m_capacity; //!< number of chunk available in this Buffer
size_t m_sizeChunk; //!< Size of one chunk (in byte)
public:
CircularBuffer();
~CircularBuffer();
/**
* @brief copy contructor.
* @param[in] _obj Circular buffer object
*/
CircularBuffer(const audio::drain::CircularBuffer& _obj);
/**
* @brief copy operator.
* @param[in] _obj Circular buffer object
*/
CircularBuffer& operator=(const audio::drain::CircularBuffer& _obj);
/**
* @brief set the capacity of the circular buffer.
* @param[in] _capacity Number of chunk in the buffer.
* @param[in] _chunkSize Size of one chunk.
* @param[in] _frequency Frequency of the buffer
*/
void setCapacity(size_t _capacity, size_t _chunkSize, uint32_t _frequency);
/**
* @brief set the capacity of the circular buffer.
* @param[in] _capacity time in millisecond stored in the buffer.
* @param[in] _chunkSize Size of one chunk.
* @param[in] _frequency Frequency of the buffer
*/
void setCapacity(std11::chrono::milliseconds _capacity, size_t _chunkSize, uint32_t _frequency);
void setCapacity(std11::chrono::microseconds _capacity, size_t _chunkSize, uint32_t _frequency) {
setCapacity(std11::chrono::milliseconds(_capacity.count()/1000), _chunkSize, _frequency);
}
/**
* @brief get free size of the buffer.
* @return Number of free chunk.
*/
size_t getFreeSize() const;
/**
* @brief Get number of chunk in the buffer.
* @return number of chunk.
*/
size_t getSize() const {
return m_size;
}
/**
* @brief Get number of chunk that can be set in the buffer.
* @return number of chunk.
*/
size_t getCapacity() const {
return m_capacity;
}
/**
* @brief Write chunk in the buffer.
* @param[in] _data Pointer on the data.
* @param[in] _nbChunk number of chunk to copy.
* @param[in] _time Time to start write data (if before end ==> not replace data, write only if after end)
* @return Number of chunk copied.
*/
size_t write(const void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time);
size_t write(const void* _data, size_t _nbChunk);
/**
* @brief Read Chunk from the buffer to the pointer data.
* @param[out] _data Pointer on the data.
* @param[in] _nbChunk number of chunk to copy.
* @param[in] _time Time to start read data (if before start ==> add 0 at start, if after, remove unread data)
* @return Number of chunk copied.
*/
size_t read(void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time);
//! @previous
size_t read(void* _data, size_t _nbChunk);
void setReadPosition(const std11::chrono::system_clock::time_point& _time);
std11::chrono::system_clock::time_point getReadTimeStamp() {
return m_timeRead;
}
/**
* @brief Clear the buffer.
*/
void clear();
private:
/**
* @brief Get number of free chunks before end of buffer.
* @return Number of chunk.
*/
size_t getFreeSizeBeforEnd() const;
/**
* @brief Get number of used chunks before end of buffer.
* @return Number of chunk.
*/
size_t getUsedSizeBeforEnd() const;
};
}
}
#endif

34
audio/drain/EndPoint.h Normal file
View File

@ -0,0 +1,34 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_END_POINT_H__
#define __AUDIO_DRAIN_ALGO_END_POINT_H__
#include <audio/drain/Algo.h>
namespace audio {
namespace drain{
class EndPoint : public Algo {
protected:
/**
* @brief Constructor
*/
EndPoint() {};
void init() {
drain::Algo::init();
};
public:
/**
* @brief Destructor
*/
virtual ~EndPoint() {
};
};
}
}
#endif

View File

@ -4,54 +4,54 @@
* @license APACHE v2.0 (see license file)
*/
#include "debug.h"
#include <drain/EndPointCallback.h>
#include <audio/drain/EndPointCallback.h>
#include <audio/drain/debug.h>
#undef __class__
#define __class__ "EndPointCallback"
drain::EndPointCallback::EndPointCallback() :
audio::drain::EndPointCallback::EndPointCallback() :
m_outputFunction(nullptr),
m_inputFunction(nullptr) {
}
void drain::EndPointCallback::init(playbackFunction _callback) {
void audio::drain::EndPointCallback::init(playbackFunction _callback) {
m_outputFunction = _callback;
drain::EndPoint::init();
audio::drain::EndPoint::init();
m_type = "EndPointCallback";
}
void drain::EndPointCallback::init(recordFunction _callback) {
void audio::drain::EndPointCallback::init(recordFunction _callback) {
m_inputFunction = _callback;
drain::EndPoint::init();
audio::drain::EndPoint::init();
m_type = "EndPointCallback";
}
std11::shared_ptr<drain::EndPointCallback> drain::EndPointCallback::create(playbackFunction _callback) {
std11::shared_ptr<drain::EndPointCallback> tmp(new drain::EndPointCallback());
std11::shared_ptr<audio::drain::EndPointCallback> audio::drain::EndPointCallback::create(playbackFunction _callback) {
std11::shared_ptr<audio::drain::EndPointCallback> tmp(new audio::drain::EndPointCallback());
tmp->init(_callback);
return tmp;
}
std11::shared_ptr<drain::EndPointCallback> drain::EndPointCallback::create(recordFunction _callback) {
std11::shared_ptr<drain::EndPointCallback> tmp(new drain::EndPointCallback());
std11::shared_ptr<audio::drain::EndPointCallback> audio::drain::EndPointCallback::create(recordFunction _callback) {
std11::shared_ptr<audio::drain::EndPointCallback> tmp(new audio::drain::EndPointCallback());
tmp->init(_callback);
return tmp;
}
void drain::EndPointCallback::configurationChange() {
drain::EndPoint::configurationChange();
void audio::drain::EndPointCallback::configurationChange() {
audio::drain::EndPoint::configurationChange();
DRAIN_INFO("update : format=" << m_output.getFormat() << " map=" << m_input.getMap() << " freq=" << m_input.getFrequency() << " size=" << int32_t(m_formatSize));
m_needProcess = true;
}
bool drain::EndPointCallback::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
drain::AutoLogInOut tmpLog("EndPointCallback");
bool audio::drain::EndPointCallback::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
audio::drain::AutoLogInOut tmpLog("EndPointCallback");
if (m_inputFunction != nullptr) {
// Call user ...
DRAIN_VERBOSE("call user set " << _inputNbChunk << "*" << m_input.getMap().size());

View File

@ -0,0 +1,55 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_END_POINT_CALLBACK_H__
#define __AUDIO_DRAIN_ALGO_END_POINT_CALLBACK_H__
#include <audio/drain/EndPoint.h>
#include <etk/functional.h>
namespace audio {
namespace drain {
typedef std11::function<void (void* _data,
const std11::chrono::system_clock::time_point& _playTime,
size_t _nbChunk,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> playbackFunction;
typedef std11::function<void (const void* _data,
const std11::chrono::system_clock::time_point& _readTime,
size_t _nbChunk,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> recordFunction;
class EndPointCallback : public EndPoint {
private:
playbackFunction m_outputFunction;
recordFunction m_inputFunction;
protected:
/**
* @brief Constructor
*/
EndPointCallback();
void init(playbackFunction _callback);
void init(recordFunction _callback);
public:
static std11::shared_ptr<EndPointCallback> create(playbackFunction _callback);
static std11::shared_ptr<EndPointCallback> create(recordFunction _callback);
/**
* @brief Destructor
*/
virtual ~EndPointCallback() {};
virtual void configurationChange();
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
};
}
}
#endif

View File

@ -0,0 +1,71 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <audio/drain/EndPointRead.h>
#include <audio/drain/debug.h>
#undef __class__
#define __class__ "EndPointRead"
audio::drain::EndPointRead::EndPointRead() {
}
void audio::drain::EndPointRead::init() {
audio::drain::EndPoint::init();
m_type = "EndPointRead";
}
std11::shared_ptr<audio::drain::EndPointRead> audio::drain::EndPointRead::create() {
std11::shared_ptr<audio::drain::EndPointRead> tmp(new audio::drain::EndPointRead());
tmp->init();
return tmp;
}
void audio::drain::EndPointRead::configurationChange() {
audio::drain::EndPoint::configurationChange();
m_needProcess = true;
}
bool audio::drain::EndPointRead::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
audio::drain::AutoLogInOut tmpLog("EndPointRead");
return false;
}
void audio::drain::EndPointRead::setBufferSize(size_t _nbChunk) {
DRAIN_TODO("...");
}
void audio::drain::EndPointRead::setBufferSize(const std11::chrono::microseconds& _time) {
DRAIN_TODO("...");
}
size_t audio::drain::EndPointRead::getBufferSize() {
DRAIN_TODO("...");
return 0;
}
std11::chrono::microseconds audio::drain::EndPointRead::getBufferSizeMicrosecond() {
DRAIN_TODO("...");
return std11::chrono::microseconds(0);
}
size_t audio::drain::EndPointRead::getBufferFillSize() {
DRAIN_TODO("...");
return 0;
}
std11::chrono::microseconds audio::drain::EndPointRead::getBufferFillSizeMicrosecond() {
DRAIN_TODO("...");
return std11::chrono::microseconds(0);
}

View File

@ -0,0 +1,67 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_END_POINT_READ_H__
#define __AUDIO_DRAIN_ALGO_END_POINT_READ_H__
#include <audio/drain/EndPoint.h>
namespace audio {
namespace drain{
class EndPointRead : public EndPoint {
protected:
/**
* @brief Constructor
*/
EndPointRead();
void init();
public:
static std11::shared_ptr<EndPointRead> create();
/**
* @brief Destructor
*/
virtual ~EndPointRead() {};
virtual void configurationChange();
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
/**
* @brief Set buffer size in chunk number
* @param[in] _nbChunk Number of chunk in the buffer
*/
virtual void setBufferSize(size_t _nbChunk);
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @param[in] _time Time in microsecond of the buffer
*/
virtual void setBufferSize(const std11::chrono::microseconds& _time);
/**
* @brief get buffer size in chunk number
* @return Number of chunk that can be written in the buffer
*/
virtual size_t getBufferSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond that can be written in the buffer
*/
virtual std11::chrono::microseconds getBufferSizeMicrosecond();
/**
* @brief Get buffer size filled in chunk number
* @return Number of chunk in the buffer (that might be read/write)
*/
virtual size_t getBufferFillSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond of the buffer (that might be read/write)
*/
virtual std11::chrono::microseconds getBufferFillSizeMicrosecond();
};
}
}
#endif

View File

@ -3,21 +3,21 @@
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include "debug.h"
#include <drain/EndPointWrite.h>
#include <audio/drain/EndPointWrite.h>
#include <audio/drain/debug.h>
#undef __class__
#define __class__ "EndPointWrite"
drain::EndPointWrite::EndPointWrite() :
audio::drain::EndPointWrite::EndPointWrite() :
m_function(nullptr),
m_bufferSizeMicroseconds(1000000) {
}
void drain::EndPointWrite::init() {
drain::EndPoint::init();
void audio::drain::EndPointWrite::init() {
audio::drain::EndPoint::init();
m_type = "EndPoint";
if ( audio::getFormatBytes(m_output.getFormat())*m_output.getMap().size() != 0
&& m_output.getFrequency() != 0) {
@ -27,14 +27,14 @@ void drain::EndPointWrite::init() {
}
}
std11::shared_ptr<drain::EndPointWrite> drain::EndPointWrite::create() {
std11::shared_ptr<drain::EndPointWrite> tmp(new drain::EndPointWrite());
std11::shared_ptr<audio::drain::EndPointWrite> audio::drain::EndPointWrite::create() {
std11::shared_ptr<audio::drain::EndPointWrite> tmp(new audio::drain::EndPointWrite());
tmp->init();
return tmp;
}
void drain::EndPointWrite::configurationChange() {
drain::EndPoint::configurationChange();
void audio::drain::EndPointWrite::configurationChange() {
audio::drain::EndPoint::configurationChange();
// update the buffer size ...
if ( audio::getFormatBytes(m_output.getFormat())*m_output.getMap().size() != 0
&& m_output.getFrequency() != 0) {
@ -52,12 +52,12 @@ void drain::EndPointWrite::configurationChange() {
}
bool drain::EndPointWrite::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
drain::AutoLogInOut tmpLog("EndPointWrite");
bool audio::drain::EndPointWrite::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
audio::drain::AutoLogInOut tmpLog("EndPointWrite");
//DRAIN_INFO(" nb Sample in buffer : " << m_buffer.size());
if (m_function != nullptr) {
// TODO : Rework this ...
@ -99,7 +99,7 @@ bool drain::EndPointWrite::process(std11::chrono::system_clock::time_point& _tim
return true;
}
void drain::EndPointWrite::write(const void* _value, size_t _nbChunk) {
void audio::drain::EndPointWrite::write(const void* _value, size_t _nbChunk) {
std11::unique_lock<std11::mutex> lock(m_mutex);
DRAIN_VERBOSE("[ASYNC] Write data : " << _nbChunk << " chunks" << " ==> " << m_output);
int32_t nbOverflow = m_buffer.write(_value, _nbChunk);
@ -108,7 +108,7 @@ void drain::EndPointWrite::write(const void* _value, size_t _nbChunk) {
}
}
void drain::EndPointWrite::setBufferSize(size_t _nbChunk) {
void audio::drain::EndPointWrite::setBufferSize(size_t _nbChunk) {
m_bufferSizeMicroseconds = std11::chrono::microseconds(0);
m_bufferSizeChunk = _nbChunk;
if ( audio::getFormatBytes(m_output.getFormat())*m_output.getMap().size() != 0
@ -119,7 +119,7 @@ void drain::EndPointWrite::setBufferSize(size_t _nbChunk) {
}
}
void drain::EndPointWrite::setBufferSize(const std11::chrono::microseconds& _time) {
void audio::drain::EndPointWrite::setBufferSize(const std11::chrono::microseconds& _time) {
m_bufferSizeMicroseconds = _time;
m_bufferSizeChunk = 0;
m_buffer.setCapacity(_time,
@ -127,24 +127,24 @@ void drain::EndPointWrite::setBufferSize(const std11::chrono::microseconds& _tim
float(m_output.getFrequency()));
}
size_t drain::EndPointWrite::getBufferSize() {
size_t audio::drain::EndPointWrite::getBufferSize() {
if (m_bufferSizeChunk != 0) {
return m_bufferSizeChunk;
}
return (int64_t(m_output.getFrequency())*m_bufferSizeMicroseconds.count())/1000000LL;
}
std11::chrono::microseconds drain::EndPointWrite::getBufferSizeMicrosecond() {
std11::chrono::microseconds audio::drain::EndPointWrite::getBufferSizeMicrosecond() {
if (m_bufferSizeMicroseconds != std11::chrono::microseconds(0) ) {
return m_bufferSizeMicroseconds;
}
return std11::chrono::microseconds(m_bufferSizeChunk*1000000LL/int64_t(m_output.getFrequency()));
}
size_t drain::EndPointWrite::getBufferFillSize() {
size_t audio::drain::EndPointWrite::getBufferFillSize() {
return m_buffer.getSize()/(audio::getFormatBytes(m_output.getFormat())*m_output.getMap().size());
}
std11::chrono::microseconds drain::EndPointWrite::getBufferFillSizeMicrosecond() {
std11::chrono::microseconds audio::drain::EndPointWrite::getBufferFillSizeMicrosecond() {
return std11::chrono::microseconds(getBufferFillSize()*1000000LL/int64_t(m_output.getFrequency()));
}

View File

@ -0,0 +1,87 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_ALGO_END_POINT_WRITE_H__
#define __AUDIO_DRAIN_ALGO_ALGO_END_POINT_WRITE_H__
#include <audio/drain/EndPoint.h>
#include <etk/functional.h>
#include <etk/mutex.h>
#include <audio/drain/CircularBuffer.h>
namespace audio {
namespace drain{
typedef std11::function<void (const std11::chrono::system_clock::time_point& _time,
size_t _nbChunk,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> playbackFunctionWrite;
class EndPointWrite : public EndPoint {
private:
audio::drain::CircularBuffer m_buffer;
playbackFunctionWrite m_function;
std11::mutex m_mutex;
protected:
/**
* @brief Constructor
*/
EndPointWrite();
void init();
public:
static std11::shared_ptr<audio::drain::EndPointWrite> create();
/**
* @brief Destructor
*/
virtual ~EndPointWrite() {};
virtual void configurationChange();
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
virtual void write(const void* _value, size_t _nbChunk);
virtual void setCallback(playbackFunctionWrite _function) {
m_function = _function;
}
protected:
std11::chrono::microseconds m_bufferSizeMicroseconds; // 0 if m_bufferSizeChunk != 0
size_t m_bufferSizeChunk; // 0 if m_bufferSizeMicroseconds != 0
public:
/**
* @brief Set buffer size in chunk number
* @param[in] _nbChunk Number of chunk in the buffer
*/
virtual void setBufferSize(size_t _nbChunk);
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @param[in] _time Time in microsecond of the buffer
*/
virtual void setBufferSize(const std11::chrono::microseconds& _time);
/**
* @brief get buffer size in chunk number
* @return Number of chunk that can be written in the buffer
*/
virtual size_t getBufferSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond that can be written in the buffer
*/
virtual std11::chrono::microseconds getBufferSizeMicrosecond();
/**
* @brief Get buffer size filled in chunk number
* @return Number of chunk in the buffer (that might be read/write)
*/
virtual size_t getBufferFillSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond of the buffer (that might be read/write)
*/
virtual std11::chrono::microseconds getBufferFillSizeMicrosecond();
};
}
}
#endif

View File

@ -4,46 +4,46 @@
* @license APACHE v2.0 (see license file)
*/
#include <drain/debug.h>
#include <drain/Equalizer.h>
#include <drain/Algo.h>
#include <audio/drain/Equalizer.h>
#include <audio/drain/Algo.h>
#include <audio/drain/debug.h>
// see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
// see http://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/
drain::Equalizer::Equalizer() {
audio::drain::Equalizer::Equalizer() {
}
void drain::Equalizer::init() {
drain::Algo::init();
drain::Algo::m_type = "Equalizer";
void audio::drain::Equalizer::init() {
audio::drain::Algo::init();
audio::drain::Algo::m_type = "Equalizer";
m_supportedFormat.push_back(audio::format_int16);
configureBiQuad();
}
std11::shared_ptr<drain::Equalizer> drain::Equalizer::create() {
std11::shared_ptr<drain::Equalizer> tmp(new drain::Equalizer());
std11::shared_ptr<audio::drain::Equalizer> audio::drain::Equalizer::create() {
std11::shared_ptr<audio::drain::Equalizer> tmp(new audio::drain::Equalizer());
tmp->init();
return tmp;
}
drain::Equalizer::~Equalizer() {
audio::drain::Equalizer::~Equalizer() {
}
void drain::Equalizer::configurationChange() {
drain::Algo::configurationChange();
void audio::drain::Equalizer::configurationChange() {
audio::drain::Algo::configurationChange();
if (m_biquads.size() != getOutputFormat().getMap().size()) {
configureBiQuad();
}
}
bool drain::Equalizer::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
bool audio::drain::Equalizer::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
_outputNbChunk = _inputNbChunk;
_output = _input;
if (_input == nullptr) {
@ -73,7 +73,7 @@ bool drain::Equalizer::process(std11::chrono::system_clock::time_point& _time,
return true;
}
bool drain::Equalizer::setParameter(const std::string& _parameter, const std::string& _value) {
bool audio::drain::Equalizer::setParameter(const std::string& _parameter, const std::string& _value) {
//DRAIN_WARNING("set : " << _parameter << " " << _value);
if (_parameter == "config") {
m_config = ejson::Object::create(_value);
@ -89,16 +89,16 @@ bool drain::Equalizer::setParameter(const std::string& _parameter, const std::st
return false;
}
std::string drain::Equalizer::getParameter(const std::string& _parameter) const {
std::string audio::drain::Equalizer::getParameter(const std::string& _parameter) const {
return "error";
}
std::string drain::Equalizer::getParameterProperty(const std::string& _parameter) const {
std::string audio::drain::Equalizer::getParameterProperty(const std::string& _parameter) const {
return "error";
}
static drain::BiQuadFloat getBiquad(const std11::shared_ptr<const ejson::Object>& _object, float _frequency) {
drain::BiQuadFloat out;
static audio::drain::BiQuadFloat getBiquad(const std11::shared_ptr<const ejson::Object>& _object, float _frequency) {
audio::drain::BiQuadFloat out;
// get type:
std::string typeString = _object->getStringValue("type", "none");
if (typeString == "direct-value") {
@ -109,7 +109,7 @@ static drain::BiQuadFloat getBiquad(const std11::shared_ptr<const ejson::Object>
double b1 = _object->getNumberValue("b1", 0.0);
out.setBiquadCoef(a0, a1, a2, b0, b1);
} else {
enum drain::filterType type;
enum audio::drain::filterType type;
if (etk::from_string(type, typeString) == false) {
DRAIN_ERROR("Can not parse equalizer type:'" << typeString << "'");
}
@ -121,7 +121,7 @@ static drain::BiQuadFloat getBiquad(const std11::shared_ptr<const ejson::Object>
return out;
}
void drain::Equalizer::configureBiQuad() {
void audio::drain::Equalizer::configureBiQuad() {
m_biquads.clear();
m_biquads.resize(getOutputFormat().getMap().size());
if (m_config == nullptr) {
@ -138,7 +138,7 @@ void drain::Equalizer::configureBiQuad() {
continue;
}
// declare biquad:
drain::BiQuadFloat biquad = getBiquad(tmpObject, getOutputFormat().getFrequency());
audio::drain::BiQuadFloat biquad = getBiquad(tmpObject, getOutputFormat().getFrequency());
// add this bequad for every Channel:
for (size_t iii=0; iii<m_biquads.size(); ++iii) {
m_biquads[iii].push_back(biquad);
@ -162,7 +162,7 @@ void drain::Equalizer::configureBiQuad() {
continue;
}
// declare biquad:
drain::BiQuadFloat biquad = getBiquad(tmpObject, getOutputFormat().getFrequency());
audio::drain::BiQuadFloat biquad = getBiquad(tmpObject, getOutputFormat().getFrequency());
// add this bequad for specific channel:
m_biquads[iii].push_back(biquad);
}
@ -170,7 +170,7 @@ void drain::Equalizer::configureBiQuad() {
return;
}
std::vector<std::pair<float,float> > drain::Equalizer::calculateTheory() {
std::vector<std::pair<float,float> > audio::drain::Equalizer::calculateTheory() {
std::vector<std::pair<float,float> > out;
for (size_t iii=0; iii<m_biquads[0].size(); ++iii) {
if (iii == 0) {

63
audio/drain/Equalizer.h Normal file
View File

@ -0,0 +1,63 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_EQUALIZER_H__
#define __AUDIO_DRAIN_ALGO_EQUALIZER_H__
#include <audio/drain/Algo.h>
#include <etk/memory.h>
#include <ejson/Object.h>
#include <audio/drain/BiQuadFloat.h>
namespace audio {
namespace drain {
class Equalizer : public Algo {
protected:
/**
* @brief Constructor
*/
Equalizer();
void init();
public:
static std11::shared_ptr<audio::drain::Equalizer> create();
/**
* @brief Destructor
*/
virtual ~Equalizer();
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
protected:
std11::shared_ptr<ejson::Object> m_config; // configuration of the equalizer.
public:
virtual bool setParameter(const std::string& _parameter, const std::string& _value);
virtual std::string getParameter(const std::string& _parameter) const;
virtual std::string getParameterProperty(const std::string& _parameter) const;
protected:
/**
* @brief repesent all the biquad to process:
* The first vector represent the number of channel to process
* The second vector represent the number of biquad to process
*/
std::vector<std::vector<BiQuadFloat> > m_biquads;
/**
* @brief Configure biquad with the user spec.
*/
void configureBiQuad();
public:
// for debug & tools only
std::vector<std::pair<float,float> > calculateTheory();
};
}
}
#endif

View File

@ -4,9 +4,9 @@
* @license APACHE v2.0 (see license file)
*/
#include "debug.h"
#include <drain/FormatUpdate.h>
#include <audio/drain/FormatUpdate.h>
#include <iostream>
#include <audio/drain/debug.h>
#undef __class__
#define __class__ "FormatUpdate"
@ -126,24 +126,24 @@ static void convert__float__to__int32(void* _input, void* _output, size_t _nbSam
}
drain::FormatUpdate::FormatUpdate() :
audio::drain::FormatUpdate::FormatUpdate() :
m_functionConvert(nullptr) {
}
void drain::FormatUpdate::init() {
drain::Algo::init();
void audio::drain::FormatUpdate::init() {
audio::drain::Algo::init();
m_type = "FormatUpdate";
}
std11::shared_ptr<drain::FormatUpdate> drain::FormatUpdate::create() {
std11::shared_ptr<drain::FormatUpdate> tmp(new drain::FormatUpdate());
std11::shared_ptr<audio::drain::FormatUpdate> audio::drain::FormatUpdate::create() {
std11::shared_ptr<audio::drain::FormatUpdate> tmp(new audio::drain::FormatUpdate());
tmp->init();
return tmp;
}
void drain::FormatUpdate::configurationChange() {
drain::Algo::configurationChange();
void audio::drain::FormatUpdate::configurationChange() {
audio::drain::Algo::configurationChange();
if (m_input.getMap() != m_output.getMap()) {
DRAIN_ERROR("can not support Map Change ...");
m_needProcess = false;
@ -243,12 +243,12 @@ void drain::FormatUpdate::configurationChange() {
}
bool drain::FormatUpdate::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
drain::AutoLogInOut tmpLog("FormatUpdate");
bool audio::drain::FormatUpdate::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
audio::drain::AutoLogInOut tmpLog("FormatUpdate");
// chack if we need to process:
if (m_needProcess == false) {
_output = _input;

View File

@ -0,0 +1,40 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_FORMAT_UPDATE_H__
#define __AUDIO_DRAIN_ALGO_FORMAT_UPDATE_H__
#include <audio/drain/Algo.h>
namespace audio {
namespace drain {
class FormatUpdate : public Algo {
protected:
/**
* @brief Constructor
*/
FormatUpdate();
void init();
public:
static std11::shared_ptr<audio::drain::FormatUpdate> create();
/**
* @brief Destructor
*/
virtual ~FormatUpdate() {};
protected:
virtual void configurationChange();
public:
virtual bool process(std11::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

View File

@ -11,7 +11,7 @@
#define __class__ "IOFormatInterface"
std::ostream& drain::operator <<(std::ostream& _os, const IOFormatInterface& _obj) {
std::ostream& audio::drain::operator <<(std::ostream& _os, const IOFormatInterface& _obj) {
_os << "{";
if (_obj.getConfigured() == false) {
_os << "Not configured";
@ -24,7 +24,7 @@ std::ostream& drain::operator <<(std::ostream& _os, const IOFormatInterface& _ob
return _os;
}
drain::IOFormatInterface::IOFormatInterface() :
audio::drain::IOFormatInterface::IOFormatInterface() :
m_configured(false),
m_format(audio::format_unknow),
m_map(),
@ -33,7 +33,7 @@ drain::IOFormatInterface::IOFormatInterface() :
m_map.push_back(audio::channel_frontRight);
}
drain::IOFormatInterface::IOFormatInterface(std::vector<audio::channel> _map, audio::format _format, float _frequency) :
audio::drain::IOFormatInterface::IOFormatInterface(std::vector<audio::channel> _map, audio::format _format, float _frequency) :
m_configured(true),
m_format(_format),
m_map(_map),
@ -41,7 +41,7 @@ drain::IOFormatInterface::IOFormatInterface(std::vector<audio::channel> _map, au
}
void drain::IOFormatInterface::set(std::vector<audio::channel> _map, audio::format _format, float _frequency) {
void audio::drain::IOFormatInterface::set(std::vector<audio::channel> _map, audio::format _format, float _frequency) {
bool hasChange = false;
if (m_map != _map) {
m_map = _map;
@ -61,19 +61,19 @@ void drain::IOFormatInterface::set(std::vector<audio::channel> _map, audio::form
}
}
void drain::IOFormatInterface::setConfigured(bool _value) {
void audio::drain::IOFormatInterface::setConfigured(bool _value) {
m_configured = _value;
}
bool drain::IOFormatInterface::getConfigured() const {
bool audio::drain::IOFormatInterface::getConfigured() const {
return m_configured;
}
audio::format drain::IOFormatInterface::getFormat() const {
audio::format audio::drain::IOFormatInterface::getFormat() const {
return m_format;
}
void drain::IOFormatInterface::setFormat(audio::format _value) {
void audio::drain::IOFormatInterface::setFormat(audio::format _value) {
if (m_format == _value) {
return;
}
@ -82,11 +82,11 @@ void drain::IOFormatInterface::setFormat(audio::format _value) {
configurationChange();
}
const std::vector<audio::channel>& drain::IOFormatInterface::getMap() const{
const std::vector<audio::channel>& audio::drain::IOFormatInterface::getMap() const{
return m_map;
}
void drain::IOFormatInterface::setMap(const std::vector<audio::channel>& _value) {
void audio::drain::IOFormatInterface::setMap(const std::vector<audio::channel>& _value) {
if (m_map == _value) {
return;
}
@ -95,11 +95,11 @@ void drain::IOFormatInterface::setMap(const std::vector<audio::channel>& _value)
configurationChange();
}
float drain::IOFormatInterface::getFrequency() const{
float audio::drain::IOFormatInterface::getFrequency() const{
return m_frequency;
}
void drain::IOFormatInterface::setFrequency(float _value) {
void audio::drain::IOFormatInterface::setFrequency(float _value) {
if (m_frequency == _value) {
return;
}
@ -108,16 +108,16 @@ void drain::IOFormatInterface::setFrequency(float _value) {
configurationChange();
}
void drain::IOFormatInterface::configurationChange() {
void audio::drain::IOFormatInterface::configurationChange() {
if (m_ioChangeFunctor != nullptr) {
m_ioChangeFunctor();
}
}
void drain::IOFormatInterface::setCallback(const std11::function<void()>& _functor) {
void audio::drain::IOFormatInterface::setCallback(const std11::function<void()>& _functor) {
m_ioChangeFunctor = _functor;
}
int32_t drain::IOFormatInterface::getChunkSize() const {
int32_t audio::drain::IOFormatInterface::getChunkSize() const {
return m_map.size() * audio::getFormatBytes(m_format);
}

View File

@ -0,0 +1,93 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_IO_FORMAT_INTERFACE_H__
#define __AUDIO_DRAIN_ALGO_IO_FORMAT_INTERFACE_H__
#include <string>
#include <vector>
#include <stdint.h>
#include <audio/format.h>
#include <audio/channel.h>
#include <etk/chrono.h>
#include <etk/functional.h>
#include <etk/memory.h>
#include "AutoLogInOut.h"
#include "debug.h"
namespace audio {
namespace drain{
class IOFormatInterface {
public:
IOFormatInterface();
IOFormatInterface(std::vector<audio::channel> _map, audio::format _format=audio::format_int16, float _frequency=48000.0f);
void set(std::vector<audio::channel> _map, audio::format _format=audio::format_int16, float _frequency=48000.0f);
protected:
bool m_configured;
public:
void setConfigured(bool _value);
bool getConfigured() const;
protected:
audio::format m_format; //!< input Algo Format
public:
/**
* @brief Get the algo format.
* @return the current Format.
*/
audio::format getFormat() const;
/**
* @brief Set the algo format.
* @param[in] _value New Format.
*/
void setFormat(audio::format _value);
protected:
std::vector<audio::channel> m_map; //!< input channel Map
public:
/**
* @brief Get the algo channel Map.
* @return the current channel Map.
*/
const std::vector<audio::channel>& getMap() const;
/**
* @brief Set the algo channel Map.
* @param[in] _value New channel Map.
*/
void setMap(const std::vector<audio::channel>& _value);
protected:
float m_frequency; //!< input Algo Format
public:
/**
* @brief Get the algo frequency.
* @return the current frequency.
*/
float getFrequency() const;
/**
* @brief Set the algo frequency.
* @param[in] _value New frequency.
*/
void setFrequency(float _value);
public:
/**
* @brief Get the Chunk size in byte.
* @return the number of byte used by chunk.
*/
int32_t getChunkSize() const;
protected:
std11::function<void()> m_ioChangeFunctor; //!< function pointer on the upper class
void configurationChange();
public:
/**
* @brief Set the callback function to be notify when the arameter change.
* @param[in] _functor Function to call.
*/
void setCallback(const std11::function<void()>& _functor);
};
std::ostream& operator <<(std::ostream& _os, const audio::drain::IOFormatInterface& _obj);
}
}
#endif

View File

@ -4,34 +4,33 @@
* @license APACHE v2.0 (see license file)
*/
#include "debug.h"
#include <string>
#include <vector>
#include <stdint.h>
#include <audio/format.h>
#include <audio/channel.h>
#include <drain/Process.h>
#include <drain/ChannelReorder.h>
#include <drain/FormatUpdate.h>
#include <drain/Resampler.h>
#include <audio/drain/Process.h>
#include <audio/drain/ChannelReorder.h>
#include <audio/drain/FormatUpdate.h>
#include <audio/drain/Resampler.h>
#include <audio/drain/debug.h>
#undef __class__
#define __class__ "Process"
drain::Process::Process() :
audio::drain::Process::Process() :
m_isConfigured(false) {
m_data.clear();
}
drain::Process::~Process() {
audio::drain::Process::~Process() {
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
m_listAlgo[iii].reset();
}
}
bool drain::Process::push(std11::chrono::system_clock::time_point& _time,
void* _data,
size_t _nbChunk) {
bool audio::drain::Process::push(std11::chrono::system_clock::time_point& _time,
void* _data,
size_t _nbChunk) {
void* out = nullptr;
size_t nbChunkOut;
DRAIN_VERBOSE(" Process push");
@ -39,10 +38,10 @@ bool drain::Process::push(std11::chrono::system_clock::time_point& _time,
return true;
}
bool drain::Process::pull(std11::chrono::system_clock::time_point& _time,
void* _data,
size_t _nbChunk,
size_t _chunkSize) {
bool audio::drain::Process::pull(std11::chrono::system_clock::time_point& _time,
void* _data,
size_t _nbChunk,
size_t _chunkSize) {
while(m_data.size()<_nbChunk*_chunkSize) {
void* in = NULL;
size_t nbChunkIn = _nbChunk - m_data.size()/_chunkSize;
@ -82,11 +81,11 @@ bool drain::Process::pull(std11::chrono::system_clock::time_point& _time,
}
bool drain::Process::process(std11::chrono::system_clock::time_point& _time,
void* _inData,
size_t _inNbChunk,
void*& _outData,
size_t& _outNbChunk) {
bool audio::drain::Process::process(std11::chrono::system_clock::time_point& _time,
void* _inData,
size_t _inNbChunk,
void*& _outData,
size_t& _outNbChunk) {
updateInterAlgo();
if (m_listAlgo.size() == 0) {
_outData = _inData;
@ -105,15 +104,15 @@ bool drain::Process::process(std11::chrono::system_clock::time_point& _time,
return true;
}
void drain::Process::pushBack(const std11::shared_ptr<drain::Algo>& _algo) {
void audio::drain::Process::pushBack(const std11::shared_ptr<audio::drain::Algo>& _algo) {
removeAlgoDynamic();
_algo->setStatusFunction(std11::bind(&drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
_algo->setStatusFunction(std11::bind(&audio::drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
m_listAlgo.push_back(_algo);
}
void drain::Process::pushFront(const std11::shared_ptr<drain::Algo>& _algo) {
void audio::drain::Process::pushFront(const std11::shared_ptr<audio::drain::Algo>& _algo) {
removeAlgoDynamic();
_algo->setStatusFunction(std11::bind(&drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
_algo->setStatusFunction(std11::bind(&audio::drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
m_listAlgo.insert(m_listAlgo.begin(), _algo);
}
@ -139,7 +138,7 @@ template<typename T> std::vector<T> getUnion(const std::vector<T>& _out, const s
}
void drain::Process::displayAlgo() {
void audio::drain::Process::displayAlgo() {
DRAIN_DEBUG(" Input : " << m_inputConfig);
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
DRAIN_DEBUG(" [" << m_listAlgo[iii]->getType() << "] '" << m_listAlgo[iii]->getName() << "'");
@ -163,7 +162,7 @@ void drain::Process::displayAlgo() {
DRAIN_DEBUG(" Output : " << m_outputConfig);
}
void drain::Process::updateAlgo(size_t _position) {
void audio::drain::Process::updateAlgo(size_t _position) {
DRAIN_VERBOSE(" id = " << _position);
if ( ( _position == 0
|| ( _position > 0
@ -243,8 +242,8 @@ void drain::Process::updateAlgo(size_t _position) {
return;
}
// create mapping to transform:
drain::IOFormatInterface out;
drain::IOFormatInterface in;
audio::drain::IOFormatInterface out;
audio::drain::IOFormatInterface in;
if (freq.size() > 0) {
out.setFrequency(freq[0]);
in.setFrequency(freq[0]);
@ -338,23 +337,23 @@ void drain::Process::updateAlgo(size_t _position) {
if ( out.getFormat() != audio::format_int16
/* && out.getFormat() != format_float */) {
// need add a format Updater
std11::shared_ptr<drain::FormatUpdate> algo = drain::FormatUpdate::create();
std11::shared_ptr<audio::drain::FormatUpdate> algo = audio::drain::FormatUpdate::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFormat(audio::format_int16);
algo->setOutputFormat(out);
algo->setStatusFunction(std11::bind(&drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
algo->setStatusFunction(std11::bind(&audio::drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_VERBOSE("convert " << out.getFormat() << " -> " << in.getFormat());
_position++;
}
// need add a resampler
std11::shared_ptr<drain::Resampler> algo = drain::Resampler::create();
std11::shared_ptr<audio::drain::Resampler> algo = audio::drain::Resampler::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFrequency(in.getFrequency());
algo->setOutputFormat(out);
algo->setStatusFunction(std11::bind(&drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
algo->setStatusFunction(std11::bind(&audio::drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_VERBOSE("convert " << out.getFrequency() << " -> " << in.getFrequency());
out.setFrequency(in.getFrequency());
@ -362,24 +361,24 @@ void drain::Process::updateAlgo(size_t _position) {
}
if (out.getMap() != in.getMap()) {
// need add a channel Reorder
std11::shared_ptr<drain::ChannelReorder> algo = drain::ChannelReorder::create();
std11::shared_ptr<audio::drain::ChannelReorder> algo = audio::drain::ChannelReorder::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setMap(in.getMap());
algo->setOutputFormat(out);
algo->setStatusFunction(std11::bind(&drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
algo->setStatusFunction(std11::bind(&audio::drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_VERBOSE("convert " << out.getMap() << " -> " << in.getMap());
_position++;
}
if (out.getFormat() != in.getFormat()) {
// need add a format Updater
std11::shared_ptr<drain::FormatUpdate> algo = drain::FormatUpdate::create();
std11::shared_ptr<audio::drain::FormatUpdate> algo = audio::drain::FormatUpdate::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFormat(in.getFormat());
algo->setOutputFormat(out);
algo->setStatusFunction(std11::bind(&drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
algo->setStatusFunction(std11::bind(&audio::drain::Process::generateStatus, this, std11::placeholders::_1, std11::placeholders::_2));
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_VERBOSE("convert " << out.getFormat() << " -> " << in.getFormat());
_position++;
@ -396,7 +395,7 @@ void drain::Process::updateAlgo(size_t _position) {
}
}
void drain::Process::updateInterAlgo() {
void audio::drain::Process::updateInterAlgo() {
if (m_isConfigured == true) {
// cahin is already configured
return ;
@ -417,7 +416,7 @@ void drain::Process::updateInterAlgo() {
//exit(-1);
}
void drain::Process::removeAlgoDynamic() {
void audio::drain::Process::removeAlgoDynamic() {
if (m_isConfigured == true) {
// chain is already unconfigured.
return;
@ -426,10 +425,10 @@ void drain::Process::removeAlgoDynamic() {
}
bool drain::Process::processIn(void* _inData,
size_t _inNbChunk,
void* _outData,
size_t _outNbChunk){
bool audio::drain::Process::processIn(void* _inData,
size_t _inNbChunk,
void* _outData,
size_t _outNbChunk){
void* outData = nullptr;
size_t outSize = 0;
bool error = process(_inData, _inNbChunk, outData, outSize);
@ -460,7 +459,7 @@ static void link(etk::FSNode& _node, const std::string& _first, const std::strin
}
}
void drain::Process::generateDot(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph) {
void audio::drain::Process::generateDot(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph) {
_node << " subgraph clusterNode_" << _basicID << "_process {\n";
_node << " label=\"Drain::Process" << (_reserseGraph?"_R":"_N") << "\";\n";
_node << " node [shape=ellipse];\n";
@ -520,7 +519,7 @@ void drain::Process::generateDot(etk::FSNode& _node, int32_t _offset, int32_t _b
_node << " }\n";
}
void drain::Process::generateDotProcess(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph) {
void audio::drain::Process::generateDotProcess(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph) {
_node << " subgraph clusterNode_" << _basicID << "_process {\n";
_node << " label=\"Drain::Process" << (_reserseGraph?"_R":"_N") << "\";\n";
_node << " node [shape=ellipse];\n";
@ -581,12 +580,12 @@ void drain::Process::generateDotProcess(etk::FSNode& _node, int32_t _offset, int
}
void drain::Process::generateStatus(const std::string& _origin, const std::string& _status) {
void audio::drain::Process::generateStatus(const std::string& _origin, const std::string& _status) {
if (m_statusFunction != nullptr) {
m_statusFunction(_origin, _status);
}
}
void drain::Process::setStatusFunction(statusFunction _newFunction) {
void audio::drain::Process::setStatusFunction(statusFunction _newFunction) {
m_statusFunction = _newFunction;
}

192
audio/drain/Process.h Normal file
View File

@ -0,0 +1,192 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_PROCESS_H__
#define __AUDIO_DRAIN_ALGO_PROCESS_H__
#include <string>
#include <vector>
#include <stdint.h>
#include <audio/format.h>
#include <audio/channel.h>
#include <audio/drain/Algo.h>
#include <etk/chrono.h>
#include <etk/memory.h>
#include <etk/os/FSNode.h>
namespace audio {
namespace drain{
typedef std11::function<void (const std::string& _origin, const std::string& _status)> statusFunction;
class Process {
protected:
std::vector<int8_t> m_data; //!< temporary overlap output buffer (change size of the output data)
public:
Process();
virtual ~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(std11::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)).
* @param[out] _chunkSize size of a single chunk. TODO : Not needed ... Remove it ...
* @return true The procress is done corectly.
* @return false An error occured.
*/
bool pull(std11::chrono::system_clock::time_point& _time,
void* _data,
size_t _nbChunk,
size_t _chunkSize);
/**
* @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(std11::chrono::system_clock::time_point& _time,
void* _inData,
size_t _inNbChunk,
void*& _outData,
size_t& _outNbChunk);
bool process(void* _inData,
size_t _inNbChunk,
void*& _outData,
size_t& _outNbChunk) {
std11::chrono::system_clock::time_point time;
return process(time, _inData, _inNbChunk, _outData, _outNbChunk);
}
bool processIn(void* _inData,
size_t _inNbChunk,
void* _outData,
size_t _outNbChunk);
protected:
IOFormatInterface m_inputConfig;
public:
const IOFormatInterface& getInputConfig() const {
return m_inputConfig;
}
void setInputConfig(const IOFormatInterface& _interface) {
m_inputConfig = _interface;
}
protected:
IOFormatInterface m_outputConfig;
public:
const IOFormatInterface& getOutputConfig() const {
return m_outputConfig;
}
void setOutputConfig(const IOFormatInterface& _interface) {
m_outputConfig = _interface;
}
protected:
std::vector<std11::shared_ptr<drain::Algo> > m_listAlgo;
public:
void pushBack(const std11::shared_ptr<drain::Algo>& _algo);
void pushFront(const std11::shared_ptr<drain::Algo>& _algo);
void clear() {
m_isConfigured = false;
m_listAlgo.clear();
}
size_t size() {
return m_listAlgo.size();
}
std::vector<std11::shared_ptr<drain::Algo> >::iterator begin() {
return m_listAlgo.begin();
}
std::vector<std11::shared_ptr<drain::Algo> >::iterator end() {
return m_listAlgo.end();
}
std11::shared_ptr<drain::Algo> operator[](int32_t _id) {
return m_listAlgo[_id];
}
template<typename T> std11::shared_ptr<T> get(const std::string& _name) {
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
if (m_listAlgo[iii] == nullptr) {
continue;
}
if (m_listAlgo[iii]->getName() == _name) {
return std11::dynamic_pointer_cast<T>(m_listAlgo[iii]);
}
}
return std11::shared_ptr<T>();
}
template<typename T> std11::shared_ptr<const T> get(const std::string& _name) const {
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
if (m_listAlgo[iii] == nullptr) {
continue;
}
if (m_listAlgo[iii]->getName() == _name) {
return std11::dynamic_pointer_cast<T>(m_listAlgo[iii]);
}
}
return std11::shared_ptr<const T>();
}
template<typename T> std11::shared_ptr<T> get(int32_t _id) {
return std11::dynamic_pointer_cast<T>(m_listAlgo[_id]);
}
template<typename T> void removeIfFirst() {
if (m_listAlgo.size() > 0) {
std11::shared_ptr<T> algoEP = get<T>(0);
if (algoEP != nullptr) {
m_listAlgo.erase(m_listAlgo.begin());
}
}
}
template<typename T> void removeIfLast() {
if (m_listAlgo.size() > 0) {
std11::shared_ptr<T> algoEP = get<T>(m_listAlgo.size()-1);
if (algoEP != nullptr) {
m_listAlgo.erase(m_listAlgo.begin()+m_listAlgo.size()-1);
}
}
}
template<typename T> bool hasType() {
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
std11::shared_ptr<T> tmp = std11::dynamic_pointer_cast<T>(m_listAlgo[iii]);
if (tmp != nullptr) {
return true;
}
}
return false;
}
private:
statusFunction m_statusFunction;
public:
void generateStatus(const std::string& _origin, const std::string& _status);
void setStatusFunction(statusFunction _newFunction);
private:
bool m_isConfigured;
public:
void updateInterAlgo();
void removeAlgoDynamic();
private:
void displayAlgo();
void updateAlgo(size_t _position);
public:
void generateDot(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph);
// TODO : Remove this one when we find a good way to do it ...
void generateDotProcess(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph);
};
}
}
#endif

View File

@ -4,14 +4,14 @@
* @license APACHE v2.0 (see license file)
*/
#include "debug.h"
#include <drain/Resampler.h>
#include <audio/drain/Resampler.h>
#include <iostream>
#include <audio/drain/debug.h>
#undef __class__
#define __class__ "Resampler"
drain::Resampler::Resampler() :
audio::drain::Resampler::Resampler() :
#ifdef HAVE_SPEEX_DSP_RESAMPLE
m_speexResampler(nullptr),
#endif
@ -20,20 +20,20 @@ drain::Resampler::Resampler() :
}
void drain::Resampler::init() {
drain::Algo::init();
void audio::drain::Resampler::init() {
audio::drain::Algo::init();
m_type = "Resampler";
m_supportedFormat.push_back(audio::format_int16);
m_residualTimeInResampler = std11::chrono::nanoseconds(0);
}
std11::shared_ptr<drain::Resampler> drain::Resampler::create() {
std11::shared_ptr<drain::Resampler> tmp(new drain::Resampler());
std11::shared_ptr<audio::drain::Resampler> audio::drain::Resampler::create() {
std11::shared_ptr<audio::drain::Resampler> tmp(new audio::drain::Resampler());
tmp->init();
return tmp;
}
drain::Resampler::~Resampler() {
audio::drain::Resampler::~Resampler() {
#ifdef HAVE_SPEEX_DSP_RESAMPLE
if (m_speexResampler != nullptr) {
speex_resampler_destroy(m_speexResampler);
@ -42,8 +42,8 @@ drain::Resampler::~Resampler() {
#endif
}
void drain::Resampler::configurationChange() {
drain::Algo::configurationChange();
void audio::drain::Resampler::configurationChange() {
audio::drain::Algo::configurationChange();
if (m_input.getFormat() != m_output.getFormat()) {
DRAIN_ERROR("can not support Format Change ...");
m_needProcess = false;
@ -85,11 +85,11 @@ void drain::Resampler::configurationChange() {
#endif
}
bool drain::Resampler::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
bool audio::drain::Resampler::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
drain::AutoLogInOut tmpLog("Resampler");
_outputNbChunk = 2048;
// chack if we need to process:

53
audio/drain/Resampler.h Normal file
View File

@ -0,0 +1,53 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_RESAMPLER_H__
#define __AUDIO_DRAIN_ALGO_RESAMPLER_H__
#include <audio/drain/Algo.h>
#ifdef HAVE_SPEEX_DSP_RESAMPLE
#include <speex/speex_resampler.h>
#endif
#include <etk/memory.h>
namespace audio {
namespace drain {
// TODO: Manage change timestamp when pull mode
// TODO: drain ...
class Resampler : public audio::drain::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
protected:
/**
* @brief Constructor
*/
Resampler();
void init();
public:
static std11::shared_ptr<audio::drain::Resampler> create();
/**
* @brief Destructor
*/
virtual ~Resampler();
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
private:
std11::chrono::nanoseconds m_residualTimeInResampler; //!< the time of data locked in the resampler ...
};
}
}
#endif

View File

@ -4,34 +4,34 @@
* @license APACHE v2.0 (see license file)
*/
#include "debug.h"
#include <drain/Volume.h>
#include <audio/drain/Volume.h>
#include <iostream>
#include <math.h>
#include <audio/drain/debug.h>
#undef __class__
#define __class__ "Volume"
drain::Volume::Volume() :
audio::drain::Volume::Volume() :
m_volumeAppli(1.0f),
m_functionConvert(nullptr) {
}
void drain::Volume::init() {
drain::Algo::init();
void audio::drain::Volume::init() {
audio::drain::Algo::init();
m_type = "Volume";
m_supportedFormat.push_back(audio::format_int16);
m_supportedFormat.push_back(audio::format_int16_on_int32);
}
std11::shared_ptr<drain::Volume> drain::Volume::create() {
std11::shared_ptr<drain::Volume> tmp(new drain::Volume());
std11::shared_ptr<audio::drain::Volume> audio::drain::Volume::create() {
std11::shared_ptr<audio::drain::Volume> tmp(new audio::drain::Volume());
tmp->init();
return tmp;
}
drain::Volume::~Volume() {
audio::drain::Volume::~Volume() {
}
@ -87,8 +87,8 @@ static void convert__float__to__float(void* _input, void* _output, size_t _nbSam
}
}
void drain::Volume::configurationChange() {
drain::Algo::configurationChange();
void audio::drain::Volume::configurationChange() {
audio::drain::Algo::configurationChange();
switch (m_input.getFormat()) {
default:
case audio::format_int16:
@ -152,7 +152,7 @@ void drain::Volume::configurationChange() {
volumeChange();
}
void drain::Volume::volumeChange() {
void audio::drain::Volume::volumeChange() {
//m_volumeAppli = 20 * log(m_volumedB);
float volumedB = 0.0f;
for (size_t iii=0; iii<m_volumeList.size(); ++iii) {
@ -273,7 +273,7 @@ void drain::Volume::volumeChange() {
}
std::vector<audio::format> drain::Volume::getFormatSupportedInput() {
std::vector<audio::format> audio::drain::Volume::getFormatSupportedInput() {
std::vector<audio::format> tmp;
if (m_output.getFormat() == audio::format_float) {
tmp.push_back(audio::format_float);
@ -288,7 +288,7 @@ std::vector<audio::format> drain::Volume::getFormatSupportedInput() {
return tmp;
};
std::vector<audio::format> drain::Volume::getFormatSupportedOutput() {
std::vector<audio::format> audio::drain::Volume::getFormatSupportedOutput() {
std::vector<audio::format> tmp;
if (m_input.getFormat() == audio::format_float) {
tmp.push_back(audio::format_float);
@ -304,12 +304,12 @@ std::vector<audio::format> drain::Volume::getFormatSupportedOutput() {
};
bool drain::Volume::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
drain::AutoLogInOut tmpLog("Volume");
bool audio::drain::Volume::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
audio::drain::AutoLogInOut tmpLog("Volume");
// chack if we need to process:
if (m_needProcess == false) {
_output = _input;
@ -334,7 +334,7 @@ bool drain::Volume::process(std11::chrono::system_clock::time_point& _time,
return true;
}
void drain::Volume::addVolumeStage(const std11::shared_ptr<VolumeElement>& _volume) {
void audio::drain::Volume::addVolumeStage(const std11::shared_ptr<audio::drain::VolumeElement>& _volume) {
if (_volume == nullptr) {
return;
}
@ -354,7 +354,7 @@ void drain::Volume::addVolumeStage(const std11::shared_ptr<VolumeElement>& _volu
volumeChange();
}
bool drain::Volume::setParameter(const std::string& _parameter, const std::string& _value) {
bool audio::drain::Volume::setParameter(const std::string& _parameter, const std::string& _value) {
if (_parameter == "FLOW") {
// set Volume ...
for (size_t iii=0; iii<m_volumeList.size(); ++iii) {
@ -382,7 +382,7 @@ bool drain::Volume::setParameter(const std::string& _parameter, const std::strin
return false;
}
std::string drain::Volume::getParameter(const std::string& _parameter) const {
std::string audio::drain::Volume::getParameter(const std::string& _parameter) const {
if (_parameter == "FLOW") {
// set Volume ...
for (size_t iii=0; iii<m_volumeList.size(); ++iii) {
@ -398,7 +398,7 @@ std::string drain::Volume::getParameter(const std::string& _parameter) const {
return "[ERROR]";
}
std::string drain::Volume::getParameterProperty(const std::string& _parameter) const {
std::string audio::drain::Volume::getParameterProperty(const std::string& _parameter) const {
if (_parameter == "FLOW") {
// set Volume ...
for (size_t iii=0; iii<m_volumeList.size(); ++iii) {

91
audio/drain/Volume.h Normal file
View File

@ -0,0 +1,91 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_VOLUME_H__
#define __AUDIO_DRAIN_ALGO_VOLUME_H__
#include <audio/drain/Algo.h>
#ifdef HAVE_SPEEX_DSP_RESAMPLE
#include <speex/speex_resampler.h>
#endif
#include <etk/memory.h>
namespace audio {
namespace drain {
// data structure.
class VolumeElement {
public:
VolumeElement(const std::string& _name="ERROR-VOLUME-NAME", float _volumedB=0.0f) :
m_name(_name),
m_volumedB(_volumedB) {
}
private:
std::string m_name;
public:
std::string getName() const {
return m_name;
}
private:
float m_volumedB;
public:
float getVolume() const {
return m_volumedB;
}
void setVolume(float _volumedB) {
m_volumedB = _volumedB;
}
};
// TODO: Optimisation
// TODO: Zero crossing
// TODO: Continuous update volume
// TODO: Manage multiple volume
// TODO: Manage set volume
class Volume : public audio::drain::Algo {
private:
std::vector<std11::shared_ptr<drain::VolumeElement> > m_volumeList;
// for float input :
float m_volumeAppli;
// for integer input :
int32_t m_volumeDecalage; // Volume to apply is simple as : X * m_coef >> m_coef
int32_t m_volumeCoef;
// convertion function:
void (*m_functionConvert)(void* _input, void* _output, size_t _nbSample, int32_t _volumeCoef, int32_t _volumeDecalage, float _volumeAppli);
protected:
/**
* @brief Constructor
*/
Volume();
void init();
public:
static std11::shared_ptr<Volume> create();
/**
* @brief Destructor
*/
virtual ~Volume();
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
public:
virtual std::vector<audio::format> getFormatSupportedInput();
virtual std::vector<audio::format> getFormatSupportedOutput();
public:
virtual void addVolumeStage(const std11::shared_ptr<drain::VolumeElement>& _volume);
virtual bool setParameter(const std::string& _parameter, const std::string& _value);
virtual std::string getParameter(const std::string& _parameter) const;
virtual std::string getParameterProperty(const std::string& _parameter) const;
public:
void volumeChange();
};
}
}
#endif

45
audio/drain/airtalgo.h Normal file
View File

@ -0,0 +1,45 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __AUDIO_DRAIN_ALGO_CORE_H__
#define __AUDIO_DRAIN_ALGO_CORE_H__
#include <string>
#include <audio/format.h>
#include <audio/drain/channel.h>
#include <etk/chrono.h>
namespace audio {
namespace drain {
/**
* @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
*/
drain::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<drain::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

View File

@ -4,10 +4,10 @@
* @license APACHE v2.0 (see license file)
*/
#include <drain/debug.h>
#include <audio/drain/debug.h>
int32_t drain::getLogId() {
static int32_t g_val = etk::log::registerInstance("drain");
int32_t audio::drain::getLogId() {
static int32_t g_val = etk::log::registerInstance("audio-drain");
return g_val;
}

View File

@ -4,15 +4,17 @@
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_DEBUG_H__
#define __DRAIN_DEBUG_H__
#ifndef __AUDIO_DRAIN_DEBUG_H__
#define __AUDIO_DRAIN_DEBUG_H__
#include <etk/log.h>
namespace drain {
int32_t getLogId();
};
#define DRAIN_BASE(info,data) TK_LOG_BASE(drain::getLogId(),info,data)
namespace audio {
namespace drain {
int32_t getLogId();
}
}
#define DRAIN_BASE(info,data) TK_LOG_BASE(audio::drain::getLogId(),info,data)
#define DRAIN_CRITICAL(data) DRAIN_BASE(1, data)
#define DRAIN_ERROR(data) DRAIN_BASE(2, data)

View File

@ -6,8 +6,8 @@
* @license BSD 3 clauses (see license file)
*/
#ifdef __DRAINO_DEBUG_H__
#undef __DRAINO_DEBUG_H__
#ifdef __AUDIO_DRAIN_DEBUG_H__
#undef __AUDIO_DRAIN_DEBUG_H__
#undef DRAIN_BASE
#undef DRAIN_CRITICAL

View File

@ -1,214 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_CORE_ALGO_H__
#define __DRAIN_ALGO_CORE_ALGO_H__
#include <string>
#include <vector>
#include <stdint.h>
#include <audio/format.h>
#include <audio/channel.h>
#include <etk/chrono.h>
#include <etk/functional.h>
#include <etk/memory.h>
#include "AutoLogInOut.h"
#include "IOFormatInterface.h"
#include "debug.h"
namespace drain{
typedef std11::function<void (const std::string& _origin, const std::string& _status)> algoStatusFunction;
class Algo : public std11::enable_shared_from_this<Algo> {
private:
std::string m_name;
public:
const std::string& getName() const {
return m_name;
}
void setName(const std::string& _name) {
m_name = _name;
}
protected:
std::string m_type;
public:
const std::string& getType() const {
return m_type;
}
void setType(const std::string& _type) {
m_type = _type;
}
private:
bool m_temporary;
public:
void setTemporary() {
m_temporary = true;
}
bool getTemporary() const {
return m_temporary;
}
private:
algoStatusFunction m_statusFunction;
public:
void setStatusFunction(algoStatusFunction _newFunction);
protected:
void generateStatus(const std::string& _status);
protected:
std::vector<int8_t> m_outputData;
int8_t m_formatSize; //!< sample size
/**
* @brief Constructor
*/
Algo();
void init();
public:
/**
* @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.set(_format.getMap(), _format.getFormat(), _format.getFrequency());
}
const IOFormatInterface& getInputFormat() const {
return m_input;
}
IOFormatInterface& getInputFormat() {
return m_input;
}
protected:
IOFormatInterface m_output; //!< Output audio property
public:
void setOutputFormat(const IOFormatInterface& _format) {
m_output.set(_format.getMap(), _format.getFormat(), _format.getFrequency());
}
const IOFormatInterface& getOutputFormat() const {
return m_output;
}
IOFormatInterface& getOutputFormat() {
return m_output;
}
private:
void configurationChangeLocal() {
if ( m_output.getConfigured() == true
&& m_output.getConfigured() == true) {
configurationChange();
}
}
public:
/**
* @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(std11::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
*/
// TODO : Manage the change of the timestamp ...
virtual size_t needInputData(size_t _output);
protected: // note when nothing ==> support all type
std::vector<audio::format> m_supportedFormat;
public:
virtual std::vector<audio::format> getFormatSupportedInput() {
if (m_output.getConfigured() == true) {
std::vector<audio::format> out;
out.push_back(m_output.getFormat());
return out;
}
return m_supportedFormat;
};
virtual std::vector<audio::format> getFormatSupportedOutput() {
if (m_input.getConfigured() == true) {
std::vector<audio::format> out;
out.push_back(m_input.getFormat());
return out;
}
return m_supportedFormat;
};
protected: // note when nothing ==> support all type
std::vector<std::vector<audio::channel> > m_supportedMap;
public:
virtual std::vector<std::vector<audio::channel> > getMapSupportedInput() {
if (m_output.getConfigured() == true) {
std::vector<std::vector<audio::channel> > out;
out.push_back(m_output.getMap());
return out;
}
return m_supportedMap;
};
virtual std::vector<std::vector<audio::channel> > getMapSupportedOutput() {
if (m_input.getConfigured() == true) {
std::vector<std::vector<audio::channel> > out;
out.push_back(m_input.getMap());
return out;
}
return m_supportedMap;
};
protected: // note when nothing ==> support all type
std::vector<float> m_supportedFrequency;
public:
virtual std::vector<float> getFrequencySupportedInput() {
if (m_output.getConfigured() == true) {
std::vector<float> out;
out.push_back(m_output.getFrequency());
return out;
}
return m_supportedFrequency;
};
virtual std::vector<float> getFrequencySupportedOutput() {
if (m_input.getConfigured() == true) {
std::vector<float> out;
out.push_back(m_input.getFrequency());
return out;
}
return m_supportedFrequency;
};
public:
/**
* @brief Set a parameter in the stream flow
* @param[in] _parameter Parameter name.
* @param[in] _value Value to set.
* @return true set done
* @return false An error occured
*/
virtual bool setParameter(const std::string& _parameter, const std::string& _value) { return false; }
/**
* @brief Get a parameter value
* @param[in] _parameter Parameter name.
* @return The requested value.
*/
virtual std::string getParameter(const std::string& _parameter) const { return "[ERROR]"; }
/**
* @brief Get a parameter value
* @param[in] _parameter Parameter name.
* @return The requested value.
*/
virtual std::string getParameterProperty(const std::string& _parameter) const { return "[ERROR]"; };
};
};
#include "debugRemove.h"
#endif

View File

@ -1,27 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_AUTO_LOG_IN_OUT_H__
#define __DRAIN_ALGO_AUTO_LOG_IN_OUT_H__
#include <string>
#include "debug.h"
namespace drain{
class AutoLogInOut {
private:
std::string m_value;
public:
AutoLogInOut(const std::string& _value);
~AutoLogInOut();
};
}
#include "debugRemove.h"
#endif

View File

@ -1,95 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_BIQUAD_FLOAT_H__
#define __DRAIN_ALGO_BIQUAD_FLOAT_H__
#include <drain/Algo.h>
#include <etk/memory.h>
namespace drain {
enum filterType {
filterType_none, //!< no filter (pass threw...)
filterType_lowPass, //!< low pass filter
filterType_highPass, //!< High pass filter
filterType_bandPass, //!< band pass filter
filterType_notch, //!< Notch Filter
filterType_peak, //!< Peaking band EQ filter
filterType_lowShelf, //!< Low shelf filter
filterType_highShelf, //!< High shelf filter
};
class BiQuadFloat {
public:
BiQuadFloat();
protected:
float m_x[2]; //!< X history
float m_y[2]; //!< Y histiry
float m_a[3]; //!< A bi-Quad coef
float m_b[2]; //!< B bi-Quad coef
public:
/**
* @brief Set the bi-quad value and type
* @param[in] _type Type of biquad.
* @param[in] _frequencyCut Cut Frequency. [0..sampleRate/2]
* @param[in] _qualityFactor Q factor of quality (good value of 0.707 ==> permit to not ower gain) limit [0.01 .. 10]
* @param[in] _gain Gain to apply (for notch, peak, lowShelf and highShelf) limit : -30, +30
* @param[in] _sampleRate Sample rate of the signal
*/
void setBiquad(enum drain::filterType _type, double _frequencyCut, double _qualityFactor, double _gain, float _sampleRate);
/**
* @brief Set direct Coefficients
*/
void setBiquadCoef(float _a0, float _a1, float _a2, float _b0, float _b1);
/**
* @brief Get direct Coefficients
*/
void getBiquadCoef(float& _a0, float& _a1, float& _a2, float& _b0, float& _b1);
/**
* @brief Get direct Coefficients
*/
std::vector<float> getCoef();
/**
* @brief Reset bequad filter (only history not value).
*/
void reset();
protected:
/**
* @brief process single sample in float.
* @param[in] _sample Sample to process
* @return updataed value
*/
float processFloat(float _sample);
public:
/**
* @brief Porcess function.
* param[in] _input Pointer on the input data.
* param[in,out] _output Poirter on the output data (can be the same as input (inplace availlable).
* param[in] _nbChunk Number of qample to process.
* param[in] _inputOffset Offset to add when read input data.
* param[in] _outputOffset Offset to add when write output data.
*/
void processFloat(float* _input,
float* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset);
//! @previous
void processInt16(int16_t* _input,
int16_t* _output,
size_t _nbChunk,
int32_t _inputOffset,
int32_t _outputOffset);
/**
* @brief calculate respond of the filter:
* @param[in] _sampleRate input qample rate
* @retrun list of frequency/power in dB
*/
std::vector<std::pair<float,float> > calculateTheory(double _sampleRate);
};
}
#endif

View File

@ -1,37 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_CHANNEL_REORDER_H__
#define __DRAIN_ALGO_CHANNEL_REORDER_H__
#include <drain/Algo.h>
namespace drain{
class ChannelReorder : public Algo {
protected:
/**
* @brief Constructor
*/
ChannelReorder();
void init();
public:
static std11::shared_ptr<ChannelReorder> create();
/**
* @brief Destructor
*/
virtual ~ChannelReorder() {};
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
};
};
#endif

View File

@ -1,143 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_CIRCULAR_BUFFER_H__
#define __DRAIN_CIRCULAR_BUFFER_H__
#include <etk/types.h>
#include <vector>
#include <etk/chrono.h>
namespace drain {
/**
* For these functions we have 4 solutions :
* - Free Buffer
* ----------------------------------------------------------
* m_data | | |
* ----------------------------------------------------------
* m_write
* m_read
* - Full Buffer
* ----------------------------------------------------------
* m_data |****************************|***************************|
* ----------------------------------------------------------
* m_write
* m_read
* - Buffer in used
* ----------------------------------------------------------
* m_data | |********************| |
* ----------------------------------------------------------
* m_read m_write
* - Buffer out used
* ----------------------------------------------------------
* m_data |****************| |******************|
* ----------------------------------------------------------
* m_read m_write
*/
class CircularBuffer {
private:
std::vector<uint8_t> m_data; //!< data pointer
void* m_write; //!< write pointer
void* m_read; //!< read pointer
std11::chrono::system_clock::time_point m_timeRead; //!< current read time
uint32_t m_frequency;
// TODO : Remove the m_size ==> this is a bad element to be mutex-less
size_t m_size; //!< number of chunk availlable in this buffer
size_t m_capacity; //!< number of chunk available in this Buffer
size_t m_sizeChunk; //!< Size of one chunk (in byte)
public:
CircularBuffer();
~CircularBuffer();
/**
* @brief copy contructor.
* @param[in] _obj Circular buffer object
*/
CircularBuffer(const drain::CircularBuffer& _obj);
/**
* @brief copy operator.
* @param[in] _obj Circular buffer object
*/
CircularBuffer& operator=(const drain::CircularBuffer& _obj);
/**
* @brief set the capacity of the circular buffer.
* @param[in] _capacity Number of chunk in the buffer.
* @param[in] _chunkSize Size of one chunk.
* @param[in] _frequency Frequency of the buffer
*/
void setCapacity(size_t _capacity, size_t _chunkSize, uint32_t _frequency);
/**
* @brief set the capacity of the circular buffer.
* @param[in] _capacity time in millisecond stored in the buffer.
* @param[in] _chunkSize Size of one chunk.
* @param[in] _frequency Frequency of the buffer
*/
void setCapacity(std11::chrono::milliseconds _capacity, size_t _chunkSize, uint32_t _frequency);
void setCapacity(std11::chrono::microseconds _capacity, size_t _chunkSize, uint32_t _frequency) {
setCapacity(std11::chrono::milliseconds(_capacity.count()/1000), _chunkSize, _frequency);
}
/**
* @brief get free size of the buffer.
* @return Number of free chunk.
*/
size_t getFreeSize() const;
/**
* @brief Get number of chunk in the buffer.
* @return number of chunk.
*/
size_t getSize() const {
return m_size;
}
/**
* @brief Get number of chunk that can be set in the buffer.
* @return number of chunk.
*/
size_t getCapacity() const {
return m_capacity;
}
/**
* @brief Write chunk in the buffer.
* @param[in] _data Pointer on the data.
* @param[in] _nbChunk number of chunk to copy.
* @param[in] _time Time to start write data (if before end ==> not replace data, write only if after end)
* @return Number of chunk copied.
*/
size_t write(const void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time);
size_t write(const void* _data, size_t _nbChunk);
/**
* @brief Read Chunk from the buffer to the pointer data.
* @param[out] _data Pointer on the data.
* @param[in] _nbChunk number of chunk to copy.
* @param[in] _time Time to start read data (if before start ==> add 0 at start, if after, remove unread data)
* @return Number of chunk copied.
*/
size_t read(void* _data, size_t _nbChunk, const std11::chrono::system_clock::time_point& _time);
//! @previous
size_t read(void* _data, size_t _nbChunk);
void setReadPosition(const std11::chrono::system_clock::time_point& _time);
std11::chrono::system_clock::time_point getReadTimeStamp() {
return m_timeRead;
}
/**
* @brief Clear the buffer.
*/
void clear();
private:
/**
* @brief Get number of free chunks before end of buffer.
* @return Number of chunk.
*/
size_t getFreeSizeBeforEnd() const;
/**
* @brief Get number of used chunks before end of buffer.
* @return Number of chunk.
*/
size_t getUsedSizeBeforEnd() const;
};
}
#endif

View File

@ -1,30 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_END_POINT_H__
#define __DRAIN_ALGO_END_POINT_H__
#include <drain/Algo.h>
namespace drain{
class EndPoint : public Algo {
protected:
/**
* @brief Constructor
*/
EndPoint() {};
void init() {
drain::Algo::init();
};
public:
/**
* @brief Destructor
*/
virtual ~EndPoint() {};
};
};
#endif

View File

@ -1,53 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_END_POINT_CALLBACK_H__
#define __DRAIN_ALGO_END_POINT_CALLBACK_H__
#include <drain/EndPoint.h>
#include <etk/functional.h>
namespace drain {
typedef std11::function<void (void* _data,
const std11::chrono::system_clock::time_point& _playTime,
size_t _nbChunk,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> playbackFunction;
typedef std11::function<void (const void* _data,
const std11::chrono::system_clock::time_point& _readTime,
size_t _nbChunk,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> recordFunction;
class EndPointCallback : public EndPoint {
private:
playbackFunction m_outputFunction;
recordFunction m_inputFunction;
protected:
/**
* @brief Constructor
*/
EndPointCallback();
void init(playbackFunction _callback);
void init(recordFunction _callback);
public:
static std11::shared_ptr<EndPointCallback> create(playbackFunction _callback);
static std11::shared_ptr<EndPointCallback> create(recordFunction _callback);
/**
* @brief Destructor
*/
virtual ~EndPointCallback() {};
virtual void configurationChange();
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
};
};
#endif

View File

@ -1,71 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include "debug.h"
#include <drain/EndPointRead.h>
#undef __class__
#define __class__ "EndPointRead"
drain::EndPointRead::EndPointRead() {
}
void drain::EndPointRead::init() {
drain::EndPoint::init();
m_type = "EndPointRead";
}
std11::shared_ptr<drain::EndPointRead> drain::EndPointRead::create() {
std11::shared_ptr<drain::EndPointRead> tmp(new drain::EndPointRead());
tmp->init();
return tmp;
}
void drain::EndPointRead::configurationChange() {
drain::EndPoint::configurationChange();
m_needProcess = true;
}
bool drain::EndPointRead::process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
drain::AutoLogInOut tmpLog("EndPointRead");
return false;
}
void drain::EndPointRead::setBufferSize(size_t _nbChunk) {
DRAIN_TODO("...");
}
void drain::EndPointRead::setBufferSize(const std11::chrono::microseconds& _time) {
DRAIN_TODO("...");
}
size_t drain::EndPointRead::getBufferSize() {
DRAIN_TODO("...");
return 0;
}
std11::chrono::microseconds drain::EndPointRead::getBufferSizeMicrosecond() {
DRAIN_TODO("...");
return std11::chrono::microseconds(0);
}
size_t drain::EndPointRead::getBufferFillSize() {
DRAIN_TODO("...");
return 0;
}
std11::chrono::microseconds drain::EndPointRead::getBufferFillSizeMicrosecond() {
DRAIN_TODO("...");
return std11::chrono::microseconds(0);
}

View File

@ -1,65 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_END_POINT_READ_H__
#define __DRAIN_ALGO_END_POINT_READ_H__
#include <drain/EndPoint.h>
namespace drain{
class EndPointRead : public EndPoint {
protected:
/**
* @brief Constructor
*/
EndPointRead();
void init();
public:
static std11::shared_ptr<EndPointRead> create();
/**
* @brief Destructor
*/
virtual ~EndPointRead() {};
virtual void configurationChange();
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
/**
* @brief Set buffer size in chunk number
* @param[in] _nbChunk Number of chunk in the buffer
*/
virtual void setBufferSize(size_t _nbChunk);
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @param[in] _time Time in microsecond of the buffer
*/
virtual void setBufferSize(const std11::chrono::microseconds& _time);
/**
* @brief get buffer size in chunk number
* @return Number of chunk that can be written in the buffer
*/
virtual size_t getBufferSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond that can be written in the buffer
*/
virtual std11::chrono::microseconds getBufferSizeMicrosecond();
/**
* @brief Get buffer size filled in chunk number
* @return Number of chunk in the buffer (that might be read/write)
*/
virtual size_t getBufferFillSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond of the buffer (that might be read/write)
*/
virtual std11::chrono::microseconds getBufferFillSizeMicrosecond();
};
};
#endif

View File

@ -1,85 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_ALGO_END_POINT_WRITE_H__
#define __DRAIN_ALGO_ALGO_END_POINT_WRITE_H__
#include <drain/EndPoint.h>
#include <etk/functional.h>
#include <etk/mutex.h>
#include <drain/CircularBuffer.h>
namespace drain{
typedef std11::function<void (const std11::chrono::system_clock::time_point& _time,
size_t _nbChunk,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> playbackFunctionWrite;
class EndPointWrite : public EndPoint {
private:
drain::CircularBuffer m_buffer;
playbackFunctionWrite m_function;
std11::mutex m_mutex;
protected:
/**
* @brief Constructor
*/
EndPointWrite();
void init();
public:
static std11::shared_ptr<EndPointWrite> create();
/**
* @brief Destructor
*/
virtual ~EndPointWrite() {};
virtual void configurationChange();
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
virtual void write(const void* _value, size_t _nbChunk);
virtual void setCallback(playbackFunctionWrite _function) {
m_function = _function;
}
protected:
std11::chrono::microseconds m_bufferSizeMicroseconds; // 0 if m_bufferSizeChunk != 0
size_t m_bufferSizeChunk; // 0 if m_bufferSizeMicroseconds != 0
public:
/**
* @brief Set buffer size in chunk number
* @param[in] _nbChunk Number of chunk in the buffer
*/
virtual void setBufferSize(size_t _nbChunk);
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @param[in] _time Time in microsecond of the buffer
*/
virtual void setBufferSize(const std11::chrono::microseconds& _time);
/**
* @brief get buffer size in chunk number
* @return Number of chunk that can be written in the buffer
*/
virtual size_t getBufferSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond that can be written in the buffer
*/
virtual std11::chrono::microseconds getBufferSizeMicrosecond();
/**
* @brief Get buffer size filled in chunk number
* @return Number of chunk in the buffer (that might be read/write)
*/
virtual size_t getBufferFillSize();
/**
* @brief Set buffer size size of the buffer with the stored time in µs
* @return Time in microsecond of the buffer (that might be read/write)
*/
virtual std11::chrono::microseconds getBufferFillSizeMicrosecond();
};
};
#endif

View File

@ -1,61 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_EQUALIZER_H__
#define __DRAIN_ALGO_EQUALIZER_H__
#include <drain/Algo.h>
#include <etk/memory.h>
#include <ejson/Object.h>
#include <drain/BiQuadFloat.h>
namespace drain {
class Equalizer : public Algo {
protected:
/**
* @brief Constructor
*/
Equalizer();
void init();
public:
static std11::shared_ptr<Equalizer> create();
/**
* @brief Destructor
*/
virtual ~Equalizer();
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
protected:
std11::shared_ptr<ejson::Object> m_config; // configuration of the equalizer.
public:
virtual bool setParameter(const std::string& _parameter, const std::string& _value);
virtual std::string getParameter(const std::string& _parameter) const;
virtual std::string getParameterProperty(const std::string& _parameter) const;
protected:
/**
* @brief repesent all the biquad to process:
* The first vector represent the number of channel to process
* The second vector represent the number of biquad to process
*/
std::vector<std::vector<BiQuadFloat> > m_biquads;
/**
* @brief Configure biquad with the user spec.
*/
void configureBiQuad();
public:
// for debug & tools only
std::vector<std::pair<float,float> > calculateTheory();
};
};
#endif

View File

@ -1,38 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_FORMAT_UPDATE_H__
#define __DRAIN_ALGO_FORMAT_UPDATE_H__
#include <drain/Algo.h>
namespace drain {
class FormatUpdate : public Algo {
protected:
/**
* @brief Constructor
*/
FormatUpdate();
void init();
public:
static std11::shared_ptr<FormatUpdate> create();
/**
* @brief Destructor
*/
virtual ~FormatUpdate() {};
protected:
virtual void configurationChange();
public:
virtual bool process(std11::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

View File

@ -1,91 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_IO_FORMAT_INTERFACE_H__
#define __DRAIN_ALGO_IO_FORMAT_INTERFACE_H__
#include <string>
#include <vector>
#include <stdint.h>
#include <audio/format.h>
#include <audio/channel.h>
#include <etk/chrono.h>
#include <etk/functional.h>
#include <etk/memory.h>
#include "AutoLogInOut.h"
#include "debug.h"
namespace drain{
class IOFormatInterface {
public:
IOFormatInterface();
IOFormatInterface(std::vector<audio::channel> _map, audio::format _format=audio::format_int16, float _frequency=48000.0f);
void set(std::vector<audio::channel> _map, audio::format _format=audio::format_int16, float _frequency=48000.0f);
protected:
bool m_configured;
public:
void setConfigured(bool _value);
bool getConfigured() const;
protected:
audio::format m_format; //!< input Algo Format
public:
/**
* @brief Get the algo format.
* @return the current Format.
*/
audio::format getFormat() const;
/**
* @brief Set the algo format.
* @param[in] _value New Format.
*/
void setFormat(audio::format _value);
protected:
std::vector<audio::channel> m_map; //!< input channel Map
public:
/**
* @brief Get the algo channel Map.
* @return the current channel Map.
*/
const std::vector<audio::channel>& getMap() const;
/**
* @brief Set the algo channel Map.
* @param[in] _value New channel Map.
*/
void setMap(const std::vector<audio::channel>& _value);
protected:
float m_frequency; //!< input Algo Format
public:
/**
* @brief Get the algo frequency.
* @return the current frequency.
*/
float getFrequency() const;
/**
* @brief Set the algo frequency.
* @param[in] _value New frequency.
*/
void setFrequency(float _value);
public:
/**
* @brief Get the Chunk size in byte.
* @return the number of byte used by chunk.
*/
int32_t getChunkSize() const;
protected:
std11::function<void()> m_ioChangeFunctor; //!< function pointer on the upper class
void configurationChange();
public:
/**
* @brief Set the callback function to be notify when the arameter change.
* @param[in] _functor Function to call.
*/
void setCallback(const std11::function<void()>& _functor);
};
std::ostream& operator <<(std::ostream& _os, const IOFormatInterface& _obj);
}
#endif

View File

@ -1,190 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_PROCESS_H__
#define __DRAIN_ALGO_PROCESS_H__
#include <string>
#include <vector>
#include <stdint.h>
#include <audio/format.h>
#include <audio/channel.h>
#include <drain/Algo.h>
#include <etk/chrono.h>
#include <etk/memory.h>
#include <etk/os/FSNode.h>
namespace drain{
typedef std11::function<void (const std::string& _origin, const std::string& _status)> statusFunction;
class Process {
protected:
std::vector<int8_t> m_data; //!< temporary overlap output buffer (change size of the output data)
public:
Process();
virtual ~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(std11::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)).
* @param[out] _chunkSize size of a single chunk. TODO : Not needed ... Remove it ...
* @return true The procress is done corectly.
* @return false An error occured.
*/
bool pull(std11::chrono::system_clock::time_point& _time,
void* _data,
size_t _nbChunk,
size_t _chunkSize);
/**
* @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(std11::chrono::system_clock::time_point& _time,
void* _inData,
size_t _inNbChunk,
void*& _outData,
size_t& _outNbChunk);
bool process(void* _inData,
size_t _inNbChunk,
void*& _outData,
size_t& _outNbChunk) {
std11::chrono::system_clock::time_point time;
return process(time, _inData, _inNbChunk, _outData, _outNbChunk);
}
bool processIn(void* _inData,
size_t _inNbChunk,
void* _outData,
size_t _outNbChunk);
protected:
IOFormatInterface m_inputConfig;
public:
const IOFormatInterface& getInputConfig() const {
return m_inputConfig;
}
void setInputConfig(const IOFormatInterface& _interface) {
m_inputConfig = _interface;
}
protected:
IOFormatInterface m_outputConfig;
public:
const IOFormatInterface& getOutputConfig() const {
return m_outputConfig;
}
void setOutputConfig(const IOFormatInterface& _interface) {
m_outputConfig = _interface;
}
protected:
std::vector<std11::shared_ptr<drain::Algo> > m_listAlgo;
public:
void pushBack(const std11::shared_ptr<drain::Algo>& _algo);
void pushFront(const std11::shared_ptr<drain::Algo>& _algo);
void clear() {
m_isConfigured = false;
m_listAlgo.clear();
}
size_t size() {
return m_listAlgo.size();
}
std::vector<std11::shared_ptr<drain::Algo> >::iterator begin() {
return m_listAlgo.begin();
}
std::vector<std11::shared_ptr<drain::Algo> >::iterator end() {
return m_listAlgo.end();
}
std11::shared_ptr<drain::Algo> operator[](int32_t _id) {
return m_listAlgo[_id];
}
template<typename T> std11::shared_ptr<T> get(const std::string& _name) {
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
if (m_listAlgo[iii] == nullptr) {
continue;
}
if (m_listAlgo[iii]->getName() == _name) {
return std11::dynamic_pointer_cast<T>(m_listAlgo[iii]);
}
}
return std11::shared_ptr<T>();
}
template<typename T> std11::shared_ptr<const T> get(const std::string& _name) const {
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
if (m_listAlgo[iii] == nullptr) {
continue;
}
if (m_listAlgo[iii]->getName() == _name) {
return std11::dynamic_pointer_cast<T>(m_listAlgo[iii]);
}
}
return std11::shared_ptr<const T>();
}
template<typename T> std11::shared_ptr<T> get(int32_t _id) {
return std11::dynamic_pointer_cast<T>(m_listAlgo[_id]);
}
template<typename T> void removeIfFirst() {
if (m_listAlgo.size() > 0) {
std11::shared_ptr<T> algoEP = get<T>(0);
if (algoEP != nullptr) {
m_listAlgo.erase(m_listAlgo.begin());
}
}
}
template<typename T> void removeIfLast() {
if (m_listAlgo.size() > 0) {
std11::shared_ptr<T> algoEP = get<T>(m_listAlgo.size()-1);
if (algoEP != nullptr) {
m_listAlgo.erase(m_listAlgo.begin()+m_listAlgo.size()-1);
}
}
}
template<typename T> bool hasType() {
for (size_t iii=0; iii<m_listAlgo.size(); ++iii) {
std11::shared_ptr<T> tmp = std11::dynamic_pointer_cast<T>(m_listAlgo[iii]);
if (tmp != nullptr) {
return true;
}
}
return false;
}
private:
statusFunction m_statusFunction;
public:
void generateStatus(const std::string& _origin, const std::string& _status);
void setStatusFunction(statusFunction _newFunction);
private:
bool m_isConfigured;
public:
void updateInterAlgo();
void removeAlgoDynamic();
private:
void displayAlgo();
void updateAlgo(size_t _position);
public:
void generateDot(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph);
// TODO : Remove this one when we find a good way to do it ...
void generateDotProcess(etk::FSNode& _node, int32_t _offset, int32_t _basicID, std::string& _nameIn, std::string& _nameOut, bool _reserseGraph);
};
};
#endif

View File

@ -1,51 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_RESAMPLER_H__
#define __DRAIN_ALGO_RESAMPLER_H__
#include <drain/Algo.h>
#ifdef HAVE_SPEEX_DSP_RESAMPLE
#include <speex/speex_resampler.h>
#endif
#include <etk/memory.h>
namespace drain {
// TODO: Manage change timestamp when pull mode
// TODO: drain ...
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
protected:
/**
* @brief Constructor
*/
Resampler();
void init();
public:
static std11::shared_ptr<Resampler> create();
/**
* @brief Destructor
*/
virtual ~Resampler();
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
private:
std11::chrono::nanoseconds m_residualTimeInResampler; //!< the time of data locked in the resampler ...
};
};
#endif

View File

@ -1,89 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_VOLUME_H__
#define __DRAIN_ALGO_VOLUME_H__
#include <drain/Algo.h>
#ifdef HAVE_SPEEX_DSP_RESAMPLE
#include <speex/speex_resampler.h>
#endif
#include <etk/memory.h>
namespace drain {
// data structure.
class VolumeElement {
public:
VolumeElement(const std::string& _name="ERROR-VOLUME-NAME", float _volumedB=0.0f) :
m_name(_name),
m_volumedB(_volumedB) {
}
private:
std::string m_name;
public:
std::string getName() const {
return m_name;
}
private:
float m_volumedB;
public:
float getVolume() const {
return m_volumedB;
}
void setVolume(float _volumedB) {
m_volumedB = _volumedB;
}
};
// TODO: Optimisation
// TODO: Zero crossing
// TODO: Continuous update volume
// TODO: Manage multiple volume
// TODO: Manage set volume
class Volume : public Algo {
private:
std::vector<std11::shared_ptr<drain::VolumeElement> > m_volumeList;
// for float input :
float m_volumeAppli;
// for integer input :
int32_t m_volumeDecalage; // Volume to apply is simple as : X * m_coef >> m_coef
int32_t m_volumeCoef;
// convertion function:
void (*m_functionConvert)(void* _input, void* _output, size_t _nbSample, int32_t _volumeCoef, int32_t _volumeDecalage, float _volumeAppli);
protected:
/**
* @brief Constructor
*/
Volume();
void init();
public:
static std11::shared_ptr<Volume> create();
/**
* @brief Destructor
*/
virtual ~Volume();
protected:
virtual void configurationChange();
public:
virtual bool process(std11::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
public:
virtual std::vector<audio::format> getFormatSupportedInput();
virtual std::vector<audio::format> getFormatSupportedOutput();
public:
virtual void addVolumeStage(const std11::shared_ptr<drain::VolumeElement>& _volume);
virtual bool setParameter(const std::string& _parameter, const std::string& _value);
virtual std::string getParameter(const std::string& _parameter) const;
virtual std::string getParameterProperty(const std::string& _parameter) const;
public:
void volumeChange();
};
};
#endif

View File

@ -1,43 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __DRAIN_ALGO_CORE_H__
#define __DRAIN_ALGO_CORE_H__
#include <string>
#include <audio/format.h>
#include <drain/channel.h>
#include <etk/chrono.h>
namespace drain {
/**
* @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
*/
drain::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<drain::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

48
lutin_audio_drain.py Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/python
import lutinModule as module
import lutinTools as tools
import lutinDebug as debug
def get_desc():
return "audio_drain : Basic audio algo interface single pipe to provess data"
def create(target):
myModule = module.Module(__file__, 'audio_drain', 'LIBRARY')
myModule.add_src_file([
'audio/drain/debug.cpp',
'audio/drain/airtalgo.cpp',
'audio/drain/Algo.cpp',
'audio/drain/BiQuadFloat.cpp',
'audio/drain/ChannelReorder.cpp',
'audio/drain/CircularBuffer.cpp',
'audio/drain/EndPointCallback.cpp',
'audio/drain/EndPoint.cpp',
'audio/drain/EndPointRead.cpp',
'audio/drain/EndPointWrite.cpp',
'audio/drain/FormatUpdate.cpp',
'audio/drain/Process.cpp',
'audio/drain/Resampler.cpp',
'audio/drain/Volume.cpp',
'audio/drain/IOFormatInterface.cpp',
'audio/drain/AutoLogInOut.cpp',
'audio/drain/Equalizer.cpp'
])
# TODO: myModule.add_optional_module_depend('speexdsp', "HAVE_SPEEX_DSP_RESAMPLE")
myModule.compile_flags_CC("-DHAVE_SPEEX_DSP_RESAMPLE")
myModule.add_module_depend(['etk', 'audio', 'ejson', 'speexdsp'])
myModule.add_export_path(tools.get_current_path(__file__))
# add the currrent module at the
return myModule

View File

@ -8,7 +8,7 @@ def get_desc():
def create(target):
myModule = module.Module(__file__, 'drain_test', 'BINARY')
myModule = module.Module(__file__, 'audio_drain_test', 'BINARY')
myModule.add_src_file([
'test/main.cpp',
@ -20,7 +20,7 @@ def create(target):
'test/equalizer.cpp'
])
myModule.add_module_depend(['drain', 'gtest', 'etk'])
myModule.add_module_depend(['audio_drain', 'gtest', 'etk'])
return myModule

View File

@ -1,49 +0,0 @@
#!/usr/bin/python
import lutinModule as module
import lutinTools as tools
import lutinDebug as debug
def get_desc():
return "drain : Basic audio algo interface single pipe to provess data"
def create(target):
myModule = module.Module(__file__, 'drain', 'LIBRARY')
myModule.add_src_file([
'drain/debug.cpp',
'drain/airtalgo.cpp',
'drain/Algo.cpp',
'drain/BiQuadFloat.cpp',
'drain/ChannelReorder.cpp',
'drain/CircularBuffer.cpp',
'drain/EndPointCallback.cpp',
'drain/EndPoint.cpp',
'drain/EndPointRead.cpp',
'drain/EndPointWrite.cpp',
'drain/FormatUpdate.cpp',
'drain/Process.cpp',
'drain/Resampler.cpp',
'drain/Volume.cpp',
'drain/IOFormatInterface.cpp',
'drain/AutoLogInOut.cpp',
'drain/Equalizer.cpp',
'drain/echoCanceller/Lms.cpp'
])
# TODO: myModule.add_optional_module_depend('speexdsp', "HAVE_SPEEX_DSP_RESAMPLE")
myModule.compile_flags_CC("-DHAVE_SPEEX_DSP_RESAMPLE")
myModule.add_module_depend(['etk', 'audio', 'ejson', 'speexdsp'])
myModule.add_export_path(tools.get_current_path(__file__))
# add the currrent module at the
return myModule