[DEV] create new API i,terface for speex ==> more stable, ABI stable
This commit is contained in:
parent
b358318a9d
commit
d1b2e07677
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user