diff --git a/src/audio/audiolayer.cpp b/src/audio/audiolayer.cpp
index 7754a34c737b78f3a2c396197d839b1d13e53e51..45924b2c5c39212be8f48abfc66462e3ee729a4a 100644
--- a/src/audio/audiolayer.cpp
+++ b/src/audio/audiolayer.cpp
@@ -2,10 +2,11 @@
  *  Copyright (C) 2005 Savoir-Faire Linux inc.
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
  *  Author: Jerome Oufella <jerome.oufella@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
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
@@ -108,13 +109,15 @@ AudioLayer::hasStream(void) {
 
 
 void
-AudioLayer::openDevice (int indexIn, int indexOut, int sampleRate) 
+AudioLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize) 
 {
   closeStream();
 
   _sampleRate = sampleRate;
-
+  _frameSize = frameSize;	
   int portaudioFramePerBuffer = FRAME_PER_BUFFER; //=FRAME_PER_BUFFER; //= paFramesPerBufferUnspecified;
+  //int portaudioFramePerBuffer = (int) (8000 * frameSize / 1000); 
+//= paFramesPerBufferUnspecified;
 
   int nbDevice = getDeviceCount();
   if (nbDevice == 0) {
diff --git a/src/audio/audiolayer.h b/src/audio/audiolayer.h
index 3c45ed0bb8e71bd7ee082d87cc4b55c21d89e6ff..548ef197930a17bc7b7bccf6ea2744fe26eff3b4 100644
--- a/src/audio/audiolayer.h
+++ b/src/audio/audiolayer.h
@@ -2,10 +2,11 @@
  *  Copyright (C) 2004-2005 Savoir-Faire Linux inc.
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
  *  Author:  Jerome Oufella <jerome.oufella@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
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *                                                                              
  *  This program is distributed in the hope that it will be useful,
@@ -35,96 +36,103 @@ class RingBuffer;
 class ManagerImpl;
 
 class AudioLayer {
-public:
-  AudioLayer(ManagerImpl* manager);
-  ~AudioLayer(void);
- 
-  /*
-   * @param indexIn
-   * @param indexOut
-   * @param sampleRate
-   */
-  void openDevice(int, int, int);
-  void startStream(void);
-  void stopStream(void);
-  void sleep(int);
-  bool hasStream(void);
-  bool isStreamActive(void);
-  bool isStreamStopped(void);
-
-  void flushMain();
-  int putMain(void* buffer, int toCopy);
-  int putUrgent(void* buffer, int toCopy);
-  int canGetMic();
-  int getMic(void *, int);
-  void flushMic();
-
-  int audioCallback (const void *, void *, unsigned long,
-        const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
-  int miniAudioCallback (const void *, void *, unsigned long,
-        const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
-
-  void setErrorMessage(const std::string& error) { _errorMessage = error; }
-  std::string getErrorMessage() { return _errorMessage; }
-
-  /**
-   * Get the sample rate of audiolayer
-   * accessor only
-   */
-  unsigned int getSampleRate() { return _sampleRate; }
-
-  int getDeviceCount();
-  AudioDevice* getAudioDeviceInfo(int index, int ioDeviceMask);
-
-  enum IODEVICE {InputDevice=0x01, OutputDevice=0x02 };
-
-  /**
-   * Toggle echo testing on/off
-   */
-  void toggleEchoTesting();
-
-private:
-  void closeStream (void);
-  RingBuffer _urgentRingBuffer;
-  RingBuffer _mainSndRingBuffer;
-  RingBuffer _micRingBuffer;
-  ManagerImpl* _manager; // augment coupling, reduce indirect access
-                        // a audiolayer can't live without manager
-
-  portaudio::MemFunCallbackStream<AudioLayer> *_stream;
-
-  /**
-   * Sample Rate of SFLphone : should be 8000 for 8khz
-   * Added because we could change it in the futur
-   */
-  unsigned int _sampleRate;
-
-  /**
-   * Input channel (mic) should be 1 mono
-   */
-  unsigned int _inChannel; // mic
-
-  /**
-   * Output channel (stereo) should be 1 mono
-   */
-  unsigned int _outChannel; // speaker
-
-  /**
-   * Default volume for incoming RTP and Urgent sounds.
-   */
-  unsigned short _defaultVolume; // 100
-
-  /**
-   * Echo testing or not
-   */
-  bool _echoTesting;
-
-  std::string _errorMessage;
-  ost::Mutex _mutex;
-
-  float *table_;
-  int tableSize_;
-  int leftPhase_;
+	public:
+		AudioLayer(ManagerImpl* manager);
+		~AudioLayer(void);
+
+		/*
+		 * @param indexIn
+		 * @param indexOut
+		 * @param sampleRate
+		 * @param frameSize
+		 */
+		void openDevice(int, int, int, int);
+		void startStream(void);
+		void stopStream(void);
+		void sleep(int);
+		bool hasStream(void);
+		bool isStreamActive(void);
+		bool isStreamStopped(void);
+
+		void flushMain();
+		int putMain(void* buffer, int toCopy);
+		int putUrgent(void* buffer, int toCopy);
+		int canGetMic();
+		int getMic(void *, int);
+		void flushMic();
+
+		int audioCallback (const void *, void *, unsigned long,
+				const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
+		int miniAudioCallback (const void *, void *, unsigned long,
+				const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags);
+
+		void setErrorMessage(const std::string& error) { _errorMessage = error; }
+		std::string getErrorMessage() { return _errorMessage; }
+
+		/**
+		 * Get the sample rate of audiolayer
+		 * accessor only
+		 */
+		unsigned int getSampleRate() { return _sampleRate; }
+		unsigned int getFrameSize() { return _frameSize; }
+		int getDeviceCount();
+		AudioDevice* getAudioDeviceInfo(int index, int ioDeviceMask);
+
+		enum IODEVICE {InputDevice=0x01, OutputDevice=0x02 };
+
+		/**
+		 * Toggle echo testing on/off
+		 */
+		void toggleEchoTesting();
+
+	private:
+		void closeStream (void);
+		RingBuffer _urgentRingBuffer;
+		RingBuffer _mainSndRingBuffer;
+		RingBuffer _micRingBuffer;
+		ManagerImpl* _manager; // augment coupling, reduce indirect access
+		// a audiolayer can't live without manager
+
+		portaudio::MemFunCallbackStream<AudioLayer> *_stream;
+
+		/**
+		 * Sample Rate SFLphone should send sound data to the sound card 
+		 * The value can be set in the user config file- now: 44100HZ
+		 */
+		unsigned int _sampleRate;
+		
+		/**
+ 		 * Length of the sound frame we capture or read in ms
+ 		 * The value can be set in the user config file - now: 20ms
+ 		 */	 		
+		unsigned int _frameSize;
+		
+		/**
+		 * Input channel (mic) should be 1 mono
+		 */
+		unsigned int _inChannel; // mic
+
+		/**
+		 * Output channel (stereo) should be 1 mono
+		 */
+		unsigned int _outChannel; // speaker
+
+		/**
+		 * Default volume for incoming RTP and Urgent sounds.
+		 */
+		unsigned short _defaultVolume; // 100
+
+		/**
+		 * Echo testing or not
+		 */
+		bool _echoTesting;
+
+		std::string _errorMessage;
+		ost::Mutex _mutex;
+
+		float *table_;
+		int tableSize_;
+		int leftPhase_;
 };
 
 #endif // _AUDIO_LAYER_H_
diff --git a/src/audio/audiortp.cpp b/src/audio/audiortp.cpp
index fe6f0833a0d255cee8befe522f04861f1c0ca64b..53efa0962dd9fa11271441c6e17d01c71eb8f304 100644
--- a/src/audio/audiortp.cpp
+++ b/src/audio/audiortp.cpp
@@ -1,12 +1,13 @@
 /*
  *  Copyright (C) 2004-2007 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: Laurielle Lea <laurielle.lea@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
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
@@ -44,476 +45,478 @@
 ////////////////////////////////////////////////////////////////////////////////
 AudioRtp::AudioRtp ()
 {
-  _RTXThread = 0;
+	_RTXThread = 0;
 }
 
 AudioRtp::~AudioRtp (void) {
-  delete _RTXThread; _RTXThread = 0;
+	delete _RTXThread; _RTXThread = 0;
 }
 
 int 
 AudioRtp::createNewSession (SIPCall *ca) {
-  ost::MutexLock m(_threadMutex);
-
-  // something should stop the thread before...
-  if ( _RTXThread != 0 ) { 
-    _debug("! ARTP Failure: Thread already exists..., stopping it\n");
-    delete _RTXThread; _RTXThread = 0;
-    //return -1; 
-  }
-
-  // Start RTP Send/Receive threads
-  _symmetric = Manager::instance().getConfigInt(SIGNALISATION,SYMMETRIC) ? true : false;
-  _RTXThread = new AudioRtpRTX (ca, _symmetric);
-
-  try {
-    if (_RTXThread->start() != 0) {
-      _debug("! ARTP Failure: unable to start RTX Thread\n");
-      return -1;
-    }
-  } catch(...) {
-    _debugException("! ARTP Failure: when trying to start a thread");
-    throw;
-  }
-  return 0;
+	ost::MutexLock m(_threadMutex);
+
+	// something should stop the thread before...
+	if ( _RTXThread != 0 ) { 
+		_debug("! ARTP Failure: Thread already exists..., stopping it\n");
+		delete _RTXThread; _RTXThread = 0;
+		//return -1; 
+	}
+
+	// Start RTP Send/Receive threads
+	_symmetric = Manager::instance().getConfigInt(SIGNALISATION,SYMMETRIC) ? true : false;
+	_RTXThread = new AudioRtpRTX (ca, _symmetric);
+
+	try {
+		if (_RTXThread->start() != 0) {
+			_debug("! ARTP Failure: unable to start RTX Thread\n");
+			return -1;
+		}
+	} catch(...) {
+		_debugException("! ARTP Failure: when trying to start a thread");
+		throw;
+	}
+	return 0;
 }
 
-	
+
 void
 AudioRtp::closeRtpSession () {
-  ost::MutexLock m(_threadMutex);
-  // This will make RTP threads finish.
-  // _debug("Stopping AudioRTP\n");
-  try {
-    delete _RTXThread; _RTXThread = 0;
-  } catch(...) {
-    _debugException("! ARTP Exception: when stopping audiortp\n");
-    throw;
-  }
+	ost::MutexLock m(_threadMutex);
+	// This will make RTP threads finish.
+	// _debug("Stopping AudioRTP\n");
+	try {
+		delete _RTXThread; _RTXThread = 0;
+	} catch(...) {
+		_debugException("! ARTP Exception: when stopping audiortp\n");
+		throw;
+	}
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AudioRtpRTX Class                                                          //
 ////////////////////////////////////////////////////////////////////////////////
 AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym)
-  // : _fstream("/tmp/audio.dat", std::ofstream::binary)
- {
-  setCancel(cancelDeferred);
-  time = new ost::Time();
-  _ca = sipcall;
-  _sym = sym;
-  // AudioRtpRTX should be close if we change sample rate
-
-  _receiveDataDecoded = new int16[RTP_20S_48KHZ_MAX];
-  _sendDataEncoded   =  new unsigned char[RTP_20S_8KHZ_MAX];
-
-  // we estimate that the number of format after a conversion 8000->48000 is expanded to 6 times
-  _dataAudioLayer = new SFLDataFormat[RTP_20S_48KHZ_MAX];
-  _floatBuffer8000  = new float32[RTP_20S_8KHZ_MAX];
-  _floatBuffer48000 = new float32[RTP_20S_48KHZ_MAX];
-  _intBuffer8000  = new int16[RTP_20S_8KHZ_MAX];
-
-  // 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();
-  ost::InetHostAddress local_ip(localipConfig.c_str());
-
-  if (!_sym) {
-    _sessionRecv = new ost::RTPSession(local_ip, _ca->getLocalAudioPort());
-    _sessionSend = new ost::RTPSession(local_ip, _ca->getLocalAudioPort());
-    _session = NULL;
-  } else {
-    _session = new ost::SymmetricRTPSession (local_ip, _ca->getLocalAudioPort());
-    _sessionRecv = NULL;
-    _sessionSend = NULL;
-  }
-
-  // libsamplerate-related
-  _src_state_mic  = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
-  _src_state_spkr = src_new(SRC_SINC_BEST_QUALITY, 1, &_src_err);
-  
+	// : _fstream("/tmp/audio.dat", std::ofstream::binary)
+{
+	setCancel(cancelDeferred);
+	time = new ost::Time();
+	_ca = sipcall;
+	_sym = sym;
+	// AudioRtpRTX should be close if we change sample rate
+
+	_codecSampleRate = _ca->getAudioCodec()->getClockRate();
+	
+	// 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();
+	ost::InetHostAddress local_ip(localipConfig.c_str());
+
+	if (!_sym) {
+		_sessionRecv = new ost::RTPSession(local_ip, _ca->getLocalAudioPort());
+		_sessionSend = new ost::RTPSession(local_ip, _ca->getLocalAudioPort());
+		_session = NULL;
+	} else {
+		_session = new ost::SymmetricRTPSession (local_ip, _ca->getLocalAudioPort());
+		_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 () {
-  _start.wait();
-
-  try {
-    this->terminate();
-  } catch(...) {
-    _debugException("! ARTP: Thread destructor didn't terminate correctly");
-    throw;
-  }
-  //_debug("terminate audiortprtx ended...\n");
-  _ca = 0;
-
-  if (!_sym) {
-    delete _sessionRecv; _sessionRecv = NULL;
-    delete _sessionSend; _sessionSend = NULL;
-  } else {
-    delete _session;     _session = NULL;
-  }
-
-  delete [] _intBuffer8000; _intBuffer8000 = NULL;
-  delete [] _floatBuffer48000; _floatBuffer48000 = NULL;
-  delete [] _floatBuffer8000; _floatBuffer8000 = NULL;
-  delete [] _dataAudioLayer; _dataAudioLayer = NULL;
-
-  delete [] _sendDataEncoded; _sendDataEncoded = NULL;
-  delete [] _receiveDataDecoded; _receiveDataDecoded = NULL;
-
-  delete time; time = NULL;
-
-  // libsamplerate-related
-  _src_state_mic  = src_delete(_src_state_mic);
-  _src_state_spkr = src_delete(_src_state_spkr);
+	_start.wait();
+
+	try {
+		this->terminate();
+	} catch(...) {
+		_debugException("! ARTP: Thread destructor didn't terminate correctly");
+		throw;
+	}
+	//_debug("terminate audiortprtx ended...\n");
+	_ca = 0;
+
+	if (!_sym) {
+		delete _sessionRecv; _sessionRecv = NULL;
+		delete _sessionSend; _sessionSend = NULL;
+	} else {
+		delete _session;     _session = NULL;
+	}
+
+	delete [] _intBufferDown; _intBufferDown = NULL;
+	delete [] _floatBufferUp; _floatBufferUp = NULL;
+	delete [] _floatBufferDown; _floatBufferDown = NULL;
+	delete [] _dataAudioLayer; _dataAudioLayer = NULL;
+
+	delete [] _sendDataEncoded; _sendDataEncoded = NULL;
+	delete [] _receiveDataDecoded; _receiveDataDecoded = 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::initAudioRtpSession (void) 
+	void
+AudioRtpRTX::initBuffers()
 {
-  try {
-    if (_ca == 0) { return; }
-
-    //_debug("Init audio RTP session\n");
-    ost::InetHostAddress remote_ip(_ca->getRemoteIp().c_str());
-    if (!remote_ip) {
-      _debug("! ARTP Thread Error: Target IP address [%s] is not correct!\n", _ca->getRemoteIp().data());
-      return;
-    }
-
-    // Initialization
-    if (!_sym) {
-      _sessionRecv->setSchedulingTimeout (10000);
-      _sessionRecv->setExpireTimeout(1000000);
-
-      _sessionSend->setSchedulingTimeout(10000);
-      _sessionSend->setExpireTimeout(1000000);
-    } else {
-      _session->setSchedulingTimeout(10000);
-      _session->setExpireTimeout(1000000);
-    }
-
-    if (!_sym) {
-      if ( !_sessionRecv->addDestination(remote_ip, (unsigned short) _ca->getRemoteAudioPort()) ) {
-        _debug("AudioRTP Thread Error: could not connect to port %d\n",  _ca->getRemoteAudioPort());
-        return;
-      }
-      if (!_sessionSend->addDestination (remote_ip, (unsigned short) _ca->getRemoteAudioPort())) {
-        _debug("! ARTP Thread Error: could not connect to port %d\n",  _ca->getRemoteAudioPort());
-        return;
-      }
-
-      AudioCodec* audiocodec = _ca->getAudioCodec();
-      bool payloadIsSet = false;
-      if (audiocodec) {
-        if (audiocodec->hasDynamicPayload()) {
-          payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate()));
-        } else {
-          payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
-          payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
-        }
-      }
-      _sessionSend->setMark(true);
-    } else {
-
-      //_debug("AudioRTP Thread: Added session destination %s:%d\n", remote_ip.getHostname(), (unsigned short) _ca->getRemoteSdpAudioPort());
-
-      if (!_session->addDestination (remote_ip, (unsigned short) _ca->getRemoteAudioPort())) {
-        return;
-      }
-
-      AudioCodec* audiocodec = _ca->getAudioCodec();
-      bool payloadIsSet = false;
-      if (audiocodec) {
-        if (audiocodec->hasDynamicPayload()) {
-          payloadIsSet = _session->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate()));
-        } else {
-          payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
-        }
-      }
-    }
-  } catch(...) {
-    _debugException("! ARTP Failure: initialisation failed");
-    throw;
-  }
+	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];
 }
 
+	void
+AudioRtpRTX::initAudioRtpSession (void) 
+{
+	try {
+		if (_ca == 0) { return; }
+
+		//_debug("Init audio RTP session\n");
+		ost::InetHostAddress remote_ip(_ca->getRemoteIp().c_str());
+		if (!remote_ip) {
+			_debug("! ARTP Thread Error: Target IP address [%s] is not correct!\n", _ca->getRemoteIp().data());
+			return;
+		}
+
+		// Initialization
+		if (!_sym) {
+			_sessionRecv->setSchedulingTimeout (10000);
+			_sessionRecv->setExpireTimeout(1000000);
+
+			_sessionSend->setSchedulingTimeout(10000);
+			_sessionSend->setExpireTimeout(1000000);
+		} else {
+			_session->setSchedulingTimeout(10000);
+			_session->setExpireTimeout(1000000);
+		}
+
+		if (!_sym) {
+			if ( !_sessionRecv->addDestination(remote_ip, (unsigned short) _ca->getRemoteAudioPort()) ) {
+				_debug("AudioRTP Thread Error: could not connect to port %d\n",  _ca->getRemoteAudioPort());
+				return;
+			}
+			if (!_sessionSend->addDestination (remote_ip, (unsigned short) _ca->getRemoteAudioPort())) {
+				_debug("! ARTP Thread Error: could not connect to port %d\n",  _ca->getRemoteAudioPort());
+				return;
+			}
+
+			AudioCodec* audiocodec = _ca->getAudioCodec();
+			bool payloadIsSet = false;
+			if (audiocodec) {
+				if (audiocodec->hasDynamicPayload()) {
+					payloadIsSet = _sessionRecv->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate()));
+				} else {
+					payloadIsSet= _sessionRecv->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
+					payloadIsSet = _sessionSend->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
+				}
+			}
+			_sessionSend->setMark(true);
+		} else {
+
+			//_debug("AudioRTP Thread: Added session destination %s:%d\n", remote_ip.getHostname(), (unsigned short) _ca->getRemoteSdpAudioPort());
+
+			if (!_session->addDestination (remote_ip, (unsigned short) _ca->getRemoteAudioPort())) {
+				return;
+			}
+
+			AudioCodec* audiocodec = _ca->getAudioCodec();
+			bool payloadIsSet = false;
+			if (audiocodec) {
+				if (audiocodec->hasDynamicPayload()) {
+					payloadIsSet = _session->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) audiocodec->getPayload(), audiocodec->getClockRate()));
+				} else {
+					payloadIsSet = _session->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) audiocodec->getPayload()));
+				}
+			}
+		}
+	} catch(...) {
+		_debugException("! ARTP Failure: initialisation failed");
+		throw;
+	}
+}
+	
 void
 AudioRtpRTX::sendSessionFromMic(int timestamp)
 {
-  // STEP:
-  //   1. get data from mic
-  //   2. convert it to int16 - good sample, good rate
-  //   3. encode it
-  //   4. send it
-  try {
-    timestamp += time->getSecond();
-    if (_ca==0) { _debug(" !ARTP: No call associated (mic)\n"); return; } // no call, so we do nothing
-    AudioLayer* audiolayer = Manager::instance().getAudioDriver();
-    if (!audiolayer) { _debug(" !ARTP: No audiolayer available for mic\n"); return; }
-
-    AudioCodec* audiocodec = _ca->getAudioCodec();
-    if (!audiocodec) { _debug(" !ARTP: No audiocodec available for mic\n"); return; }
-
-    // we have to get 20ms of data from the mic *20/1000 = /50
-    // rate/50 shall be lower than RTP_20S_48KHZ_MAX
-    int maxBytesToGet = audiolayer->getSampleRate()/50*sizeof(SFLDataFormat);
-
-    // available bytes inside ringbuffer
-    int availBytesFromMic = audiolayer->canGetMic();
-
-    // take the lowest
-    int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;
-    //_debug("available = %d, maxBytesToGet = %d\n", availBytesFromMic, maxBytesToGet);
-
-    // Get bytes from micRingBuffer to data_from_mic
-    int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat);
-
-    int16* toSIP = NULL;
-    if (audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) {
-       SRC_DATA src_data;
-       #ifdef DATAFORMAT_IS_FLOAT   
-          src_data.data_in = _dataAudioLayer;
-       #else
-          src_short_to_float_array(_dataAudioLayer, _floatBuffer48000, nbSample);
-          src_data.data_in = _floatBuffer48000; 
-       #endif
-
-       double factord = (double) audiocodec->getClockRate() / audiolayer->getSampleRate();
-
-       src_data.src_ratio = factord;
-       src_data.input_frames = nbSample;
-       src_data.output_frames = (int) floor(factord * nbSample);
-       src_data.data_out = _floatBuffer8000;
-       src_data.end_of_input = 0; /* More data to come */
-
-       src_process(_src_state_mic, &src_data);
-
-       nbSample = src_data.output_frames_gen;
-
-       /* WRITE IN A FILE FOR DEBUG */
-       //_fstream.write((char *) _floatBuffer48000, src_data.output_frames_gen * sizeof(float));
-       //_fstream.flush();
-
-
-       //if (nbSample > RTP_20S_8KHZ_MAX) { _debug("Alert from mic, nbSample %d is bigger than expected %d\n", nbSample, RTP_20S_8KHZ_MAX); }
-
-       src_float_to_short_array (_floatBuffer8000, _intBuffer8000, nbSample);
-       toSIP = _intBuffer8000;
-    } else {
-      #ifdef DATAFORMAT_IS_FLOAT
-        // convert _receiveDataDecoded to float inside _receiveData
-        src_float_to_short_array(_dataAudioLayer, _intBuffer8000, nbSample);
-        toSIP = _intBuffer8000;
-       //if (nbSample > RTP_20S_8KHZ_MAX) { _debug("Alert from mic, nbSample %d is bigger than expected %d\n", nbSample, RTP_20S_8KHZ_MAX); }
-      #else
-        toSIP = _dataAudioLayer; // int to int
-      #endif
-    }
-
-    if ( nbSample < (RTP_20S_8KHZ_MAX - 10) ) { // if only 10 is missing, it's ok
-      // fill end with 0...
-      //_debug("begin: %p, nbSample: %d\n", toSIP, nbSample);
-      //_debug("has to fill: %d chars at %p\n", (RTP_20S_8KHZ_MAX-nbSample)*sizeof(int16), toSIP + nbSample);
-      memset(toSIP + nbSample, 0, (RTP_20S_8KHZ_MAX-nbSample)*sizeof(int16));
-      nbSample = RTP_20S_8KHZ_MAX;
-    }
-    //_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));
-
-    // encode divise by two
-    // Send encoded audio sample over the network
-    if (compSize > RTP_20S_8KHZ_MAX) { _debug("! ARTP: %d should be %d\n", compSize, RTP_20S_8KHZ_MAX);}
-    if (!_sym) {
-      _sessionSend->putData(timestamp, _sendDataEncoded, compSize);
-    } else {
-      _session->putData(timestamp, _sendDataEncoded, compSize);
-    }
-    toSIP = NULL;
-  } catch(...) {
-    _debugException("! ARTP: sending failed");
-    throw;
-  }
+	// STEP:
+	//   1. get data from mic
+	//   2. convert it to int16 - good sample, good rate
+	//   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
+		AudioLayer* audiolayer = Manager::instance().getAudioDriver();
+		if (!audiolayer) { _debug(" !ARTP: No audiolayer available for mic\n"); return; }
+
+		AudioCodec* audiocodec = _ca->getAudioCodec();
+		if (!audiocodec) { _debug(" !ARTP: No audiocodec available for mic\n"); return; }
+
+		// we have to get 20ms of data from the mic *20/1000 = /50
+		int maxBytesToGet = _layerSampleRate * _layerFrameSize * sizeof(SFLDataFormat) / 1000;
+
+		// available bytes inside ringbuffer
+		int availBytesFromMic = audiolayer->canGetMic();
+
+		// take the lowest
+		int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;
+
+		// Get bytes from micRingBuffer to data_from_mic
+		int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat);
+		int nb_sample_up = nbSample;
+		int nbSamplesMax = _layerFrameSize * audiocodec->getClockRate() / 1000;
+		
+		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));
+			nbSample = nbSamplesMax;
+		}
+		//_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));
+
+		// 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);
+		} else {
+			_session->putData(timestamp, _sendDataEncoded, compSize);
+		}
+		toSIP = NULL;
+	} catch(...) {
+		_debugException("! ARTP: sending failed");
+		throw;
+	}
 
 }
 
-void
+
+
+	void
 AudioRtpRTX::receiveSessionForSpkr (int& countTime)
 {
-  if (_ca == 0) { return; }
-  try {
-    AudioLayer* audiolayer = Manager::instance().getAudioDriver();
-    if (!audiolayer) { return; }
-
-    const ost::AppDataUnit* adu = NULL;
-    // Get audio data stream
-
-    if (!_sym) {
-      adu = _sessionRecv->getData(_sessionRecv->getFirstTimestamp());
-    } else {
-      adu = _session->getData(_session->getFirstTimestamp());
-    }
-    if (adu == NULL) {
-      return;
-    }
-
-    int payload = adu->getType(); // codec type
-    unsigned char* data  = (unsigned char*)adu->getData(); // data in char
-    unsigned int size    = adu->getSize(); // size in char
-
-    if ( size > RTP_20S_8KHZ_MAX ) {
-      _debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, RTP_20S_8KHZ_MAX);
-      _debug("The packet size has been cropped\n");
-      size=RTP_20S_8KHZ_MAX;
-    }
-
-    // NOTE: L'audio rendu ici (dans data/size) est parfait.
-
-    // Decode data with relevant codec
-    AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload);
-    if (audiocodec != NULL) {
-      // codecDecode(int16 *dest, char* src, size in bytes of the src)
-      // decode multiply by two, so the number of byte should be double
-      // size shall be RTP_FRAME2SEND or lower
-      int expandedSize = audiocodec->codecDecode(_receiveDataDecoded, data, size);
-      int nbInt16      = expandedSize / sizeof(int16);
-      if (nbInt16 > RTP_20S_8KHZ_MAX) {
-        _debug("We have decoded an RTP packet larger than expected: %s VS %s. Cropping.\n", nbInt16, RTP_20S_8KHZ_MAX);
-        nbInt16=RTP_20S_8KHZ_MAX;
-      }
-
-      // NOTE: l'audio arrivé ici (dans _receiveDataDecoded/expandedSize) est parfait.
-
-      SFLDataFormat* toAudioLayer;
-      int nbSample = nbInt16;
-      // 48000 / 8000 = 6, the number of samples for the maximum rate conversion.
-      int nbSampleMaxRate = nbInt16 * 6; // TODO: change it
-
-      // We assume over here that we pass from a lower rate to a higher one. Bad bad.
-      if ( audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) {
-        // Do sample rate conversion
-
-        double factord = (double) audiolayer->getSampleRate() / audiocodec->getClockRate();
-
-	// SRC_DATA from samplerate.h
-        SRC_DATA src_data;
-        src_data.data_in = _floatBuffer8000;
-        src_data.data_out = _floatBuffer48000;
-        src_data.input_frames = nbSample;
-        src_data.output_frames = (int) floor(factord * nbSample);
-        src_data.src_ratio = factord;
-	src_data.end_of_input = 0; /* More data will come */
-        src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);
-
-	// NOTE: L'audio arrivé ici (dans _floatBuffer8000/nbSample*sizeof(float) est parfait.
-
-	src_process(_src_state_spkr, &src_data);
-
-	// Truncate number of samples if too high (ouch!)
-        nbSample = ( src_data.output_frames_gen > RTP_20S_48KHZ_MAX) ? RTP_20S_48KHZ_MAX : src_data.output_frames_gen;
-
-        #ifdef DATAFORMAT_IS_FLOAT
-          toAudioLayer = _floatBuffer48000;
-	#else
-          src_float_to_short_array(_floatBuffer48000, _dataAudioLayer, nbSample);
-	  toAudioLayer = _dataAudioLayer;
-	#endif
+	if (_ca == 0) { return; }
+	try {
+		AudioLayer* audiolayer = Manager::instance().getAudioDriver();
+		if (!audiolayer) { return; }
+
+		const ost::AppDataUnit* adu = NULL;
+		// Get audio data stream
+
+		if (!_sym) {
+			adu = _sessionRecv->getData(_sessionRecv->getFirstTimestamp());
+		} else {
+			adu = _session->getData(_session->getFirstTimestamp());
+		}
+		if (adu == NULL) {
+			return;
+		}
+
+		int payload = adu->getType(); // codec type
+		unsigned char* data  = (unsigned char*)adu->getData(); // data in char
+		unsigned int size    = adu->getSize(); // size in char
+		  
+
+		// Decode data with relevant codec
+		AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload);
+		_codecSampleRate = audiocodec->getClockRate();
+		int max = (int)(_codecSampleRate * _layerFrameSize);
+
+		if ( size > max ) {
+                        _debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, max);
+                        _debug("The packet size has been cropped\n");
+                        size=max;
+                }
+
+
+		if (audiocodec != NULL) {
+			int expandedSize = audiocodec->codecDecode(_receiveDataDecoded, data, 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
+			if (nbInt16 > max) {
+				_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->putMain(toAudioLayer, nbSample * sizeof(SFLDataFormat));
+
+			// Notify (with a beep) an incoming call when there is already a call 
+			countTime += time->getSecond();
+			if (Manager::instance().incomingCallWaiting() > 0) {
+				countTime = countTime % 500; // more often...
+				if (countTime == 0) {
+					Manager::instance().notificationIncomingCall();
+				}
+			}
+
+		} else {
+			countTime += time->getSecond();
+		}
+
+		delete adu; adu = NULL;
+	} catch(...) {
+		_debugException("! ARTP: receiving failed");
+		throw;
+	}
+}
 
-	
-      } else {
-        nbSample = nbInt16;
-        #ifdef DATAFORMAT_IS_FLOAT
-      	  // convert _receiveDataDecoded to float inside _receiveData
-          src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);
-	  toAudioLayer = _floatBuffer8000;
-        #else
-	  toAudioLayer = _receiveDataDecoded; // int to int
-        #endif
-      }
-
-      audiolayer->putMain(toAudioLayer, nbSample * sizeof(SFLDataFormat));
-      //_debug("ARTP: %d\n", nbSample * sizeof(SFLDataFormat));
-
-      // Notify (with a beep) an incoming call when there is already a call 
-      countTime += time->getSecond();
-      if (Manager::instance().incomingCallWaiting() > 0) {
-        countTime = countTime % 500; // more often...
-        if (countTime == 0) {
-          Manager::instance().notificationIncomingCall();
-        }
-      }
-
-    } else {
-      countTime += time->getSecond();
-    }
-
-    delete adu; adu = NULL;
-  } catch(...) {
-    _debugException("! ARTP: receiving failed");
-    throw;
-  }
+int 
+AudioRtpRTX::reSampleData(int sampleRate_codec, int nbSamples, int status)
+{
+	if(status==UP_SAMPLING)
+		return upSampleData(sampleRate_codec, nbSamples);
+	else if(status==DOWN_SAMPLING)
+		return downSampleData(sampleRate_codec, 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();
-
-  try {
-    // Init the session
-    initAudioRtpSession();
-
-    // start running the packet queue scheduler.
-    //_debug("AudioRTP Thread started\n");
-    if (!_sym) {
-      _sessionRecv->startRunning();
-      _sessionSend->startRunning();
-    } else {
-      _session->startRunning();
-      //_debug("Session is now: %d active\n", _session->isActive());
-    }
-
-    int timestamp = 0; // for mic
-    int countTime = 0; // for receive
-    // TODO: get frameSize from user config 
-    int frameSize = 20; // 20ms frames
-    TimerPort::setTimer(frameSize);
-
-    audiolayer->flushMic();
-    audiolayer->startStream();
-    _start.post();
-    _debug("- ARTP Action: Start\n");
-    while (!testCancel()) {
-      ////////////////////////////
-      // Send session
-      ////////////////////////////
-      sendSessionFromMic(timestamp);
-      timestamp += RTP_20S_8KHZ_MAX;
-
-      ////////////////////////////
-      // Recv session
-      ////////////////////////////
-      receiveSessionForSpkr(countTime);
-
-      // Let's wait for the next transmit cycle
-      Thread::sleep(TimerPort::getTimer());
-      TimerPort::incTimer(frameSize); // 'frameSize' ms
-    }
-    //_debug("stop stream for audiortp loop\n");
-    audiolayer->stopStream();
-  } catch(std::exception &e) {
-    _start.post();
-    _debug("! ARTP: Stop %s\n", e.what());
-    throw;
-  } catch(...) {
-    _start.post();
-    _debugException("* ARTP Action: Stop");
-    throw;
-  }
+	//mic, we receive from soundcard in stereo, and we send encoded
+	//encoding before sending
+	AudioLayer *audiolayer = Manager::instance().getAudioDriver();
+
+	_layerFrameSize = audiolayer->getFrameSize(); // en ms
+	_layerSampleRate = audiolayer->getSampleRate();	
+	initBuffers();
+	int step = (int)(_layerFrameSize * _codecSampleRate / 1000);
+
+	try {
+		// Init the session
+		initAudioRtpSession();
+
+		// start running the packet queue scheduler.
+		//_debug("AudioRTP Thread started\n");
+		if (!_sym) {
+			_sessionRecv->startRunning();
+			_sessionSend->startRunning();
+		} else {
+			_session->startRunning();
+			//_debug("Session is now: %d active\n", _session->isActive());
+		}
+
+		int timestamp = 0; // for mic
+		int countTime = 0; // for receive
+		TimerPort::setTimer(_layerFrameSize);
+
+		audiolayer->flushMic();
+		audiolayer->startStream();
+		_start.post();
+		_debug("- ARTP Action: Start\n");
+		while (!testCancel()) {
+			////////////////////////////
+			// Send session
+			////////////////////////////
+			sendSessionFromMic(timestamp);
+			timestamp += step;
+			////////////////////////////
+			// Recv session
+			////////////////////////////
+			receiveSessionForSpkr(countTime);
+
+			// Let's wait for the next transmit cycle
+			Thread::sleep(TimerPort::getTimer());
+			TimerPort::incTimer(_layerFrameSize); // 'frameSize' ms
+		}
+		//_debug("stop stream for audiortp loop\n");
+		audiolayer->stopStream();
+	} catch(std::exception &e) {
+		_start.post();
+		_debug("! ARTP: Stop %s\n", e.what());
+		throw;
+	} catch(...) {
+		_start.post();
+		_debugException("* ARTP Action: Stop");
+		throw;
+	}
 }
 
 
diff --git a/src/audio/audiortp.h b/src/audio/audiortp.h
index 4b018276929b5a2c63d95bcb79027a1ffc3c8580..2444be567611e17b4858ef8321baed96a7c91500 100644
--- a/src/audio/audiortp.h
+++ b/src/audio/audiortp.h
@@ -1,12 +1,13 @@
 /*
  *  Copyright (C) 2004-2007 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: Laurielle Lea <laurielle.lea@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
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -33,81 +34,108 @@
 
 #include "../global.h"
 
-/** maximum bytes inside an incoming packet 
- *  8000 sampling/s * 20s/1000 = 160
- */
-#define RTP_20S_8KHZ_MAX 160
-#define RTP_20S_48KHZ_MAX 960
+#define UP_SAMPLING 0
+#define DOWN_SAMPLING 1
+
+
 class SIPCall;
 
 ///////////////////////////////////////////////////////////////////////////////
 // Two pair of sockets
 ///////////////////////////////////////////////////////////////////////////////
 class AudioRtpRTX : public ost::Thread, public ost::TimerPort {
-public:
-	AudioRtpRTX (SIPCall *, bool);
-	~AudioRtpRTX();
-
-	ost::Time *time; 	// For incoming call notification 
-	virtual void run ();
-
-private:
-  SIPCall* _ca;
-  ost::RTPSession *_sessionSend;
-  ost::RTPSession *_sessionRecv;
-  ost::SymmetricRTPSession *_session;
-  ost::Semaphore _start;
-  bool _sym;
-
-  /** 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;
-
-  /** Debugging output file */
-  //std::ofstream _fstream;
-
-   /** 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;
-
-  void initAudioRtpSession(void);
-  void sendSessionFromMic(int);
-  void receiveSessionForSpkr(int&);
+	public:
+		AudioRtpRTX (SIPCall *, bool);
+		~AudioRtpRTX();
+
+		ost::Time *time; 	// For incoming call notification 
+		virtual void run ();
+
+	private:
+		SIPCall* _ca;
+		ost::RTPSession *_sessionSend;
+		ost::RTPSession *_sessionRecv;
+		ost::SymmetricRTPSession *_session;
+		ost::Semaphore _start;
+		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;
+		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;
+
+		/** Buffers used for sample rate conversion */
+		float32* _floatBufferDown;
+		float32* _floatBufferUp;
+
+		/** Debugging output file */
+		//std::ofstream _fstream;
+
+		/** 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;
+
+		// Variables to process audio stream
+		int _layerSampleRate;  // sample rate for playing sound (typically 44100HZ)
+		int _codecSampleRate; // sample rate of the codec we use to encode and decode (most of time 8000HZ)
+		int _layerFrameSize; // length of the sound frame we capture in ms(typically 20ms)
+
+		void initAudioRtpSession(void);
+		/**
+ 		 * Get the data from the mic, encode it and send it through the RTP session
+ 		 */ 		 	
+		void sendSessionFromMic(int);
+		/**
+ 		 * Get the data from the RTP packets, decode it and send it to the sound card
+ 		 */		 	
+		void receiveSessionForSpkr(int&);
+		/**
+ 		 * Init the buffers used for processing sound data
+ 		 */ 
+		void initBuffers(void);
+		/**
+ 		 * Call the appropriate function, up or downsampling
+ 		 */ 
+		int reSampleData(int, int ,int);
+		/**
+ 		 * Upsample the data from the clock rate of the codec to the sample rate of the layer
+ 		 * @param int The clock rate of the codec
+ 		 * @param int The number of samples we have in the buffer
+ 		 * @return int The number of samples after the operation
+ 		 */
+		int upSampleData(int, int);
+		/**
+ 		 * Downsample the data from the sample rate of the layer to the clock rate of the codec
+ 		 *  @param int The clock rate of the codec
+ 		 *  @param int The number of samples we have in the buffer 
+ 		 *  @return int The number of samples after the operation
+ 		 */
+		int downSampleData(int, int);
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 // Main class rtp
 ///////////////////////////////////////////////////////////////////////////////
 class AudioRtp {
-public:
-  AudioRtp();
-  ~AudioRtp();
+	public:
+		AudioRtp();
+		~AudioRtp();
 
-  int 			createNewSession (SIPCall *);
-  void			closeRtpSession	 ();
+		int 			createNewSession (SIPCall *);
+		void			closeRtpSession	 ();
 
-private:
-  AudioRtpRTX*	        _RTXThread;
-  bool			_symmetric;
-  ost::Mutex            _threadMutex;
+	private:
+		AudioRtpRTX*	        _RTXThread;
+		bool			_symmetric;
+		ost::Mutex            _threadMutex;
 };
 
 #endif // __AUDIO_RTP_H__
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index 0e92c0c9711f5953afcf2e193ad1e8def3230385..de29ed38b9968313c6eb80652b8edb6338132156 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -1050,7 +1050,8 @@ ManagerImpl::initConfigFile (void)
   //fill_config_int(DRIVER_NAME, DFT_DRIVER_STR);
   fill_config_int(DRIVER_NAME_IN, DFT_DRIVER_STR);
   fill_config_int(DRIVER_NAME_OUT, DFT_DRIVER_STR);
-  fill_config_int(DRIVER_SAMPLE_RATE, DRIVER_SAMPLE_RATE_DEFAULT);
+  fill_config_int(DRIVER_SAMPLE_RATE, DFT_SAMPLE_RATE);
+  fill_config_int(DRIVER_FRAME_SIZE, DFT_FRAME_SIZE);
   fill_config_str(CODEC1, DFT_CODEC);
   fill_config_str(CODEC2, DFT_CODEC);
   fill_config_str(CODEC3, DFT_CODEC);
@@ -1118,6 +1119,7 @@ ManagerImpl::selectAudioDriver (void)
   if (sampleRate <=0 || sampleRate > 48000) {
       sampleRate = 8000;
   }
+	int frameSize = getConfigInt(AUDIO, DRIVER_FRAME_SIZE);
 
   // this is when no audio device in/out are set
   // or the audio device in/out are set to 0
@@ -1128,7 +1130,7 @@ ManagerImpl::selectAudioDriver (void)
   //}
   _debugInit(" AudioLayer Opening Device");
   _audiodriver->setErrorMessage("");
-  _audiodriver->openDevice(noDeviceIn, noDeviceOut, sampleRate);
+  _audiodriver->openDevice(noDeviceIn, noDeviceOut, sampleRate, frameSize);
 }
 
 /**
@@ -1787,10 +1789,11 @@ ManagerImpl::removeAccount(const AccountID& accountID)
 std::string  
 ManagerImpl::getDefaultAccount()
 {
+	
 	std::string id;
 	id = getConfigString(PREFERENCES, "DefaultAccount");
 	_debug("Default Account = %s\n",id.c_str());	
-	return id; 
+	return id;
 }
 
 void
diff --git a/src/user_cfg.h b/src/user_cfg.h
index 0d9319d12b616a73abd31e8d5ff1594370a9219d..53e51cdd561df403ad334ae85bf76c3eb9f62b0a 100644
--- a/src/user_cfg.h
+++ b/src/user_cfg.h
@@ -62,7 +62,7 @@
 #define DRIVER_NAME_IN		"Drivers.driverNameIn"
 #define DRIVER_NAME_OUT		"Drivers.driverNameOut"
 #define DRIVER_SAMPLE_RATE      "Drivers.sampleRate"
-#define DRIVER_SAMPLE_RATE_DEFAULT "8000"
+#define DRIVER_FRAME_SIZE	"Drivers.framesize"
 #define NB_CODEC		"Codecs.nbCodec"
 #define CODEC1			"Codecs.codec1"
 #define CODEC2			"Codecs.codec2"
@@ -102,6 +102,8 @@
 #define DFT_SKIN 			"metal"
 #define DFT_ZONE			"North America"
 #define DFT_VOICEMAIL 		"888"
+#define DFT_FRAME_SIZE		"20"
+#define DFT_SAMPLE_RATE		"44100"
 // zeroconfig default value
 #ifdef USE_ZEROCONF
 #define CONFIG_ZEROCONF_DEFAULT_STR "1"