[DEV] rework drain in audio-drain
This commit is contained in:
parent
98cbaedc2c
commit
62e581f5ae
@ -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
216
audio/drain/Algo.h
Normal 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
|
@ -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]");
|
||||
}
|
29
audio/drain/AutoLogInOut.h
Normal file
29
audio/drain/AutoLogInOut.h
Normal 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
|
||||
|
@ -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
97
audio/drain/BiQuadFloat.h
Normal 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
|
||||
|
@ -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) {
|
39
audio/drain/ChannelReorder.h
Normal file
39
audio/drain/ChannelReorder.h
Normal 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
|
@ -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];
|
145
audio/drain/CircularBuffer.h
Normal file
145
audio/drain/CircularBuffer.h
Normal 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
34
audio/drain/EndPoint.h
Normal file
@ -0,0 +1,34 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#ifndef __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
|
@ -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());
|
55
audio/drain/EndPointCallback.h
Normal file
55
audio/drain/EndPointCallback.h
Normal 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
|
71
audio/drain/EndPointRead.cpp
Normal file
71
audio/drain/EndPointRead.cpp
Normal 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);
|
||||
}
|
||||
|
67
audio/drain/EndPointRead.h
Normal file
67
audio/drain/EndPointRead.h
Normal 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
|
@ -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()));
|
||||
}
|
87
audio/drain/EndPointWrite.h
Normal file
87
audio/drain/EndPointWrite.h
Normal 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
|
@ -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
63
audio/drain/Equalizer.h
Normal 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
|
@ -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;
|
40
audio/drain/FormatUpdate.h
Normal file
40
audio/drain/FormatUpdate.h
Normal 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
|
@ -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);
|
||||
}
|
93
audio/drain/IOFormatInterface.h
Normal file
93
audio/drain/IOFormatInterface.h
Normal 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
|
@ -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
192
audio/drain/Process.h
Normal 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
|
@ -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
53
audio/drain/Resampler.h
Normal 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
|
@ -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
91
audio/drain/Volume.h
Normal 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
45
audio/drain/airtalgo.h
Normal 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
|
@ -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;
|
||||
}
|
@ -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)
|
@ -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
|
214
drain/Algo.h
214
drain/Algo.h
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
190
drain/Process.h
190
drain/Process.h
@ -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
|
@ -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
|
@ -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
|
@ -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
48
lutin_audio_drain.py
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user