[DEV] create new API i,terface for speex ==> more stable, ABI stable

This commit is contained in:
Edouard DUPIN 2015-04-21 21:57:32 +02:00
parent b358318a9d
commit d1b2e07677
4 changed files with 126 additions and 100 deletions

View File

@ -8,28 +8,27 @@
#include <audio/algo/speex/Resampler.h> #include <audio/algo/speex/Resampler.h>
#include <audio/algo/speex/debug.h> #include <audio/algo/speex/debug.h>
#include <cmath> #include <cmath>
#ifdef HAVE_SPEEX_DSP
#include <speex/speex_resampler.h>
#endif
#undef __class__ #undef __class__
#define __class__ "algo::speex::Resampler" #define __class__ "algo::speex::ResamplerPrivate"
namespace audio {
audio::algo::speex::Resampler::Resampler() : namespace algo {
namespace speex {
class ResamplerPrivate {
private:
#ifdef HAVE_SPEEX_DSP
SpeexResamplerState* m_speexResampler;
#endif
enum audio::format m_format;
public:
ResamplerPrivate(int8_t _nbChannel, float _inputSampleRate, float _outputSampleRate, int8_t _quality, enum audio::format _format) :
#ifdef HAVE_SPEEX_DSP #ifdef HAVE_SPEEX_DSP
m_speexResampler(nullptr), m_speexResampler(nullptr),
#endif #endif
m_isConfigured(false) { m_format(_format) {
}
audio::algo::speex::Resampler::~Resampler() {
#ifdef HAVE_SPEEX_DSP
if (m_speexResampler != nullptr) {
speex_resampler_destroy(m_speexResampler);
m_speexResampler = nullptr;
}
#endif
}
void audio::algo::speex::Resampler::init(int8_t _nbChannel, float _inputSampleRate, float _outputSampleRate, int8_t _quality) {
#ifdef HAVE_SPEEX_DSP #ifdef HAVE_SPEEX_DSP
if (m_speexResampler != nullptr) { if (m_speexResampler != nullptr) {
speex_resampler_destroy(m_speexResampler); speex_resampler_destroy(m_speexResampler);
@ -41,31 +40,23 @@ void audio::algo::speex::Resampler::init(int8_t _nbChannel, float _inputSampleRa
_inputSampleRate, _inputSampleRate,
_outputSampleRate, _outputSampleRate,
_quality, &err); _quality, &err);
m_isConfigured = true;
#else #else
AA_SPEEX_WARNING("SPEEX DSP lib not accessible ==> can not resample"); AA_SPEEX_WARNING("SPEEX DSP lib not accessible ==> can not resample");
m_isConfigured = false;
#endif #endif
}
std::vector<enum audio::format> audio::algo::speex::Resampler::getSupportedFormat() {
std::vector<enum audio::format> out = getNativeSupportedFormat();
return out;
}
std::vector<enum audio::format> audio::algo::speex::Resampler::getNativeSupportedFormat() {
std::vector<enum audio::format> out;
out.push_back(audio::format_float);
out.push_back(audio::format_int16);
return out;
}
void audio::algo::speex::Resampler::process(void* _output, size_t& _nbChunkOut, const void* _input, size_t _nbChunk, enum audio::format _format) {
if (m_isConfigured == false) {
AA_SPEEX_ERROR("Algo is not initialized...");
} }
~ResamplerPrivate() {
#ifdef HAVE_SPEEX_DSP #ifdef HAVE_SPEEX_DSP
switch (_format) { if (m_speexResampler != nullptr) {
speex_resampler_destroy(m_speexResampler);
m_speexResampler = nullptr;
}
#endif
}
void process(void* _output, size_t& _nbChunkOut, const void* _input, size_t _nbChunk) {
#ifdef HAVE_SPEEX_DSP
switch (m_format) {
case audio::format_int16: case audio::format_int16:
{ {
uint32_t nbChunkInput = _nbChunk; uint32_t nbChunkInput = _nbChunk;
@ -109,12 +100,51 @@ void audio::algo::speex::Resampler::process(void* _output, size_t& _nbChunkOut,
} }
break; break;
default: default:
AA_SPEEX_ERROR("Can not Limit with unsupported format : " << _format); AA_SPEEX_ERROR("Can not Limit with unsupported format : " << m_format);
break; break;
} }
#else #else
AA_SPEEX_ERROR("Not build with speex DSP ... "); AA_SPEEX_ERROR("Not build with speex DSP ... ");
_nbChunkOut = _nbChunk/10; _nbChunkOut = _nbChunk/10;
#endif #endif
}
};
}
}
}
#undef __class__
#define __class__ "algo::speex::Resampler"
audio::algo::speex::Resampler::Resampler() {
}
audio::algo::speex::Resampler::~Resampler() {
}
void audio::algo::speex::Resampler::init(int8_t _nbChannel, float _inputSampleRate, float _outputSampleRate, int8_t _quality, enum audio::format _format) {
m_private.reset();
m_private = std11::make_shared<audio::algo::speex::ResamplerPrivate>(_nbChannel, _inputSampleRate, _outputSampleRate, _quality, _format);
}
std::vector<enum audio::format> audio::algo::speex::Resampler::getSupportedFormat() {
std::vector<enum audio::format> out = getNativeSupportedFormat();
return out;
}
std::vector<enum audio::format> audio::algo::speex::Resampler::getNativeSupportedFormat() {
std::vector<enum audio::format> out;
out.push_back(audio::format_float);
out.push_back(audio::format_int16);
return out;
}
void audio::algo::speex::Resampler::process(void* _output, size_t& _nbChunkOut, const void* _input, size_t _nbChunk) {
if (m_private == nullptr) {
AA_SPEEX_ERROR("Algo is not initialized...");
}
m_private->process(_output, _nbChunkOut, _input, _nbChunk);
} }

View File

@ -11,20 +11,14 @@
#include <etk/types.h> #include <etk/types.h>
#include <audio/format.h> #include <audio/format.h>
#include <etk/chrono.h> #include <etk/chrono.h>
#include <etk/memory.h>
#include <vector> #include <vector>
#ifdef HAVE_SPEEX_DSP
#include <speex/speex_resampler.h>
#endif
namespace audio { namespace audio {
namespace algo { namespace algo {
namespace speex { namespace speex {
class ResamplerPrivate;
class Resampler { class Resampler {
protected:
#ifdef HAVE_SPEEX_DSP
SpeexResamplerState* m_speexResampler;
#endif
bool m_isConfigured;
public: public:
Resampler(); Resampler();
virtual ~Resampler(); virtual ~Resampler();
@ -35,8 +29,9 @@ namespace audio {
* @param[in] _inputSampleRate Input sample rate. * @param[in] _inputSampleRate Input sample rate.
* @param[in] _outputSampleRate Output sample rate. * @param[in] _outputSampleRate Output sample rate.
* @param[in] _quality Resampler quality [1..10]. * @param[in] _quality Resampler quality [1..10].
* @param[in] _format Input/output data format.
*/ */
virtual void init(int8_t _nbChannel, float _inputSampleRate, float _outputSampleRate, int8_t _quality); virtual void init(int8_t _nbChannel, float _inputSampleRate, float _outputSampleRate, int8_t _quality=4, enum audio::format _format = audio::format_float);
/** /**
* @brief Get list of format suported in input. * @brief Get list of format suported in input.
* @return list of supported format * @return list of supported format
@ -54,9 +49,10 @@ namespace audio {
* @param[in] _input Input data. * @param[in] _input Input data.
* @param[in] _nbChunk Number of chunk in the input buffer. * @param[in] _nbChunk Number of chunk in the input buffer.
* @param[in] _nbChannel Number of channel in the stream. * @param[in] _nbChannel Number of channel in the stream.
* @param[in] _format Input data format.
*/ */
virtual void process(void* _output, size_t& _nbChunkOut, const void* _input, size_t _nbChunk, enum audio::format _format = audio::format_float); virtual void process(void* _output, size_t& _nbChunkOut, const void* _input, size_t _nbChunk);
protected:
std11::shared_ptr<ResamplerPrivate> m_private; // private data.
}; };
} }
} }

View File

@ -15,7 +15,7 @@ def create(target):
]) ])
myModule.add_module_depend(['etk', 'audio']) myModule.add_module_depend(['etk', 'audio'])
myModule.add_optionnal_module_depend('speexdsp', "HAVE_SPEEX_DSP", True) myModule.add_optionnal_module_depend('speexdsp', "HAVE_SPEEX_DSP")
myModule.add_export_path(tools.get_current_path(__file__)) myModule.add_export_path(tools.get_current_path(__file__))
# return module # return module

View File

@ -79,11 +79,11 @@ float performanceResamplerStepFloat(float _sampleRateIn, float _sampleRateOut, i
APPL_INFO("Start Resampler performance ... " << _sampleRateIn << " -> " << _sampleRateOut << " float"); APPL_INFO("Start Resampler performance ... " << _sampleRateIn << " -> " << _sampleRateOut << " float");
Performance perfo; Performance perfo;
audio::algo::speex::Resampler algo; audio::algo::speex::Resampler algo;
algo.init(1, _sampleRateIn, _sampleRateOut, _quality); algo.init(1, _sampleRateIn, _sampleRateOut, _quality, audio::format_float);
for (int32_t iii=0; iii<1024; ++iii) { for (int32_t iii=0; iii<1024; ++iii) {
perfo.tic(); perfo.tic();
size_t sizeOut = output.size(); size_t sizeOut = output.size();
algo.process(&output[0], sizeOut, &input[0], input.size(), audio::format_float); algo.process(&output[0], sizeOut, &input[0], input.size());
perfo.toc(); perfo.toc();
usleep(1000); usleep(1000);
} }
@ -119,11 +119,11 @@ float performanceResamplerStepI16(float _sampleRateIn, float _sampleRateOut, int
APPL_INFO("Start Resampler performance ... " << _sampleRateIn << " -> " << _sampleRateOut << " int16_t"); APPL_INFO("Start Resampler performance ... " << _sampleRateIn << " -> " << _sampleRateOut << " int16_t");
Performance perfo; Performance perfo;
audio::algo::speex::Resampler algo; audio::algo::speex::Resampler algo;
algo.init(1, _sampleRateIn, _sampleRateOut, _quality); algo.init(1, _sampleRateIn, _sampleRateOut, _quality, audio::format_int16);
for (int32_t iii=0; iii<1024; ++iii) { for (int32_t iii=0; iii<1024; ++iii) {
perfo.tic(); perfo.tic();
size_t sizeOut = output.size(); size_t sizeOut = output.size();
algo.process(&output[0], sizeOut, &input[0], input.size(), audio::format_int16); algo.process(&output[0], sizeOut, &input[0], input.size());
perfo.toc(); perfo.toc();
usleep(1000); usleep(1000);
} }
@ -247,7 +247,7 @@ int main(int _argc, const char** _argv) {
Performance perfo; Performance perfo;
audio::algo::speex::Resampler algo; audio::algo::speex::Resampler algo;
algo.init(nbChan, sampleRateIn, sampleRateOut, quality); algo.init(nbChan, sampleRateIn, sampleRateOut, quality, audio::format_int16);
int32_t lastPourcent = -1; int32_t lastPourcent = -1;
size_t outputPosition = 0; size_t outputPosition = 0;
for (int32_t iii=0; iii<inputData.size()/blockSize; ++iii) { for (int32_t iii=0; iii<inputData.size()/blockSize; ++iii) {
@ -259,7 +259,7 @@ int main(int _argc, const char** _argv) {
} }
size_t availlableSize = (output.size() - outputPosition) / nbChan; size_t availlableSize = (output.size() - outputPosition) / nbChan;
perfo.tic(); perfo.tic();
algo.process(&output[outputPosition], availlableSize, &inputData[iii*blockSize], blockSize, audio::format_int16); algo.process(&output[outputPosition], availlableSize, &inputData[iii*blockSize], blockSize);
if (perf == true) { if (perf == true) {
perfo.toc(); perfo.toc();
usleep(1000); usleep(1000);