From 7cf8ce36dcb16444162415815b6295946dec1186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Carr=C3=A9?= <rafael.carre@savoirfairelinux.com> Date: Wed, 10 Aug 2011 16:15:19 -0400 Subject: [PATCH] resampler: grow internal buffers dynamically also fix wrong assertion about the final number of samples --- sflphone-common/src/audio/alsa/alsalayer.cpp | 2 +- .../audio/audiortp/AudioRtpRecordHandler.cpp | 2 +- .../src/audio/pulseaudio/pulselayer.cpp | 2 +- .../src/audio/samplerateconverter.cpp | 34 +++++++++++-------- .../src/audio/samplerateconverter.h | 5 ++- sflphone-common/src/audio/sound/audiofile.cpp | 2 +- sflphone-common/src/iax/iaxvoiplink.cpp | 2 +- 7 files changed, 29 insertions(+), 20 deletions(-) diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp index 9291dc1f27..a05eef1778 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.cpp +++ b/sflphone-common/src/audio/alsa/alsalayer.cpp @@ -129,7 +129,7 @@ AlsaLayer::openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, _audioThread = NULL; // use 1 sec buffer for resampling - _converter = new SamplerateConverter (_audioSampleRate, 1000); + _converter = new SamplerateConverter (_audioSampleRate); AudioLayer::_dcblocker = new DcBlocker(); AudioLayer::_audiofilter = new AudioProcessing (static_cast<Algorithm *> (_dcblocker)); diff --git a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp index e4c741de1b..cc94eccff0 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp +++ b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp @@ -190,7 +190,7 @@ void AudioRtpRecordHandler::initBuffers() // (internal buffers initialized with maximal sampling rate and frame size) int rate = getCodecSampleRate(); int fs = getCodecFrameSize(); - _audioRtpRecord._converter = new SamplerateConverter (rate, fs); + _audioRtpRecord._converter = new SamplerateConverter (rate); int nbSamplesMax = (int) ( (getCodecSampleRate() * getCodecFrameSize() / 1000)); _audioRtpRecord._micData = new SFLDataFormat[nbSamplesMax]; diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp index e7f0811976..9cd8269f3c 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp @@ -403,7 +403,7 @@ void PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int indexR flushUrgent(); // use 1 sec buffer for resampling - _converter = new SamplerateConverter (_audioSampleRate, 1000); + _converter = new SamplerateConverter (_audioSampleRate); // Instantiate the algorithm AudioLayer::_dcblocker = new DcBlocker(); diff --git a/sflphone-common/src/audio/samplerateconverter.cpp b/sflphone-common/src/audio/samplerateconverter.cpp index 2ea2e275c9..411c20389c 100644 --- a/sflphone-common/src/audio/samplerateconverter.cpp +++ b/sflphone-common/src/audio/samplerateconverter.cpp @@ -30,16 +30,17 @@ #include "samplerateconverter.h" #include "manager.h" +#include <cassert> -SamplerateConverter::SamplerateConverter (int freq , int fs) +SamplerateConverter::SamplerateConverter (int freq) : _maxFreq(freq) { int err; _src_state = src_new (SRC_LINEAR, 1, &err); - int nbSamplesMax = (int) ( (freq * fs) / 1000); + _samples = (freq * 20) / 1000; // start with 20 ms buffers - _floatBufferIn = new float32[nbSamplesMax]; - _floatBufferOut = new float32[nbSamplesMax]; + _floatBufferIn = new float32[_samples]; + _floatBufferOut = new float32[_samples]; } SamplerateConverter::~SamplerateConverter (void) @@ -61,29 +62,34 @@ SamplerateConverter::Short2FloatArray (const short *in, float *out, int len) } //TODO Add ifdef for int16 or float32 type -void SamplerateConverter::resample (SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples) +void SamplerateConverter::resample (SFLDataFormat* dataIn , SFLDataFormat* dataOut , int inputFreq , int outputFreq , int nbSamples) { - double sampleFactor; - if (samplerate1 > samplerate2) - sampleFactor = (double) samplerate1 / samplerate2; - else - sampleFactor = (double) samplerate2 / samplerate1; + assert(outputFreq <= _maxFreq); + double sampleFactor = (double) inputFreq / outputFreq; if (sampleFactor == 1) return; + int outSamples = nbSamples * sampleFactor; + if (outSamples > _samples) { + /* grow buffer if needed */ + _samples = outSamples; + delete [] _floatBufferIn; + delete [] _floatBufferOut; + _floatBufferIn = new float32[_samples]; + _floatBufferOut = new float32[_samples]; + } + SRC_DATA src_data; src_data.data_in = _floatBufferIn; src_data.data_out = _floatBufferOut; src_data.input_frames = nbSamples; - src_data.output_frames = nbSamples; + src_data.output_frames = outSamples; src_data.src_ratio = sampleFactor; src_data.end_of_input = 0; // More data will come Short2FloatArray (dataIn , _floatBufferIn, nbSamples); src_process (_src_state, &src_data); - assert(nbSamples == src_data.output_frames_gen); - - src_float_to_short_array (_floatBufferOut, dataOut , nbSamples); + src_float_to_short_array (_floatBufferOut, dataOut , outSamples); } diff --git a/sflphone-common/src/audio/samplerateconverter.h b/sflphone-common/src/audio/samplerateconverter.h index 18f095d735..6d17b8d671 100644 --- a/sflphone-common/src/audio/samplerateconverter.h +++ b/sflphone-common/src/audio/samplerateconverter.h @@ -47,7 +47,7 @@ class SamplerateConverter * internal buffer size. Converter must be reinitialized * every time these parameters change */ - SamplerateConverter (int freq, int frameSize); + SamplerateConverter (int freq); /** Destructor */ ~SamplerateConverter (void); @@ -77,8 +77,11 @@ class SamplerateConverter // Assignment Operator SamplerateConverter& operator= (const SamplerateConverter& rh); + /* temporary buffers */ float32* _floatBufferIn; float32* _floatBufferOut; + size_t _samples; // size in samples of temporary buffers + int _maxFreq; // maximal output frequency SRC_STATE* _src_state; }; diff --git a/sflphone-common/src/audio/sound/audiofile.cpp b/sflphone-common/src/audio/sound/audiofile.cpp index 69761cdab7..b10382945d 100644 --- a/sflphone-common/src/audio/sound/audiofile.cpp +++ b/sflphone-common/src/audio/sound/audiofile.cpp @@ -212,7 +212,7 @@ WaveFile::WaveFile (const std::string& fileName, unsigned int audioSamplingRate) // Sample rate converter initialized with 88200 sample long int converterSamples = (srate > audioSamplingRate) ? srate : audioSamplingRate; - SamplerateConverter _converter (converterSamples, 2000); + SamplerateConverter _converter (converterSamples); // Get length of data from the header. SINT32 bytes; diff --git a/sflphone-common/src/iax/iaxvoiplink.cpp b/sflphone-common/src/iax/iaxvoiplink.cpp index e6f6212ce6..ba70c8628e 100644 --- a/sflphone-common/src/iax/iaxvoiplink.cpp +++ b/sflphone-common/src/iax/iaxvoiplink.cpp @@ -77,7 +77,7 @@ IAXVoIPLink::IAXVoIPLink (const std::string& accountID) : VoIPLink () // to get random number for RANDOM_PORT srand (time (NULL)); - converter = new SamplerateConverter (44100, 20); + converter = new SamplerateConverter (44100); // int nbSamplesMax = (int) (converter->getFrequence() * converter->getFramesize() / 1000); int nbSamplesMax = (44100 * 20) / 1000; -- GitLab