Commit 4df0d6a2 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Sample rate conversion stands in one place, tight to the config

parent 1e9dc55b
sflphone (0.9.2) unstable; urgency=low
* Ticket #14: Sample rate conversion stands in one place now
-- Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> Thu, 22 May 2008 11:14:25 -0500
sflphone (0.9.1) unstable; urgency=low
* Add a search tool in the history
* Migrate some gtk_entry_new to sexy_icon_entry_new
......
......@@ -39,7 +39,6 @@
#include "ringbuffer.h"
#include "../user_cfg.h"
#include "../sipcall.h"
#include <samplerate.h>
////////////////////////////////////////////////////////////////////////////////
// AudioRtp
......@@ -103,9 +102,6 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
_ca = sipcall;
_sym = sym;
// AudioRtpRTX should be close if we change sample rate
//int IDcodec= _ca->getAudioCodec();
//_codecSampleRate = _ca->getAudioCodec()->getClockRate();
//_codecDesc = Manager::instance().getCodecDescriptorMap();
// TODO: Change bind address according to user settings.
// TODO: this should be the local ip not the external (router) IP
std::string localipConfig = _ca->getLocalIp(); // _ca->getLocalIp();
......@@ -119,13 +115,6 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
_sessionRecv = NULL;
_sessionSend = NULL;
}
// libsamplerate-related
// Set the converter type for the upsampling and the downsampling
// interpolator SRC_SINC_BEST_QUALITY
_src_state_mic = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
_src_state_spkr = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
}
AudioRtpRTX::~AudioRtpRTX () {
......@@ -146,41 +135,34 @@ AudioRtpRTX::~AudioRtpRTX () {
delete _session; _session = NULL;
}
delete [] _intBufferDown; _intBufferDown = NULL;
delete [] _floatBufferUp; _floatBufferUp = NULL;
delete [] _floatBufferDown; _floatBufferDown = NULL;
delete [] _dataAudioLayer; _dataAudioLayer = NULL;
delete [] micData; micData = NULL;
delete [] micDataConverted; micDataConverted = NULL;
delete [] micDataEncoded; micDataEncoded = NULL;
delete [] _sendDataEncoded; _sendDataEncoded = NULL;
delete [] _receiveDataDecoded; _receiveDataDecoded = NULL;
delete [] spkrDataDecoded; spkrDataDecoded = NULL;
delete [] spkrDataConverted; spkrDataConverted = NULL;
delete time; time = NULL;
// libsamplerate-related
_src_state_mic = src_delete(_src_state_mic);
_src_state_spkr = src_delete(_src_state_spkr);
}
void
AudioRtpRTX::initBuffers()
{
converter = new SamplerateConverter();
converter = new SamplerateConverter( _layerSampleRate , _layerFrameSize );
int nbSamplesMax = (int) (_layerSampleRate * _layerFrameSize /1000);
_dataAudioLayer = new SFLDataFormat[nbSamplesMax];
_receiveDataDecoded = new int16[nbSamplesMax];
_floatBufferDown = new float32[nbSamplesMax];
_floatBufferUp = new float32[nbSamplesMax];
_sendDataEncoded = new unsigned char[nbSamplesMax];
_intBufferDown = new int16[nbSamplesMax];
micData = new SFLDataFormat[nbSamplesMax];
micDataConverted = new SFLDataFormat[nbSamplesMax];
micDataEncoded = new unsigned char[nbSamplesMax];
spkrDataConverted = new SFLDataFormat[nbSamplesMax];
spkrDataDecoded = new SFLDataFormat[nbSamplesMax];
}
void
AudioRtpRTX::initAudioRtpSession (void)
{
try {
if (_ca == 0) { return; }
_audiocodec = Manager::instance().getCodecDescriptorMap().getCodec( _ca->getAudioCodec() );
......@@ -257,7 +239,6 @@ AudioRtpRTX::sendSessionFromMic(int timestamp)
// 3. encode it
// 4. send it
try {
int16* toSIP = NULL;
timestamp += time->getSecond();
if (_ca==0) { _debug(" !ARTP: No call associated (mic)\n"); return; } // no call, so we do nothing
......@@ -270,50 +251,38 @@ AudioRtpRTX::sendSessionFromMic(int timestamp)
int maxBytesToGet = _layerSampleRate * _layerFrameSize * sizeof(SFLDataFormat) / 1000;
// available bytes inside ringbuffer
int availBytesFromMic = audiolayer->canGetMic();
//printf("%i \n", availBytesFromMic);
// take the lowest
int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;
//printf("%i\n", bytesAvail);
// Get bytes from micRingBuffer to data_from_mic
int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat);
//_debug("get data from mic\n");
int nbSample = audiolayer->getMic( micData , bytesAvail ) / sizeof(SFLDataFormat);
int nb_sample_up = nbSample;
int nbSamplesMax = _layerFrameSize * _audiocodec->getClockRate() / 1000;
//_debug("resample data\n");
nbSample = reSampleData(_audiocodec->getClockRate(), nb_sample_up, DOWN_SAMPLING);
toSIP = _intBufferDown;
if ( nbSample < nbSamplesMax - 10 ) { // if only 10 is missing, it's ok
// fill end with 0...
//_debug("begin: %p, nbSample: %d\n", toSIP, nbSample);
memset(toSIP + nbSample, 0, (nbSamplesMax-nbSample)*sizeof(int16));
memset( micDataConverted + nbSample, 0, (nbSamplesMax-nbSample)*sizeof(int16));
nbSample = nbSamplesMax;
}
// debug - dump sound in a file
//_debug("AR: Nb sample: %d int, [0]=%d [1]=%d [2]=%d\n", nbSample, toSIP[0], toSIP[1], toSIP[2]);
// for the mono: range = 0 to RTP_FRAME2SEND * sizeof(int16)
// codecEncode(char *dest, int16* src, size in bytes of the src)
int compSize = _audiocodec->codecEncode(_sendDataEncoded, toSIP, nbSample*sizeof(int16));
//printf("jusqu'ici tout vas bien\n");
int compSize = _audiocodec->codecEncode( micDataEncoded , micDataConverted , nbSample*sizeof(int16));
// encode divise by two
// Send encoded audio sample over the network
if (compSize > nbSamplesMax) { _debug("! ARTP: %d should be %d\n", compSize, nbSamplesMax);}
if (!_sym) {
_sessionSend->putData(timestamp, _sendDataEncoded, compSize);
_sessionSend->putData(timestamp, micDataEncoded, compSize);
} else {
_session->putData(timestamp, _sendDataEncoded, compSize);
_session->putData(timestamp, micDataEncoded, compSize);
}
toSIP = NULL;
} catch(...) {
_debugException("! ARTP: sending failed");
throw;
}
}
void
AudioRtpRTX::receiveSessionForSpkr (int& countTime)
{
......@@ -338,11 +307,9 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
}
int payload = adu->getType(); // codec type
unsigned char* data = (unsigned char*)adu->getData(); // data in char
unsigned char* spkrData = (unsigned char*)adu->getData(); // data in char
unsigned int size = adu->getSize(); // size in char
//_fstream.write((char*) data, size);
// Decode data with relevant codec
int max = (int)(_codecSampleRate * _layerFrameSize / 1000);
......@@ -352,13 +319,9 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
size=max;
}
//printf("size = %i\n", size);
if (_audiocodec != NULL) {
int expandedSize = _audiocodec->codecDecode(_receiveDataDecoded, data, size);
// printf("%i\n", expandedSize);
//_fstream.write((char*) _receiveDataDecoded, );
int expandedSize = _audiocodec->codecDecode( spkrDataDecoded , spkrData , size );
//buffer _receiveDataDecoded ----> short int or int16, coded on 2 bytes
int nbInt16 = expandedSize / sizeof(int16);
//nbInt16 represents the number of samples we just decoded
......@@ -366,21 +329,16 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
_debug("We have decoded an RTP packet larger than expected: %s VS %s. Cropping.\n", nbInt16, max);
nbInt16=max;
}
SFLDataFormat* toAudioLayer;
int nbSample = nbInt16;
// Do sample rate conversion
int nb_sample_down = nbSample;
nbSample = reSampleData(_codecSampleRate , nb_sample_down, UP_SAMPLING);
#ifdef DATAFORMAT_IS_FLOAT
toAudioLayer = _floatBufferUp;
#else
toAudioLayer = _dataAudioLayer;
#endif
audiolayer->playSamples(toAudioLayer, nbSample * sizeof(SFLDataFormat), true);
audiolayer->playSamples( spkrDataConverted , nbSample * sizeof(SFLDataFormat), true);
// Notify (with a beep) an incoming call when there is already a call
countTime += time->getSecond();
if (Manager::instance().incomingCallWaiting() > 0) {
......@@ -393,7 +351,6 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
} else {
countTime += time->getSecond();
}
delete adu; adu = NULL;
} catch(...) {
_debugException("! ARTP: receiving failed");
......@@ -407,75 +364,20 @@ AudioRtpRTX::receiveSessionForSpkr (int& countTime)
AudioRtpRTX::reSampleData(int sampleRate_codec, int nbSamples, int status)
{
if(status==UP_SAMPLING){
//return upSampleData(sampleRate_codec, nbSamples);
return converter->upsampleData( _receiveDataDecoded , _dataAudioLayer, sampleRate_codec , _layerSampleRate , nbSamples );
return converter->upsampleData( spkrDataDecoded , spkrDataConverted , sampleRate_codec , _layerSampleRate , nbSamples );
}
else if(status==DOWN_SAMPLING){
//return downSampleData(sampleRate_codec, nbSamples);
return converter->downsampleData( _dataAudioLayer , _intBufferDown, sampleRate_codec , _layerSampleRate , nbSamples );
return converter->downsampleData( micData , micDataConverted , sampleRate_codec , _layerSampleRate , nbSamples );
}
else
return 0;
}
////////////////////////////////////////////////////////////////////
//////////// RESAMPLING FUNCTIONS /////////////////////////////////
//////////////////////////////////////////////////////////////////
int
AudioRtpRTX::upSampleData(int sampleRate_codec, int nbSamples)
{
double upsampleFactor = (double) _layerSampleRate / sampleRate_codec;
int nbSamplesMax = (int) (_layerSampleRate * _layerFrameSize /1000);
if( upsampleFactor != 1 )
{
SRC_DATA src_data;
src_data.data_in = _floatBufferDown;
src_data.data_out = _floatBufferUp;
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
src_short_to_float_array(_receiveDataDecoded, _floatBufferDown, nbSamples);
src_process(_src_state_spkr, &src_data);
nbSamples = ( src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen;
src_float_to_short_array(_floatBufferUp, _dataAudioLayer, nbSamples);
}
return nbSamples;
}
int
AudioRtpRTX::downSampleData(int sampleRate_codec, int nbSamples)
{
double downsampleFactor = (double) sampleRate_codec / _layerSampleRate;
int nbSamplesMax = (int) (sampleRate_codec * _layerFrameSize / 1000);
if ( downsampleFactor != 1)
{
SRC_DATA src_data;
src_data.data_in = _floatBufferUp;
src_data.data_out = _floatBufferDown;
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
src_short_to_float_array(_dataAudioLayer, _floatBufferUp, nbSamples);
src_process(_src_state_mic, &src_data);
nbSamples = ( src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen;
src_float_to_short_array(_floatBufferDown, _intBufferDown, nbSamples);
}
return nbSamples;
}
//////////////////////// END RESAMPLING //////////////////////////////////////////////////////
void
AudioRtpRTX::run () {
//mic, we receive from soundcard in stereo, and we send encoded
//encoding before sending
AudioLayer *audiolayer = Manager::instance().getAudioDriver();
//loadCodec(_ca->getAudioCodec());
_layerFrameSize = audiolayer->getFrameSize(); // en ms
_layerSampleRate = audiolayer->getSampleRate();
initBuffers();
......@@ -499,7 +401,6 @@ AudioRtpRTX::run () {
int countTime = 0; // for receive
TimerPort::setTimer(_layerFrameSize);
//audiolayer->flushMic();
audiolayer->startStream();
_start.post();
_debug("- ARTP Action: Start\n");
......@@ -517,8 +418,6 @@ AudioRtpRTX::run () {
Thread::sleep(TimerPort::getTimer());
TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
}
//_fstream.close();
//unloadCodec();
//_debug("stop stream for audiortp loop\n");
audiolayer->stopStream();
} catch(std::exception &e) {
......
......@@ -28,8 +28,6 @@
#include <ccrtp/rtp.h>
#include <cc++/numbers.h>
#include <samplerate.h>
#include "../global.h"
#include "../samplerateconverter.h"
......@@ -85,34 +83,16 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
/** Is the session symmetric or not */
bool _sym;
/** When we receive data, we decode it inside this buffer */
int16* _receiveDataDecoded;
/** Buffers used for send data from the mic */
unsigned char* _sendDataEncoded;
/** Downsampled int16 buffer */
int16* _intBufferDown;
/** After that we send the data inside this buffer if there is a format conversion or rate conversion */
/** Also use for getting mic-ringbuffer data */
SFLDataFormat* _dataAudioLayer;
/** Downsampled float buffer */
float32* _floatBufferDown;
/** Mic-data related buffers */
SFLDataFormat* micData;
SFLDataFormat* micDataConverted;
unsigned char* micDataEncoded;
/** Upsampled float buffer */
float32* _floatBufferUp;
/** libsamplerate converter for incoming voice */
SRC_STATE* _src_state_spkr;
/** libsamplerate converter for outgoing voice */
SRC_STATE* _src_state_mic;
/** libsamplerate error */
int _src_err;
/** Speaker-data related buffers */
SFLDataFormat* spkrDataDecoded;
SFLDataFormat* spkrDataConverted;
/** Sample rate converter object */
SamplerateConverter* converter;
/** Variables to process audio stream: sample rate for playing sound (typically 44100HZ) */
......@@ -158,22 +138,6 @@ class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
*/
int reSampleData(int sampleRate_codec, int nbSamples, int status);
/**
* Upsample the data from the clock rate of the codec to the sample rate of the layer
* @param sampleRate_codec The sample rate of the codec selected to encode/decode the data
* @param nbSamples Number of samples to process
* @return int The number of samples after process
*/
int upSampleData(int sampleRate_codec, int nbSamples);
/**
* Downsample the data from the sample rate of the layer to the clock rate of the codec
* @param sampleRate_codec The sample rate of the codec selected to encode/decode the data
* @param nbSamples Number of samples to process
* @return int The number of samples after process
*/
int downSampleData(int sampleRate_codec, int nbSamples);
/** The audio codec used during the session */
AudioCodec* _audiocodec;
};
......
This diff is collapsed.
/*
* Copyright (C) 2006-2007 Savoir-Faire Linux inc.
* Copyright (C) 2006-2007-2008 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -24,9 +24,9 @@
#include "voiplink.h"
#include <iax2/iax-client.h>
#include "global.h"
#include <samplerate.h>
#include "audio/codecDescriptor.h"
#include "samplerateconverter.h"
class EventThread;
class IAXCall;
......@@ -279,31 +279,17 @@ class IAXVoIPLink : public VoIPLink
/** Connection to audio card/device */
AudioLayer* audiolayer;
/** When we receive data, we decode it inside this buffer */
int16* _receiveDataDecoded;
/** When we send data, we encode it inside this buffer*/
unsigned char* _sendDataEncoded;
/** After that we send the data inside this buffer if there is a format conversion or rate conversion. */
/* Also use for getting mic-ringbuffer data */
SFLDataFormat* _dataAudioLayer;
/** Buffer for 8000hz samples in conversion */
float32* _floatBuffer8000;
/** Buffer for 48000hz samples in conversion */
float32* _floatBuffer48000;
/** Buffer for 8000hz samples for mic conversion */
int16* _intBuffer8000;
/** libsamplerate converter for incoming voice */
SRC_STATE* _src_state_spkr;
/** Mic-data related buffers */
SFLDataFormat* micData;
SFLDataFormat* micDataConverted;
unsigned char* micDataEncoded;
/** libsamplerate converter for outgoing voice */
SRC_STATE* _src_state_mic;
/** Speaker-data related buffers */
SFLDataFormat* spkrDataDecoded;
SFLDataFormat* spkrDataConverted;
/** libsamplerate error */
int _src_err;
/** Sample rate converter object */
SamplerateConverter* converter;
};
......
......@@ -19,71 +19,98 @@
#include "samplerateconverter.h"
SamplerateConverter::SamplerateConverter( void ) {
// libSamplerateConverter-related
// Set the converter type for the upsampling and the downsampling
// interpolator SRC_SINC_BEST_QUALITY
_src_state_mic = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
_src_state_spkr = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
// Default values
_frequence = Manager::instance().getConfigInt( AUDIO , ALSA_SAMPLE_RATE ); // 44100;
_framesize = Manager::instance().getConfigInt( AUDIO , ALSA_FRAME_SIZE );
init();
}
int nbSamplesMax = (int) ( 44100 * 20 /1000); // TODO Make this generic
_floatBufferDown = new float32[nbSamplesMax];
_floatBufferUp = new float32[nbSamplesMax];
SamplerateConverter::SamplerateConverter( int freq , int fs ) {
_frequence = freq ;
_framesize = fs ;
init();
}
SamplerateConverter::~SamplerateConverter( void ) {
delete [] _floatBufferUp; _floatBufferUp = NULL;
delete [] _floatBufferDown; _floatBufferDown = NULL;
delete [] _floatBufferUpMic; _floatBufferUpMic = NULL;
delete [] _floatBufferDownMic; _floatBufferDownMic = 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);
}
void SamplerateConverter::init( void ) {
// libSamplerateConverter-related
// Set the converter type for the upsampling and the downsampling
// interpolator SRC_SINC_BEST_QUALITY
_src_state_mic = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
_src_state_spkr = src_new(SRC_SINC_BEST_QUALITY, 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];
}
//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 ;
int nbSamplesMax = (int) (samplerate2 * 20 /1000); // TODO get the value from the constructor
if( upsampleFactor != 1 )
int nbSamplesMax = (int) ( samplerate2 * getFramesize() / 1000 );
if( upsampleFactor != 1 && dataIn != NULL )
{
_debug("Begin upsample data\n");
SRC_DATA src_data;
src_data.data_in = _floatBufferDown;
src_data.data_out = _floatBufferUp;
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
src_short_to_float_array( dataIn , _floatBufferDown, nbSamples);
//_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(_floatBufferUp, dataOut, nbSamples);
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) samplerate2 / samplerate1;
int nbSamplesMax = (int) (samplerate1 * 20 / 1000); // TODO get the value from somewhere
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 = _floatBufferUp;
src_data.data_out = _floatBufferDown;
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
src_short_to_float_array(dataIn, _floatBufferUp, nbSamples);
//_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( "return %i samples\n" , nbSamples );
src_float_to_short_array(_floatBufferDown, dataOut, nbSamples);
_debug("Begin downsample data\n");
//_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;
}
......@@ -23,11 +23,13 @@
#include <math.h>
#include "global.h"
#include "manager.h"
class SamplerateConverter {
public:
/** Constructor */
SamplerateConverter( void );
SamplerateConverter( int freq , int fs );
/** Destructor */
~SamplerateConverter( void );
......@@ -51,19 +53,28 @@ class SamplerateConverter {
*/
int downsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples );
private:
/** Downsampled float buffer */
float32* _floatBufferDown;
int getFrequence( void ) { return _frequence; }
/** Upsampled float buffer */
float32* _floatBufferUp;
int getFramesize( void ) { return _framesize; }
/** libSamplerateConverter converter for incoming voice */
SRC_STATE* _src_state_spkr;
private:
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 */