332 lines
9.1 KiB
C++
332 lines
9.1 KiB
C++
/** @file
|
|
* @author Edouard DUPIN
|
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
|
* @license APACHE v2.0 (see license file)
|
|
*/
|
|
|
|
|
|
#ifndef __AIRT_ALGO_CORE_ALGO_H__
|
|
#define __AIRT_ALGO_CORE_ALGO_H__
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <stdint.h>
|
|
#include <airtalgo/format.h>
|
|
#include <airtalgo/channel.h>
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include "debug.h"
|
|
|
|
namespace airtalgo{
|
|
class autoLogInOut {
|
|
private:
|
|
std::string m_value;
|
|
public:
|
|
autoLogInOut(const std::string& _value) :
|
|
m_value(_value) {
|
|
AIRTALGO_VERBOSE(" '" << m_value << "' [START]");
|
|
}
|
|
~autoLogInOut() {
|
|
AIRTALGO_VERBOSE(" '" << m_value << "' [STOP]");
|
|
}
|
|
};
|
|
class IOFormatInterface {
|
|
public:
|
|
IOFormatInterface() :
|
|
m_configured(false),
|
|
m_format(airtalgo::format_unknow),
|
|
m_map(),
|
|
m_frequency(0) {
|
|
m_map.push_back(airtalgo::channel_frontLeft);
|
|
m_map.push_back(airtalgo::channel_frontRight);
|
|
}
|
|
IOFormatInterface(std::vector<airtalgo::channel> _map, airtalgo::format _format=airtalgo::format_int16, float _frequency=48000.0f) :
|
|
m_configured(true),
|
|
m_format(_format),
|
|
m_map(_map),
|
|
m_frequency(_frequency) {
|
|
|
|
AIRTALGO_WARNING(" plop : " << m_map << " " << m_format << " " << m_frequency);
|
|
}
|
|
void set(std::vector<airtalgo::channel> _map, airtalgo::format _format=airtalgo::format_int16, float _frequency=48000.0f) {
|
|
bool hasChange = false;
|
|
if (m_map != _map) {
|
|
m_map = _map;
|
|
hasChange = true;
|
|
}
|
|
if (m_format != _format) {
|
|
m_format = _format;
|
|
hasChange = true;
|
|
}
|
|
if (m_frequency == _frequency) {
|
|
m_frequency = _frequency;
|
|
hasChange = true;
|
|
}
|
|
if (hasChange == true) {
|
|
m_configured = true;
|
|
configurationChange();
|
|
}
|
|
AIRTALGO_WARNING(" plop : " << m_map << " " << m_format << " " << m_frequency);
|
|
}
|
|
protected:
|
|
bool m_configured;
|
|
public:
|
|
void setConfigured(bool _value) {
|
|
m_configured = _value;
|
|
}
|
|
bool getConfigured() const {
|
|
return m_configured;
|
|
}
|
|
protected:
|
|
airtalgo::format m_format; //!< input Algo Format
|
|
public:
|
|
/**
|
|
* @brief Get the algo format.
|
|
* @return the current Format.
|
|
*/
|
|
airtalgo::format getFormat() const {
|
|
return m_format;
|
|
}
|
|
/**
|
|
* @brief Set the algo format.
|
|
* @param[in] _value New Format.
|
|
*/
|
|
void setFormat(airtalgo::format _value) {
|
|
if (m_format == _value) {
|
|
return;
|
|
}
|
|
m_format = _value;
|
|
m_configured = true;
|
|
configurationChange();
|
|
}
|
|
protected:
|
|
std::vector<airtalgo::channel> m_map; //!< input channel Map
|
|
public:
|
|
/**
|
|
* @brief Get the algo channel Map.
|
|
* @return the current channel Map.
|
|
*/
|
|
const std::vector<airtalgo::channel>& getMap() const{
|
|
return m_map;
|
|
}
|
|
/**
|
|
* @brief Set the algo channel Map.
|
|
* @param[in] _value New channel Map.
|
|
*/
|
|
void setMap(const std::vector<airtalgo::channel>& _value) {
|
|
AIRTALGO_DEBUG(" base : " << m_map << " " << _value);
|
|
if (m_map == _value) {
|
|
return;
|
|
}
|
|
m_map = _value;
|
|
m_configured = true;
|
|
AIRTALGO_DEBUG(" base2 : " << m_map);
|
|
configurationChange();
|
|
}
|
|
protected:
|
|
float m_frequency; //!< input Algo Format
|
|
public:
|
|
/**
|
|
* @brief Get the algo frequency.
|
|
* @return the current frequency.
|
|
*/
|
|
float getFrequency() const{
|
|
return m_frequency;
|
|
}
|
|
/**
|
|
* @brief Set the algo frequency.
|
|
* @param[in] _value New frequency.
|
|
*/
|
|
void setFrequency(float _value) {
|
|
if (m_frequency == _value) {
|
|
return;
|
|
}
|
|
m_configured = true;
|
|
m_frequency = _value;
|
|
configurationChange();
|
|
}
|
|
protected:
|
|
std::function<void()> m_ioChangeFunctor; //!< function pointer on the upper class
|
|
void configurationChange() {
|
|
if (m_ioChangeFunctor != nullptr) {
|
|
m_ioChangeFunctor();
|
|
}
|
|
}
|
|
public:
|
|
/**
|
|
* @brief Set the callback function to be notify when the arameter change.
|
|
* @param[in] _functor Function to call.
|
|
*/
|
|
void setCallback(const std::function<void()>& _functor) {
|
|
m_ioChangeFunctor = _functor;
|
|
}
|
|
|
|
};
|
|
std::ostream& operator <<(std::ostream& _os, const IOFormatInterface& _obj);
|
|
|
|
class Algo : public std::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& _name) {
|
|
m_type = _name;
|
|
}
|
|
private:
|
|
bool m_temporary;
|
|
public:
|
|
void setTemporary() {
|
|
m_temporary = true;
|
|
}
|
|
bool getTemporary() const {
|
|
return m_temporary;
|
|
}
|
|
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) {
|
|
AIRTALGO_WARNING(" plopp : " << _format.getMap() << " " << _format.getFormat() << " " << _format.getFrequency());
|
|
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) {
|
|
AIRTALGO_WARNING(" plopp : " << _format.getMap() << " " << _format.getFormat() << " " << _format.getFrequency());
|
|
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(std::chrono::system_clock::time_point& _time,
|
|
void* _input,
|
|
size_t _inputNbChunk,
|
|
void*& _output,
|
|
size_t& _outputNbChunk) = 0;
|
|
/**
|
|
* @brief To approximatively have the correct input of data of every algo ge call it to have an aproxomation of input data needed.
|
|
* @param[in] _output number of chunk estimate in output
|
|
* @return number of sample needed to have nearly the good number of sample
|
|
*/
|
|
virtual size_t needInputData(size_t _output);
|
|
protected: // note when nothing ==> support all type
|
|
std::vector<airtalgo::format> m_supportedFormat;
|
|
public:
|
|
virtual std::vector<airtalgo::format> getFormatSupportedInput() {
|
|
if (m_output.getConfigured() == true) {
|
|
std::vector<airtalgo::format> out;
|
|
out.push_back(m_output.getFormat());
|
|
return out;
|
|
}
|
|
return m_supportedFormat;
|
|
};
|
|
virtual std::vector<airtalgo::format> getFormatSupportedOutput() {
|
|
if (m_input.getConfigured() == true) {
|
|
std::vector<airtalgo::format> out;
|
|
out.push_back(m_input.getFormat());
|
|
return out;
|
|
}
|
|
return m_supportedFormat;
|
|
};
|
|
protected: // note when nothing ==> support all type
|
|
std::vector<std::vector<airtalgo::channel>> m_supportedMap;
|
|
public:
|
|
virtual std::vector<std::vector<airtalgo::channel>> getMapSupportedInput() {
|
|
if (m_output.getConfigured() == true) {
|
|
std::vector<std::vector<airtalgo::channel>> out;
|
|
out.push_back(m_output.getMap());
|
|
return out;
|
|
}
|
|
return m_supportedMap;
|
|
};
|
|
virtual std::vector<std::vector<airtalgo::channel>> getMapSupportedOutput() {
|
|
if (m_input.getConfigured() == true) {
|
|
std::vector<std::vector<airtalgo::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;
|
|
};
|
|
};
|
|
};
|
|
#include "debugRemove.h"
|
|
|
|
#endif
|