diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp index 9291dc1f27b9760bb7fedf7d756597ef6830064a..a05eef17780b702cb48c03cabd5ae16a09730dcf 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 e4c741de1bdfd6360105f28e30a0f96afd204d1c..cc94eccff0829288ed55e9125e91281c816ddffa 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 e7f081197628f83dd6e412e475c9fefe582e221a..9cd8269f3c83f552454ed4322bc41ee14ed066bc 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 2ea2e275c966c479baef7bb584466f9e89fcc954..411c20389c39b4b6e415f93a8ef3ca5085522e1c 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 18f095d735283364790dc46ca904c83d4bb8ad8f..6d17b8d671f84e056ec32cdc1a0c1a5f9fd17af2 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 69761cdab7e81de9a408d695dbc494f1c5eef8b1..b10382945d52fd9da91ec7af22011fa8d13f206c 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 e6f6212ce61ab1856395967686c1e658e755fccb..ba70c8628ea47d4b11ab77f959e1dd38b567a45c 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;