diff --git a/sflphone-common/src/samplerateconverter.cpp b/sflphone-common/src/samplerateconverter.cpp index ccdb09da238437baf77d8273298b7774f603368b..bfede7ce321df32a1e73b0572356eaf215c670b9 100644 --- a/sflphone-common/src/samplerateconverter.cpp +++ b/sflphone-common/src/samplerateconverter.cpp @@ -18,124 +18,143 @@ #include "samplerateconverter.h" -SamplerateConverter::SamplerateConverter (void) - : _frequence (Manager::instance().getConfigInt (AUDIO , ALSA_SAMPLE_RATE)) //44100 - , _framesize (Manager::instance().getConfigInt (AUDIO , ALSA_FRAME_SIZE)) - , _floatBufferDownMic (NULL) - , _floatBufferUpMic (NULL) - , _src_state_mic (NULL) - , _floatBufferDownSpkr (NULL) - , _floatBufferUpSpkr (NULL) - , _src_state_spkr (NULL) - , _src_err (0) + SamplerateConverter::SamplerateConverter (void) + : _frequence (Manager::instance().getConfigInt (AUDIO , ALSA_SAMPLE_RATE)) //44100 + , _framesize (Manager::instance().getConfigInt (AUDIO , ALSA_FRAME_SIZE)) + , _floatBufferDownMic (NULL) + , _floatBufferUpMic (NULL) + , _src_state_mic (NULL) + , _floatBufferDownSpkr (NULL) + , _floatBufferUpSpkr (NULL) + , _src_state_spkr (NULL) + , _src_err (0) { - init(); + init(); } -SamplerateConverter::SamplerateConverter (int freq , int fs) - : _frequence (freq) - , _framesize (fs) - , _floatBufferDownMic (NULL) - , _floatBufferUpMic (NULL) - , _src_state_mic (NULL) - , _floatBufferDownSpkr (NULL) - , _floatBufferUpSpkr (NULL) - , _src_state_spkr (NULL) - , _src_err (0) + SamplerateConverter::SamplerateConverter (int freq , int fs) + : _frequence (freq) + , _framesize (fs) + , _floatBufferDownMic (NULL) + , _floatBufferUpMic (NULL) + , _src_state_mic (NULL) + , _floatBufferDownSpkr (NULL) + , _floatBufferUpSpkr (NULL) + , _src_state_spkr (NULL) + , _src_err (0) { - init(); + init(); } SamplerateConverter::~SamplerateConverter (void) { - delete [] _floatBufferUpMic; - _floatBufferUpMic = NULL; - delete [] _floatBufferDownMic; - _floatBufferDownMic = NULL; + delete [] _floatBufferUpMic; + _floatBufferUpMic = NULL; + delete [] _floatBufferDownMic; + _floatBufferDownMic = NULL; - delete [] _floatBufferUpSpkr; - _floatBufferUpSpkr = NULL; - delete [] _floatBufferDownSpkr; - _floatBufferDownSpkr = NULL; + delete [] _floatBufferUpSpkr; + _floatBufferUpSpkr = NULL; + delete [] _floatBufferDownSpkr; + _floatBufferDownSpkr = NULL; - // libSamplerateConverter-related - _src_state_mic = src_delete (_src_state_mic); - _src_state_spkr = src_delete (_src_state_spkr); + // libSamplerateConverter-related + _src_state_mic = src_delete (_src_state_mic); + _src_state_spkr = src_delete (_src_state_spkr); } void SamplerateConverter::init (void) { - // libSamplerateConverter-related - // Set the converter type for the upsampling and the downsampling - // interpolator SRC_SINC_BEST_QUALITY - // interpolator SRC_SINC_FASTEST - // interpolator SRC_LINEAR - _src_state_mic = src_new (SRC_SINC_FASTEST, 1, &_src_err); - _src_state_spkr = src_new (SRC_SINC_FASTEST, 1, &_src_err); - - int nbSamplesMax = (int) (getFrequence() * getFramesize() / 1000); - _floatBufferDownMic = new float32[nbSamplesMax]; - _floatBufferUpMic = new float32[nbSamplesMax]; - _floatBufferDownSpkr = new float32[nbSamplesMax]; - _floatBufferUpSpkr = new float32[nbSamplesMax]; + // libSamplerateConverter-related + // Set the converter type for the upsampling and the downsampling + // interpolator SRC_SINC_BEST_QUALITY + // interpolator SRC_SINC_FASTEST + // interpolator SRC_LINEAR + _src_state_mic = src_new (SRC_SINC_FASTEST, 1, &_src_err); + _src_state_spkr = src_new (SRC_SINC_FASTEST, 1, &_src_err); + + int nbSamplesMax = (int) (getFrequence() * getFramesize() / 1000); + _floatBufferDownMic = new float32[nbSamplesMax]; + _floatBufferUpMic = new float32[nbSamplesMax]; + _floatBufferDownSpkr = new float32[nbSamplesMax]; + _floatBufferUpSpkr = new float32[nbSamplesMax]; } + void +SamplerateConverter::Short2FloatArray (const short *in, float *out, int len) +{ + // factor is 1/(2^15), used to rescale the short int range to the + // [-1.0 - 1.0] float range. +#define S2F_FACTOR .000030517578125f; + + while (len) + { + len--; + out[len] = (float) in[len] * S2F_FACTOR; + } +} + + //TODO Add ifdef for int16 or float32 type int SamplerateConverter::upsampleData (SFLDataFormat* dataIn , SFLDataFormat* dataOut, int samplerate1 , int samplerate2 , int nbSamples) { - double upsampleFactor = (double) samplerate2 / samplerate1 ; - //_debug("factor = %f\n" , upsampleFactor); - int nbSamplesMax = (int) (samplerate2 * getFramesize() / 1000); - - if (upsampleFactor != 1 && dataIn != NULL) { - SRC_DATA src_data; - src_data.data_in = _floatBufferDownSpkr; - src_data.data_out = _floatBufferUpSpkr; - src_data.input_frames = nbSamples; - src_data.output_frames = (int) floor (upsampleFactor * nbSamples); - src_data.src_ratio = upsampleFactor; - src_data.end_of_input = 0; // More data will come - //_debug("upsample %d %d %f %d\n" , src_data.input_frames , src_data.output_frames, src_data.src_ratio , nbSamples); - src_short_to_float_array (dataIn , _floatBufferDownSpkr, nbSamples); - //_debug("upsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); - src_process (_src_state_spkr, &src_data); - //_debug("upsample %d %d %d\n" , samplerate1, samplerate2 , nbSamples); - nbSamples = (src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen; - src_float_to_short_array (_floatBufferUpSpkr, dataOut, nbSamples); - //_debug("upsample %d %d %d\n" , samplerate1, samplerate2 , nbSamples); - } - - return nbSamples; + double upsampleFactor = (double) samplerate2 / samplerate1 ; + //_debug("factor = %f\n" , upsampleFactor); + int nbSamplesMax = (int) (samplerate2 * getFramesize() / 1000); + + if (upsampleFactor != 1 && dataIn != NULL) { + SRC_DATA src_data; + src_data.data_in = _floatBufferDownSpkr; + src_data.data_out = _floatBufferUpSpkr; + src_data.input_frames = nbSamples; + src_data.output_frames = (int) floor (upsampleFactor * nbSamples); + src_data.src_ratio = upsampleFactor; + src_data.end_of_input = 0; // More data will come + //_debug("upsample %d %d %f %d\n" , src_data.input_frames , src_data.output_frames, src_data.src_ratio , nbSamples); + // Override libsamplerate conversion function + Short2FloatArray (dataIn , _floatBufferDownSpkr, nbSamples); + //src_short_to_float_array (dataIn , _floatBufferDownSpkr, nbSamples); + //_debug("upsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); + src_process (_src_state_spkr, &src_data); + //_debug("upsample %d %d %d\n" , samplerate1, samplerate2 , nbSamples); + nbSamples = (src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen; + src_float_to_short_array (_floatBufferUpSpkr, dataOut, nbSamples); + //_debug("upsample %d %d %d\n" , samplerate1, samplerate2 , nbSamples); + } + + return nbSamples; } //TODO Add ifdef for int16 or float32 type int SamplerateConverter::downsampleData (SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples) { - double downsampleFactor = (double) samplerate1 / samplerate2; - //_debug("factor = %f\n" , downsampleFactor); - int nbSamplesMax = (int) (samplerate1 * getFramesize() / 1000); - - if (downsampleFactor != 1) { - SRC_DATA src_data; - src_data.data_in = _floatBufferUpMic; - src_data.data_out = _floatBufferDownMic; - src_data.input_frames = nbSamples; - src_data.output_frames = (int) floor (downsampleFactor * nbSamples); - src_data.src_ratio = downsampleFactor; - src_data.end_of_input = 0; // More data will come - //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); - src_short_to_float_array (dataIn, _floatBufferUpMic, nbSamples); - //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); - src_process (_src_state_mic, &src_data); - //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); - nbSamples = (src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen; - //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); - src_float_to_short_array (_floatBufferDownMic , dataOut , nbSamples); - } - - return nbSamples; + double downsampleFactor = (double) samplerate1 / samplerate2; + //_debug("factor = %f\n" , downsampleFactor); + int nbSamplesMax = (int) (samplerate1 * getFramesize() / 1000); + + if (downsampleFactor != 1) { + SRC_DATA src_data; + src_data.data_in = _floatBufferUpMic; + src_data.data_out = _floatBufferDownMic; + src_data.input_frames = nbSamples; + src_data.output_frames = (int) floor (downsampleFactor * nbSamples); + src_data.src_ratio = downsampleFactor; + src_data.end_of_input = 0; // More data will come + //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); + // Override libsamplerate conversion function + Short2FloatArray (dataIn , _floatBufferUpMic, nbSamples); + //src_short_to_float_array (dataIn, _floatBufferUpMic, nbSamples); + //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); + src_process (_src_state_mic, &src_data); + //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); + nbSamples = (src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen; + //_debug("downsample %d %f %d\n" , src_data.output_frames, src_data.src_ratio , nbSamples); + src_float_to_short_array (_floatBufferDownMic , dataOut , nbSamples); + } + + return nbSamples; } diff --git a/sflphone-common/src/samplerateconverter.h b/sflphone-common/src/samplerateconverter.h index f6423197fadcf268ae851fd0f1d9c88167ffddd2..d4d37035e0c008f68c35ed3f7d87f3eb185e681b 100644 --- a/sflphone-common/src/samplerateconverter.h +++ b/sflphone-common/src/samplerateconverter.h @@ -26,63 +26,72 @@ #include "manager.h" class SamplerateConverter { - public: - /** Constructor */ - SamplerateConverter( void ); - SamplerateConverter( int freq , int fs ); - /** Destructor */ - ~SamplerateConverter( void ); - - /** - * Upsample from the samplerate1 to the samplerate2 - * @param data The data buffer - * @param SamplerateConverter1 The lower sample rate - * @param SamplerateConverter2 The higher sample rate - * @param nbSamples The number of samples to process - * @return int The number of samples after the operation - */ - int upsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples ); - - /** - * Downsample from the samplerate1 to the samplerate2 - * @param data The data buffer - * @param SamplerateConverter1 The lower sample rate - * @param SamplerateConverter2 The higher sample rate - * @param nbSamples The number of samples to process - * @return int The number of samples after the operation - */ - int downsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples ); - - int getFrequence( void ) { return _frequence; } - - int getFramesize( void ) { return _framesize; } - - private: - // Copy Constructor - SamplerateConverter(const SamplerateConverter& rh); - - // Assignment Operator - SamplerateConverter& operator=( const SamplerateConverter& rh); - - void init( void ); - - /** Audio layer caracteristics */ - int _frequence; - int _framesize; - - /** Downsampled/Upsampled float buffers for the mic data processing */ - float32* _floatBufferDownMic; - float32* _floatBufferUpMic; - /** libSamplerateConverter converter for outgoing voice */ - SRC_STATE* _src_state_mic; - - /** Downsampled/Upsampled float buffers for the speaker data processing */ - float32* _floatBufferDownSpkr; - float32* _floatBufferUpSpkr; - /** libSamplerateConverter converter for incoming voice */ - SRC_STATE* _src_state_spkr; - /** libSamplerateConverter error */ - int _src_err; + public: + /** Constructor */ + SamplerateConverter( void ); + SamplerateConverter( int freq , int fs ); + /** Destructor */ + ~SamplerateConverter( void ); + + /** + * Upsample from the samplerate1 to the samplerate2 + * @param data The data buffer + * @param SamplerateConverter1 The lower sample rate + * @param SamplerateConverter2 The higher sample rate + * @param nbSamples The number of samples to process + * @return int The number of samples after the operation + */ + int upsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples ); + + /** + * Downsample from the samplerate1 to the samplerate2 + * @param data The data buffer + * @param SamplerateConverter1 The lower sample rate + * @param SamplerateConverter2 The higher sample rate + * @param nbSamples The number of samples to process + * @return int The number of samples after the operation + */ + int downsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples ); + + int getFrequence( void ) { return _frequence; } + + int getFramesize( void ) { return _framesize; } + + /** + * Convert short table to floats for audio processing + * @param in the input (short) array + * @param out The resulting (float) array + * @param len The number of elements in both tables + */ + void Short2FloatArray (const short *in, float *out, int len); + + + private: + // Copy Constructor + SamplerateConverter(const SamplerateConverter& rh); + + // Assignment Operator + SamplerateConverter& operator=( const SamplerateConverter& rh); + + void init( void ); + + /** Audio layer caracteristics */ + int _frequence; + int _framesize; + + /** Downsampled/Upsampled float buffers for the mic data processing */ + float32* _floatBufferDownMic; + float32* _floatBufferUpMic; + /** libSamplerateConverter converter for outgoing voice */ + SRC_STATE* _src_state_mic; + + /** Downsampled/Upsampled float buffers for the speaker data processing */ + float32* _floatBufferDownSpkr; + float32* _floatBufferUpSpkr; + /** libSamplerateConverter converter for incoming voice */ + SRC_STATE* _src_state_spkr; + /** libSamplerateConverter error */ + int _src_err; }; #endif //_SAMPLE_RATE_H