/** @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 #include #include #include #include #include #include #include #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 _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 _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 m_map; //!< input channel Map public: /** * @brief Get the algo channel Map. * @return the current channel Map. */ const std::vector& getMap() const{ return m_map; } /** * @brief Set the algo channel Map. * @param[in] _value New channel Map. */ void setMap(const std::vector& _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 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& _functor) { m_ioChangeFunctor = _functor; } }; std::ostream& operator <<(std::ostream& _os, const IOFormatInterface& _obj); class Algo : public std::enable_shared_from_this { 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 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 m_supportedFormat; public: virtual std::vector getFormatSupportedInput() { if (m_output.getConfigured() == true) { std::vector out; out.push_back(m_output.getFormat()); return out; } return m_supportedFormat; }; virtual std::vector getFormatSupportedOutput() { if (m_input.getConfigured() == true) { std::vector out; out.push_back(m_input.getFormat()); return out; } return m_supportedFormat; }; protected: // note when nothing ==> support all type std::vector> m_supportedMap; public: virtual std::vector> getMapSupportedInput() { if (m_output.getConfigured() == true) { std::vector> out; out.push_back(m_output.getMap()); return out; } return m_supportedMap; }; virtual std::vector> getMapSupportedOutput() { if (m_input.getConfigured() == true) { std::vector> out; out.push_back(m_input.getMap()); return out; } return m_supportedMap; }; protected: // note when nothing ==> support all type std::vector m_supportedFrequency; public: virtual std::vector getFrequencySupportedInput() { if (m_output.getConfigured() == true) { std::vector out; out.push_back(m_output.getFrequency()); return out; } return m_supportedFrequency; }; virtual std::vector getFrequencySupportedOutput() { if (m_input.getConfigured() == true) { std::vector out; out.push_back(m_input.getFrequency()); return out; } return m_supportedFrequency; }; }; }; #include "debugRemove.h" #endif