diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp
index a636de6840b6ca57b68e1fe6fe916f2c493313e0..a24aeef2e82c5fbb958560dc866ef4f5f1ff1f58 100644
--- a/sflphone-common/src/audio/alsa/alsalayer.cpp
+++ b/sflphone-common/src/audio/alsa/alsalayer.cpp
@@ -33,8 +33,6 @@
 
 #include "managerimpl.h"
 
-int framesPerBufferAlsa = 2048;
-
 // Constructor
 AlsaLayer::AlsaLayer (ManagerImpl* manager)
     : AudioLayer (manager , ALSA)
@@ -428,7 +426,7 @@ bool AlsaLayer::alsa_set_params (snd_pcm_t *pcm_handle, int type, int rate)
     /* Set sample rate. If we can't set to the desired exact value, we set to the nearest acceptable */
     dir=0;
 
-    rate = getSampleRate();
+    rate = _audioSampleRate;
 
     exact_ivalue = rate;
 
@@ -825,12 +823,12 @@ AlsaLayer::soundCardGetIndex (std::string description)
 void AlsaLayer::audioCallback (void)
 {
 
-    int toGet, urgentAvailBytes, normalAvailBytes;
+    int urgentAvailBytes;
     unsigned short spkrVolume, micVolume;
     AudioLoop *tone;
     AudioLoop *file_tone;
-
-    SFLDataFormat *out = NULL;
+    unsigned int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
+    bool resample = _audioSampleRate != _mainBufferSampleRate;
 
     notifyincomingCall();
 
@@ -853,119 +851,68 @@ void AlsaLayer::audioCallback (void)
     int playbackAvailBytes = playbackAvailSmpl*sizeof (SFLDataFormat);
 
     if (urgentAvailBytes > 0) {
-
         // Urgent data (dtmf, incoming call signal) come first.
-        toGet = (urgentAvailBytes < (int) (playbackAvailBytes)) ? urgentAvailBytes : playbackAvailBytes;
-        out = (SFLDataFormat*) malloc (toGet);
-        memset (out, 0, toGet);
-
-        if (out) {
-            _urgentRingBuffer.Get (out, toGet);
-            if (spkrVolume!=100)
-                for (int i=0; i<toGet / sizeof (SFLDataFormat); i++)
-                    out[i] = out[i] * spkrVolume / 100;
-
-            write (out, toGet, _PlaybackHandle);
-            free (out);
-        }
-
-        out=NULL;
-
+        int toGet = urgentAvailBytes;
+        if (toGet > playbackAvailBytes)
+			toGet = playbackAvailBytes;
+        SFLDataFormat *out = (SFLDataFormat*) malloc (toGet);
+		_urgentRingBuffer.Get (out, toGet);
+		if (spkrVolume != 100)
+			for (unsigned int i=0; i < toGet / sizeof (SFLDataFormat); i++)
+				out[i] = out[i] * spkrVolume / 100;
+
+		write (out, toGet, _PlaybackHandle);
+		free (out);
         // Consume the regular one as well (same amount of bytes)
         getMainBuffer()->discard (toGet);
-
     } else {
-
-        normalAvailBytes = getMainBuffer()->availForGet();
-
-        if (tone && (normalAvailBytes <= 0)) {
-
-            out = (SFLDataFormat *) malloc (playbackAvailBytes);
-            memset (out, 0, playbackAvailBytes);
-
-            if (out) {
-		_debug("Write tone (normal %d) (playbackAvail %d)", normalAvailBytes, playbackAvailBytes);
-                tone->getNext (out, playbackAvailSmpl, spkrVolume);
-                write (out , playbackAvailBytes, _PlaybackHandle);
-                free (out);
-            }
-
-            out = NULL;
-
-        } else if (file_tone && !_RingtoneHandle && (normalAvailBytes <= 0)) {
-
-            out = (SFLDataFormat *) malloc (playbackAvailBytes);
-            memset (out, 0, playbackAvailBytes);
-
-            if (out) {
-                file_tone->getNext (out, playbackAvailSmpl, spkrVolume);
-                write (out, playbackAvailBytes, _PlaybackHandle);
-                free (out);
-            }
-
-            out = NULL;
-
+    	// regular audio data
+        int toGet = getMainBuffer()->availForGet();
+
+        if (toGet <= 0) {
+        	// no audio available, play tone or silence
+			SFLDataFormat *out = (SFLDataFormat *) malloc (playbackAvailBytes);
+
+			if (tone)
+				tone->getNext (out, playbackAvailSmpl, spkrVolume);
+			else if (file_tone && !_RingtoneHandle)
+				file_tone->getNext (out, playbackAvailSmpl, spkrVolume);
+			else
+				memset(out, 0, playbackAvailBytes);
+
+            write (out, playbackAvailBytes, _PlaybackHandle);
+			free (out);
         } else {
-            // If nothing urgent, play the regular sound samples
+        	// play the regular sound samples
 
-            int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
-            int maxNbSamplesToGet = playbackAvailSmpl;
             int maxNbBytesToGet = playbackAvailBytes;
-
-            // Compute maximal value to get into the ring buffer
-
-            if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
-
-                double upsampleFactor = (double) _audioSampleRate / _mainBufferSampleRate;
-                maxNbSamplesToGet = (int) ( (double) playbackAvailSmpl  / upsampleFactor);
-                maxNbBytesToGet = maxNbSamplesToGet * sizeof (SFLDataFormat);
-
-            }
-
-            toGet = (normalAvailBytes < (int) maxNbBytesToGet) ? normalAvailBytes : maxNbBytesToGet;
-
-            out = (SFLDataFormat*) malloc (maxNbBytesToGet);
-            memset (out, 0, maxNbBytesToGet);
-
-            if (normalAvailBytes) {
-                getMainBuffer()->getData (out, toGet);
-                if (spkrVolume!=100)
-                    for (int i=0; i<toGet / sizeof (SFLDataFormat); i++)
-                        out[i] = out[i] * spkrVolume / 100;
-
-                if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
-                    SFLDataFormat *rsmpl_out = (SFLDataFormat*) malloc (playbackAvailBytes);
-					memset (out, 0, playbackAvailBytes);
-
-					_converter->resample ( (SFLDataFormat*) out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, toGet / sizeof (SFLDataFormat));
-					write (rsmpl_out, toGet, _PlaybackHandle);
-					free (rsmpl_out);
-
-                } else {
-
-                    write (out, toGet, _PlaybackHandle);
-
-                }
-            } else {
-
-                if (!tone && !file_tone) {
-
-                    SFLDataFormat *zeros = (SFLDataFormat*) malloc (playbackAvailBytes);
-
-                    if (zeros) {
-                        bzero (zeros, playbackAvailBytes);
-                        write (zeros, playbackAvailBytes, _PlaybackHandle);
-                        free (zeros);
-                    }
-
-                    zeros = NULL;
-                }
+            // Compute maximal value to get from the ring buffer
+            double resampleFactor = 1.0;
+            if (resample) {
+                resampleFactor = (double) _audioSampleRate / _mainBufferSampleRate;
+                maxNbBytesToGet = (double) toGet / resampleFactor;
             }
 
-            _urgentRingBuffer.Discard (toGet);
-
-            free (out);
-            out = NULL;
+            if (toGet > maxNbBytesToGet)
+            	toGet = maxNbBytesToGet;
+
+			SFLDataFormat *out = (SFLDataFormat*) malloc (toGet);
+			getMainBuffer()->getData (out, toGet);
+			if (spkrVolume!=100)
+				for (unsigned int i=0; i<toGet / sizeof (SFLDataFormat); i++)
+					out[i] = out[i] * spkrVolume / 100;
+
+			if (resample) {
+				int inSamples = toGet / sizeof(SFLDataFormat);
+				int outSamples = inSamples * resampleFactor;
+				SFLDataFormat *rsmpl_out = (SFLDataFormat*) malloc (outSamples * sizeof(SFLDataFormat));
+				_converter->resample (out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, inSamples);
+				write (rsmpl_out, outSamples * sizeof(SFLDataFormat), _PlaybackHandle);
+				free (rsmpl_out);
+			} else {
+				write (out, toGet, _PlaybackHandle);
+			}
+			free (out);
         }
     }
 
@@ -973,96 +920,68 @@ void AlsaLayer::audioCallback (void)
 
         int ringtoneAvailSmpl = snd_pcm_avail_update (_RingtoneHandle);
         int ringtoneAvailBytes = ringtoneAvailSmpl*sizeof (SFLDataFormat);
-        out = (SFLDataFormat *) malloc (ringtoneAvailBytes);
-
-        if (out) {
-            file_tone->getNext (out, ringtoneAvailSmpl, spkrVolume);
-            write (out, ringtoneAvailBytes, _RingtoneHandle);
-            free (out);
-        }
-
-        out = NULL;
-
+        SFLDataFormat *out = (SFLDataFormat *) malloc (ringtoneAvailBytes);
+		file_tone->getNext (out, ringtoneAvailSmpl, spkrVolume);
+		write (out, ringtoneAvailBytes, _RingtoneHandle);
+		free (out);
     } else if (_RingtoneHandle) {
 
         int ringtoneAvailSmpl = snd_pcm_avail_update (_RingtoneHandle);
         int ringtoneAvailBytes = ringtoneAvailSmpl*sizeof (SFLDataFormat);
 
-        out = (SFLDataFormat *) malloc (ringtoneAvailBytes);
-
-        if (out) {
-            memset (out, 0, ringtoneAvailBytes);
-            write (out, ringtoneAvailBytes, _RingtoneHandle);
-            free (out);
-        }
-
-        out = NULL;
+        SFLDataFormat *out = (SFLDataFormat *) malloc (ringtoneAvailBytes);
+		memset (out, 0, ringtoneAvailBytes);
+		write (out, ringtoneAvailBytes, _RingtoneHandle);
+		free (out);
     }
 
     // Additionally handle the mic's audio stream
-    int micAvailBytes;
-    int toPut;
-
-    SFLDataFormat* in = NULL;
-
     if (!is_capture_running())
         return;
 
-    micAvailBytes = snd_pcm_avail_update (_CaptureHandle);
-
-    if (micAvailBytes < 0)
-        _debug ("Audio: Mic error: %s", snd_strerror (micAvailBytes));
-    if (micAvailBytes <= 0)
+    int toPutSamples = snd_pcm_avail_update (_CaptureHandle);
+    if (toPutSamples <= 0) {
+        if (toPutSamples < 0)
+        	_error ("Audio: Mic error: %s", snd_strerror (toPutSamples));
         return;
+    }
     
-    toPut = (micAvailBytes <= framesPerBufferAlsa) ? micAvailBytes : framesPerBufferAlsa;
-    in = (SFLDataFormat*) malloc (toPut * sizeof (SFLDataFormat));
-    toPut = read (in, toPut* sizeof (SFLDataFormat));
-
-    adjustVolume (in, toPut, SFL_PCM_CAPTURE);
-
-    int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
-
-    if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
-
-        SFLDataFormat* rsmpl_out = (SFLDataFormat*) malloc (framesPerBufferAlsa * sizeof (SFLDataFormat));
-
-        _converter->resample ( (SFLDataFormat*) in, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, toPut / sizeof (SFLDataFormat));
-
-        _audiofilter->processAudio (rsmpl_out, toPut);
-
-        getMainBuffer()->putData (rsmpl_out, toPut);
-
+    const int framesPerBufferAlsa = 2048;
+    if (toPutSamples > framesPerBufferAlsa)
+    	toPutSamples = framesPerBufferAlsa;
+
+    int toPutBytes = toPutSamples * sizeof(SFLDataFormat);
+    SFLDataFormat* in = (SFLDataFormat*) malloc (toPutBytes);
+    int bytes = read (in, toPutBytes);
+    if (toPutBytes != bytes) {
+    	_error("ALSA MIC : Couldn't read!");
+    	free(in);
+    	return;
+    }
+    adjustVolume (in, toPutSamples, _manager->getSpkrVolume());
+
+    if (resample) {
+    	int outSamples = toPutSamples * ((double) _audioSampleRate / _mainBufferSampleRate);
+    	int outBytes = outSamples * sizeof (SFLDataFormat);
+        SFLDataFormat* rsmpl_out = (SFLDataFormat*) malloc (outBytes);
+        _converter->resample ( (SFLDataFormat*) in, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, toPutSamples);
+        _audiofilter->processAudio (rsmpl_out, outBytes);
+        getMainBuffer()->putData (rsmpl_out, outBytes);
         free (rsmpl_out);
     } else {
-        SFLDataFormat* filter_out = (SFLDataFormat*) malloc (framesPerBufferAlsa * sizeof (SFLDataFormat));
-
-        if (filter_out) {
-            _audiofilter->processAudio (in, filter_out, toPut);
-            // captureFile->write ( (const char *) filter_out, toPut);
-            getMainBuffer()->putData (filter_out, toPut);
-            free (filter_out);
-        }
+        SFLDataFormat* filter_out = (SFLDataFormat*) malloc (toPutBytes);
+		_audiofilter->processAudio (in, filter_out, toPutBytes);
+		// captureFile->write ( (const char *) filter_out, toPut);
+		getMainBuffer()->putData (filter_out, toPutBytes);
+		free (filter_out);
     }
 
     free (in);
 }
 
-void* AlsaLayer::adjustVolume (void* buffer , int len, int stream)
+void AlsaLayer::adjustVolume (SFLDataFormat *src , int samples, int volume)
 {
-    int vol = (stream == SFL_PCM_PLAYBACK)
-        ? _manager->getSpkrVolume()
-        : _manager->getMicVolume();
-
-    SFLDataFormat *src = (SFLDataFormat*) buffer;
-
-    if (vol != 100) {
-        int i, size = len / sizeof (SFLDataFormat);
-
-        for (i = 0 ; i < size ; i++) {
-            src[i] = src[i] * vol / 100 ;
-        }
-    }
-
-    return src ;
+    if (volume != 100)
+        for (int i = 0 ; i < samples; i++)
+            src[i] = src[i] * volume / 100 ;
 }
diff --git a/sflphone-common/src/audio/alsa/alsalayer.h b/sflphone-common/src/audio/alsa/alsalayer.h
index c317700327a35d44b9c63a8a9c81157cf7e5d1f4..f35f322a4b521edaa2164e2bd2d9b923b29e5f41 100644
--- a/sflphone-common/src/audio/alsa/alsalayer.h
+++ b/sflphone-common/src/audio/alsa/alsalayer.h
@@ -292,7 +292,7 @@ class AlsaLayer : public AudioLayer
          */
         void handle_xrun_playback (snd_pcm_t *handle);
 
-        void* adjustVolume (void* buffer , int len, int stream);
+        void adjustVolume (SFLDataFormat* buffer , int samples, int volume);
 
         /**
          * Handles to manipulate playback stream
diff --git a/sflphone-common/src/audio/audioloop.cpp b/sflphone-common/src/audio/audioloop.cpp
index ebfc29edddeafdfaf4394bb1fff620faeb7f06a8..7bd8afe3987f90556066810ab97975eaab1114fb 100644
--- a/sflphone-common/src/audio/audioloop.cpp
+++ b/sflphone-common/src/audio/audioloop.cpp
@@ -46,20 +46,19 @@ AudioLoop::~AudioLoop()
     _buffer = 0;
 }
 
-int
-AudioLoop::getNext (SFLDataFormat* output, int nb, short volume)
+void
+AudioLoop::getNext (SFLDataFormat* output, int samples, short volume)
 {
-    int copied = 0;
     int block;
     int pos = _pos;
 
     if(_size == 0) {
     	_error("AudioLoop: Error: Audio loop size is 0");
-    	return 0;
+    	return;
     }
 
-    while (nb) {
-        block = nb;
+    while (samples) {
+        block = samples;
 
         if (block > (_size-pos)) {
             block = _size-pos;
@@ -79,13 +78,9 @@ AudioLoop::getNext (SFLDataFormat* output, int nb, short volume)
         // should adjust sound here, in output???
         pos = (pos + block) % _size;
 
-        nb -= block;
-
-        copied += block;
+        samples -= block;
     }
 
     _pos = pos;
-
-    return copied;
 }
 
diff --git a/sflphone-common/src/audio/audioloop.h b/sflphone-common/src/audio/audioloop.h
index 2eb1c7bc4e86c1e6e366250529888dedad5d8a78..5e6616e710c825fba5c2243adcdf642c84f89318 100644
--- a/sflphone-common/src/audio/audioloop.h
+++ b/sflphone-common/src/audio/audioloop.h
@@ -60,9 +60,8 @@ class AudioLoop
          * @param output  The data buffer
          * @param nb of int16 to send
          * @param volume  The volume
-         * @return the number of int16 sent (nb*2)
          */
-        int getNext (SFLDataFormat* output, int nb, short volume=100);
+        void getNext (SFLDataFormat* output, int samples, short volume=100);
 
         /**
          * Reset the pointer position
diff --git a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp
index c27b1533a3fa905e186bfad51f2d260bba709510..8a5503ecf1f781cf765286a18a6059ea077f741b 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp
+++ b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.cpp
@@ -42,18 +42,10 @@ static const SFLDataFormat initFadeinFactor = 32000;
 
 AudioRtpRecord::AudioRtpRecord () : _audioCodec (NULL)
     , _hasDynamicPayloadType (false)
-    , _micData (NULL)
-    , _micDataConverted (NULL)
-    , _micDataEncoded (NULL)
-    , _spkrDataDecoded (NULL)
-    , _spkrDataConverted (NULL)
     , _converter (NULL)
     , _codecSampleRate (0)
     , _codecFrameSize (0)
-    , _micFadeInComplete (false)
-    , _spkrFadeInComplete (false)
     , _micAmplFactor (initFadeinFactor)
-    , _spkrAmplFactor (initFadeinFactor)
     , _audioProcess (NULL)
     , _noiseSuppress (NULL)
     , _callId ("")
@@ -65,35 +57,10 @@ AudioRtpRecord::AudioRtpRecord () : _audioCodec (NULL)
 
 AudioRtpRecord::~AudioRtpRecord()
 {
-    _debug ("AudioRtpRecord: Delete audio rtp internal data");
-
-    delete [] _micData;
-
-    delete [] _micDataConverted;
-
-    delete [] _micDataEncoded;
-
-    delete [] _micDataEchoCancelled;
-
-    delete [] _spkrDataDecoded;
-
-    delete [] _spkrDataConverted;
-
     delete _converter;
-
-    audioCodecMutex.enter();
-
     delete _audioCodec;
-
-    audioCodecMutex.leave();
-
-    audioProcessMutex.enter();
-
     delete _audioProcess;
-
     delete _noiseSuppress;
-
-    audioProcessMutex.leave();
 }
 
 
@@ -124,93 +91,41 @@ void AudioRtpRecordHandler::updateRtpMedia (AudioCodec *audioCodec)
 {
     int lastSamplingRate = _audioRtpRecord._codecSampleRate;
 
-    _audioRtpRecord.audioCodecMutex.enter();
-
-    if (_audioRtpRecord._audioCodec) {
-        delete _audioRtpRecord._audioCodec;
-        _audioRtpRecord._audioCodec = NULL;
-    }
-
-    _audioRtpRecord._audioCodec = audioCodec;
-    _audioRtpRecord._codecPayloadType = audioCodec->getPayloadType();
-    _audioRtpRecord._codecSampleRate = audioCodec->getClockRate();
-    _audioRtpRecord._codecFrameSize = audioCodec->getFrameSize();
-    _audioRtpRecord._hasDynamicPayloadType = audioCodec->hasDynamicPayload();
-
-    _audioRtpRecord.audioCodecMutex.leave();
+    setRtpMedia(audioCodec);
 
     Manager::instance().audioSamplingRateChanged(_audioRtpRecord._codecSampleRate);
 
-    if (lastSamplingRate != _audioRtpRecord._codecSampleRate)
-        updateNoiseSuppress();
-}
-
-void AudioRtpRecordHandler::init()
-{
+    if (lastSamplingRate != _audioRtpRecord._codecSampleRate) {
+        _debug ("AudioRtpSession: Update noise suppressor with sampling rate %d and frame size %d", getCodecSampleRate(), getCodecFrameSize());
+        initNoiseSuppress();
+    }
 }
 
 void AudioRtpRecordHandler::initBuffers()
 {
-    int codecSampleRate = _audioRtpRecord._codecSampleRate;
-
     // Set sampling rate, main buffer choose the highest one
     // Manager::instance().getMainBuffer()->setInternalSamplingRate (codecSampleRate);
-    Manager::instance().audioSamplingRateChanged(codecSampleRate);
+    Manager::instance().audioSamplingRateChanged(_audioRtpRecord._codecSampleRate);
 
     // initialize SampleRate converter using AudioLayer's sampling rate
     // (internal buffers initialized with maximal sampling rate and frame size)
-    int rate = getCodecSampleRate();
-    _audioRtpRecord._converter = new SamplerateConverter (rate);
-
-    int nbSamplesMax = (int) ( (getCodecSampleRate() * getCodecFrameSize() / 1000));
-    _audioRtpRecord._micData = new SFLDataFormat[nbSamplesMax];
-    _audioRtpRecord._micDataConverted = new SFLDataFormat[nbSamplesMax];
-    _audioRtpRecord._micDataEchoCancelled = new SFLDataFormat[nbSamplesMax];
-    _audioRtpRecord._micDataEncoded = new unsigned char[nbSamplesMax * 2];
-    _audioRtpRecord._spkrDataConverted = new SFLDataFormat[nbSamplesMax];
-    _audioRtpRecord._spkrDataDecoded = new SFLDataFormat[nbSamplesMax];
+    delete _audioRtpRecord._converter;
+    _audioRtpRecord._converter = new SamplerateConverter (getCodecSampleRate());
 }
 
 void AudioRtpRecordHandler::initNoiseSuppress()
 {
     _audioRtpRecord.audioProcessMutex.enter();
 
-    NoiseSuppress *noiseSuppress = new NoiseSuppress (getCodecFrameSize(), getCodecSampleRate());
-    AudioProcessing *processing = new AudioProcessing (noiseSuppress);
+    delete _audioRtpRecord._audioProcess;
+    delete _audioRtpRecord._noiseSuppress;
 
-    _audioRtpRecord._noiseSuppress = noiseSuppress;
-    _audioRtpRecord._audioProcess = processing;
+    _audioRtpRecord._noiseSuppress = new NoiseSuppress (getCodecFrameSize(), getCodecSampleRate());
+    _audioRtpRecord._audioProcess = new AudioProcessing (_audioRtpRecord._noiseSuppress);
 
     _audioRtpRecord.audioProcessMutex.leave();
 }
 
-void AudioRtpRecordHandler::updateNoiseSuppress()
-{
-
-    _audioRtpRecord.audioProcessMutex.enter();
-
-    if (_audioRtpRecord._audioProcess)
-        delete _audioRtpRecord._audioProcess;
-
-    _audioRtpRecord._audioProcess = NULL;
-
-    if (_audioRtpRecord._noiseSuppress)
-        delete _audioRtpRecord._noiseSuppress;
-
-    _audioRtpRecord._noiseSuppress = NULL;
-
-    _debug ("AudioRtpSession: Update noise suppressor with sampling rate %d and frame size %d", getCodecSampleRate(), getCodecFrameSize());
-
-    NoiseSuppress *noiseSuppress = new NoiseSuppress (getCodecFrameSize(), getCodecSampleRate());
-    AudioProcessing *processing = new AudioProcessing (noiseSuppress);
-
-    _audioRtpRecord._noiseSuppress = noiseSuppress;
-    _audioRtpRecord._audioProcess = processing;
-
-    _audioRtpRecord.audioProcessMutex.leave();
-
-}
-
 void AudioRtpRecordHandler::putDtmfEvent (int digit)
 {
     sfl::DtmfEvent *dtmf = new sfl::DtmfEvent();
@@ -230,73 +145,54 @@ std::ofstream teststream("test_process_data_encode.raw");
 
 int AudioRtpRecordHandler::processDataEncode (void)
 {
-    SFLDataFormat *micData = _audioRtpRecord._micData;
-    unsigned char *micDataEncoded = _audioRtpRecord._micDataEncoded;
-    SFLDataFormat *micDataConverted = _audioRtpRecord._micDataConverted;
+    SFLDataFormat *micData 			= _audioRtpRecord.decData;
+    unsigned char *micDataEncoded 	= _audioRtpRecord.encodedData;
+    SFLDataFormat *micDataConverted = _audioRtpRecord.resampledData;
 
     int codecSampleRate = getCodecSampleRate();
     int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
 
-    // compute codec framesize in ms
-    float fixedCodecFramesize = ((float)getCodecFrameSize() * 1000.0) / (float)codecSampleRate;
-    // compute nb of byte to get coresponding to 20 ms at audio layer frame size (44.1 khz)
-    int bytesToGet = (int) ( ( (float) mainBufferSampleRate * fixedCodecFramesize * sizeof (SFLDataFormat)) / 1000.0);
+    double resampleFactor = (double)mainBufferSampleRate / codecSampleRate;
 
-    if (Manager::instance().getMainBuffer()->availForGet (id_) < bytesToGet)
+    // compute nb of byte to get coresponding to 1 audio frame
+    int samplesToGet = resampleFactor * getCodecFrameSize();
+    int bytesToGet = samplesToGet * sizeof (SFLDataFormat);
+
+    if (Manager::instance().getMainBuffer()->availForGet (id_) < bytesToGet) {
+    	_error("%s : not enough data available", __PRETTY_FUNCTION__);
         return 0;
+    }
 
     int bytes = Manager::instance().getMainBuffer()->getData (micData, bytesToGet, id_);
-    if (bytes == 0)
+    if (bytes != bytesToGet) {
+    	_error("%s : asked %d bytes from mainbuffer, got %d", __PRETTY_FUNCTION__, bytesToGet, bytes);
         return 0;
+    }
 
-    if (!_audioRtpRecord._micFadeInComplete)
-        _audioRtpRecord._micFadeInComplete = fadeIn (micData, bytes / sizeof(SFLDataFormat), &_audioRtpRecord._micAmplFactor);
-
-    // nb bytes to be sent over RTP
-    int compSize;
-
-    // test if resampling is required
-    if (codecSampleRate != mainBufferSampleRate) {
-        _audioRtpRecord._converter->resample (micData, micDataConverted, codecSampleRate, mainBufferSampleRate, bytes / sizeof(SFLDataFormat));
-
-        _audioRtpRecord.audioProcessMutex.enter();
-
-        if (Manager::instance().audioPreference.getNoiseReduce()) {
-            _audioRtpRecord._audioProcess->processAudio (micDataConverted, bytes);
-        }
-
-        if(Manager::instance().getEchoCancelState() == "enabled") {
-            echoCanceller.getData(micData);
-        }
-
-        _audioRtpRecord.audioProcessMutex.leave();
-
-        _audioRtpRecord.audioCodecMutex.enter();
-
-        compSize = _audioRtpRecord._audioCodec->encode (micDataEncoded, micData, bytes);
-
-        _audioRtpRecord.audioCodecMutex.leave();
+    fadeIn (micData, bytesToGet / sizeof(SFLDataFormat), &_audioRtpRecord._micAmplFactor);
 
-    } else {        // no resampling required
-        _audioRtpRecord.audioProcessMutex.enter();
+    if(Manager::instance().getEchoCancelState() == "enabled")
+        echoCanceller.getData(micData);
 
-        if (Manager::instance().audioPreference.getNoiseReduce())
-            _audioRtpRecord._audioProcess->processAudio (micData, bytes);
+	_audioRtpRecord.audioProcessMutex.enter();
+	if (Manager::instance().audioPreference.getNoiseReduce())
+		_audioRtpRecord._audioProcess->processAudio (micData, bytesToGet);
+	_audioRtpRecord.audioProcessMutex.leave();
 
-        if(Manager::instance().getEchoCancelState() == "enabled")
-            echoCanceller.getData(micData);
-	
 #ifdef DUMP_PROCESS_DATA_ENCODE
-        teststream.write(reinterpret_cast<char *>(micData), nbSample * sizeof(SFLDataFormat));
+        teststream.write(reinterpret_cast<char *>(micData), bytesToGet);
 #endif
-        
-        _audioRtpRecord.audioProcessMutex.leave();
 
-        _audioRtpRecord.audioCodecMutex.enter();
-        compSize = _audioRtpRecord._audioCodec->encode (micDataEncoded, micData, bytes);
-        _audioRtpRecord.audioCodecMutex.leave();
+	SFLDataFormat *out = micData;
+    if (codecSampleRate != mainBufferSampleRate) {
+    	out = micDataConverted;
+        _audioRtpRecord._converter->resample (micData, micDataConverted, codecSampleRate, mainBufferSampleRate, samplesToGet);
     }
 
+	_audioRtpRecord.audioCodecMutex.enter();
+	int compSize = _audioRtpRecord._audioCodec->encode (micDataEncoded, out, getCodecFrameSize());
+	_audioRtpRecord.audioCodecMutex.leave();
+
     return compSize;
 }
 
@@ -304,8 +200,8 @@ void AudioRtpRecordHandler::processDataDecode (unsigned char *spkrData, unsigned
 {
     int codecSampleRate = getCodecSampleRate();
 
-    SFLDataFormat *spkrDataDecoded = _audioRtpRecord._spkrDataConverted;
-    SFLDataFormat *spkrDataConverted = _audioRtpRecord._spkrDataDecoded;
+    SFLDataFormat *spkrDataDecoded = _audioRtpRecord.decData;
+    SFLDataFormat *spkrDataConverted = _audioRtpRecord.resampledData;
 
     int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
 
@@ -316,50 +212,38 @@ void AudioRtpRecordHandler::processDataDecode (unsigned char *spkrData, unsigned
 
     _audioRtpRecord.audioCodecMutex.leave();
 
-    // buffer _receiveDataDecoded ----> short int or int16, coded on 2 bytes
-    int nbSample = expandedSize / sizeof (SFLDataFormat);
+    int inSamples = expandedSize / sizeof (SFLDataFormat);
 
-    if (!_audioRtpRecord._spkrFadeInComplete) {
-        _audioRtpRecord._spkrFadeInComplete = fadeIn (spkrDataDecoded, nbSample, &_audioRtpRecord._micAmplFactor);
-    }
+    fadeIn (spkrDataDecoded, inSamples, &_audioRtpRecord._micAmplFactor);
 
     // Normalize incomming signal
-    gainController.process(spkrDataDecoded, nbSample);
+    gainController.process(spkrDataDecoded, inSamples);
 
+    SFLDataFormat *out = spkrDataDecoded;
+    int outSamples = inSamples;
     // test if resampling is required
     if (codecSampleRate != mainBufferSampleRate) {
         // Do sample rate conversion
-        _audioRtpRecord._converter->resample (spkrDataDecoded, spkrDataConverted, codecSampleRate, mainBufferSampleRate, nbSample);
-
-        if(Manager::instance().getEchoCancelState() == "enabled") {
-            echoCanceller.putData(spkrDataConverted, expandedSize);
-        }
-
-        // put data in audio layer, size in byte
-        Manager::instance().getMainBuffer()->putData (spkrDataConverted, expandedSize, id_);
-
-    } else {
-    	if(Manager::instance().getEchoCancelState() == "enabled") {
-    	    echoCanceller.putData(spkrDataDecoded, expandedSize);
-    	}
-        // put data in audio layer, size in byte
-        Manager::instance().getMainBuffer()->putData (spkrDataDecoded, expandedSize, id_);
+        outSamples = ((float) inSamples * ( (float) mainBufferSampleRate / (float) codecSampleRate));
+        _audioRtpRecord._converter->resample (spkrDataDecoded, spkrDataConverted, codecSampleRate, mainBufferSampleRate, inSamples);
+        out = spkrDataConverted;
     }
+
+	if(Manager::instance().getEchoCancelState() == "enabled")
+	    echoCanceller.putData(out, outSamples * sizeof (SFLDataFormat));
+    Manager::instance().getMainBuffer()->putData (out, outSamples * sizeof (SFLDataFormat), id_);
 }
 
-bool AudioRtpRecordHandler::fadeIn (SFLDataFormat *audio, int size, SFLDataFormat *factor)
+void AudioRtpRecordHandler::fadeIn (SFLDataFormat *audio, int size, SFLDataFormat *factor)
 {
-    // if factor reach 0, this function should no be called anymore
+    // if factor reach 0, this function should have no effect
     if (*factor <= 0)
-        return true;
+        return;
 
     while (size)
         audio[--size] /= *factor;
 
     *factor /= FADEIN_STEP_SIZE;
-
-    return *factor <= 0;
 }
 
 }
-
diff --git a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h
index 87bd6e4814e0021486d3de23beef46d0d1c039a7..c9d64998660d61db534146a7dd44c854a8c90453 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h
+++ b/sflphone-common/src/audio/audiortp/AudioRtpRecordHandler.h
@@ -95,21 +95,15 @@ class AudioRtpRecord
         ost::Mutex audioCodecMutex;
         int _codecPayloadType;
         bool _hasDynamicPayloadType;
-        SFLDataFormat *_micData;
-        SFLDataFormat *_micDataConverted;
-        SFLDataFormat *_micDataEchoCancelled;
-        unsigned char *_micDataEncoded;
-        SFLDataFormat *_spkrDataDecoded;
-        SFLDataFormat *_spkrDataConverted;
+        SFLDataFormat decData[DEC_BUFFER_SIZE];
+        SFLDataFormat resampledData[DEC_BUFFER_SIZE];
+        unsigned char encodedData[DEC_BUFFER_SIZE];
         SamplerateConverter *_converter;
         int _codecSampleRate;
         int _codecFrameSize;
         int _converterSamplingRate;
         EventQueue _eventQueue;
-        bool _micFadeInComplete;
-        bool _spkrFadeInComplete;
         SFLDataFormat _micAmplFactor;
-        SFLDataFormat _spkrAmplFactor;
         AudioProcessing *_audioProcess;
         NoiseSuppress *_noiseSuppress;
         ost::Mutex audioProcessMutex;
@@ -162,30 +156,14 @@ class AudioRtpRecordHandler
             return _audioRtpRecord._eventQueue.size();
         }
 
-        SFLDataFormat *getMicData (void) {
-            return _audioRtpRecord._micData;
+        const unsigned char *getMicDataEncoded (void) const {
+            return _audioRtpRecord.encodedData;
         }
 
-        SFLDataFormat *getMicDataConverted (void) const {
-            return _audioRtpRecord._micDataConverted;
-        }
-
-        unsigned char *getMicDataEncoded (void) const {
-            return _audioRtpRecord._micDataEncoded;
-        }
-
-        void init (void);
-
-        /**
-         * Allocate memory for RTP buffers and fill them with zeros
-         * @prereq Session codec needs to be initialized prior calling this method
-         */
         void initBuffers (void);
 
         void initNoiseSuppress (void);
 
-        void updateNoiseSuppress (void);
-
         /**
          * Encode audio data from mainbuffer
          */
@@ -199,7 +177,7 @@ class AudioRtpRecordHandler
         /**
         * Ramp In audio data to avoid audio click from peer
         */
-        bool fadeIn (SFLDataFormat *audio, int size, SFLDataFormat *factor);
+        void fadeIn (SFLDataFormat *audio, int size, SFLDataFormat *factor);
 
         void setDtmfPayloadType(unsigned int payloadType) {
         	_audioRtpRecord._dtmfPayloadType = payloadType;
diff --git a/sflphone-common/src/audio/codecs/audiocodec.h b/sflphone-common/src/audio/codecs/audiocodec.h
index 7f443db054fd4447269073c76bcc60068c1e9727..aa05c008e4f2d2a532d863168de087e93dee07f5 100644
--- a/sflphone-common/src/audio/codecs/audiocodec.h
+++ b/sflphone-common/src/audio/codecs/audiocodec.h
@@ -38,6 +38,11 @@
 
 #include "Codec.h"
 
+// We assume all decoders will be fed 20ms of audio or less
+// And we'll resample them to 44.1kHz or less
+// Also assume mono
+#define DEC_BUFFER_SIZE ((44100 * 20) / 1000)
+
 namespace ost {
     class PayloadFormat;
     class DynamicPayloadFormat;
diff --git a/sflphone-common/src/audio/codecs/audiocodecfactory.cpp b/sflphone-common/src/audio/codecs/audiocodecfactory.cpp
index 2142e5bc1be5e213d91adad47b0e86e87fc42740..9c429336aba12fce69d78c9ce5cd964c8fa219aa 100644
--- a/sflphone-common/src/audio/codecs/audiocodecfactory.cpp
+++ b/sflphone-common/src/audio/codecs/audiocodecfactory.cpp
@@ -388,7 +388,6 @@ bool AudioCodecFactory::isCodecLoaded (int payload)
 
 std::vector <std::string> AudioCodecFactory::getCodecSpecifications (const int32_t& payload)
 {
-
     _debug ("CodecDescriptor: Gathering codec specifications for payload %i", payload);
 
     std::vector<std::string> v;
@@ -408,5 +407,4 @@ std::vector <std::string> AudioCodecFactory::getCodecSpecifications (const int32
     ss.str ("");
 
     return v;
-
 }
diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
index dbc3457b04215abe4fa9cad72cf2d1f8350c726d..db24a223a154ee47cd6953739bd9d60f6cd8ce36 100644
--- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
+++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
@@ -719,132 +719,86 @@ void PulseLayer::setNoiseSuppressState (bool state)
 
 void PulseLayer::writeToSpeaker (void)
 {
-    /** Bytes available in the urgent ringbuffer ( reserved for DTMF ) */
-    int urgentAvailBytes;
-    /** Bytes available in the regular ringbuffer ( reserved for voice ) */
-    int normalAvailBytes;
-    /** Bytes to get in the ring buffer **/
-    int byteToGet;
-
     notifyincomingCall();
 
-    SFLDataFormat* out;// = (SFLDataFormat*)pa_xmalloc(framesPerBuffer);
-    urgentAvailBytes = _urgentRingBuffer.AvailForGet();
-
     // available bytes to be written in pulseaudio internal buffer
-    int writeableSize = pa_stream_writable_size (playback->pulseStream());
-
-    if (writeableSize < 0) {
-        _warn ("Audio: playback error : %s", pa_strerror (writeableSize));
-    }
-
-    AudioLoop *toneToPlay = _manager->getTelephoneTone();
-
-    if (urgentAvailBytes > writeableSize) {
-
-        out = (SFLDataFormat*) pa_xmalloc (writeableSize);
-        memset (out, 0, writeableSize);
-
-        _urgentRingBuffer.Get (out, writeableSize);
-
-        pa_stream_write (playback->pulseStream(), out, writeableSize, NULL, 0, PA_SEEK_RELATIVE);
-
+    int writeableSizeBytes = pa_stream_writable_size (playback->pulseStream());
+    if (writeableSizeBytes < 0) {
+        _error ("Audio: playback error : %s", pa_strerror (writeableSizeBytes));
+        return;
+    }
+
+    int urgentBytes = _urgentRingBuffer.AvailForGet();
+    if (urgentBytes > writeableSizeBytes)
+    	urgentBytes = writeableSizeBytes;
+    if (urgentBytes) {
+    	SFLDataFormat *out = (SFLDataFormat*) pa_xmalloc (urgentBytes);
+        _urgentRingBuffer.Get (out, urgentBytes);
+        pa_stream_write (playback->pulseStream(), out, urgentBytes, NULL, 0, PA_SEEK_RELATIVE);
         pa_xfree (out);
-
         // Consume the regular one as well (same amount of bytes)
-        getMainBuffer()->discard (writeableSize);
-
-
-    } 
-    else if (toneToPlay != 0) {
-
-        if (playback->getStreamState() == PA_STREAM_READY) {
-
-            out = (SFLDataFormat*) pa_xmalloc (writeableSize);
-            memset (out, 0, writeableSize);
-
-            int copied = toneToPlay->getNext (out, writeableSize / sizeof (SFLDataFormat), 100);
-
-            //spkrFile->write ( (const char *) out, copied*sizeof (SFLDataFormat));
-                pa_stream_write (playback->pulseStream(), out, copied * sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
-
-                pa_xfree (out);
-        }
+        getMainBuffer()->discard (urgentBytes);
+        return;
     }
-    else {
-
-        // We must test if data have been received from network in case of early media
-        normalAvailBytes = getMainBuffer()->availForGet();
-
-        // flush remaining samples in _urgentRingBuffer
-        flushUrgent();
-
-        int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
-
-        int maxNbBytesToGet = 0;
-
-        // test if audio resampling is needed
-        if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
-            double upsampleFactor = (double) _mainBufferSampleRate / _audioSampleRate;
-             maxNbBytesToGet = ( (double) writeableSize * upsampleFactor);
-        } else {
-            maxNbBytesToGet = writeableSize;
-        }
-
-        byteToGet = (normalAvailBytes < (int) (maxNbBytesToGet)) ? normalAvailBytes : maxNbBytesToGet;
-
-        if (byteToGet) {
-            // Sending an odd number of byte breaks the audio!
-        	byteToGet &= ~1;
-
-            out = (SFLDataFormat*) pa_xmalloc (maxNbBytesToGet);
-            memset (out, 0, maxNbBytesToGet);
-
-            getMainBuffer()->getData (out, byteToGet);
-
-            // test if resampling is required
-            if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
-                SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (writeableSize);
-                memset (out, 0, writeableSize);
 
-                _converter->resample ( (SFLDataFormat*) out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, byteToGet / sizeof (SFLDataFormat));
-
-                if ( byteToGet > (unsigned int) writeableSize)
-                    _warn ("Audio: Error: nbsbyte exceed buffer length");
-
-                pa_stream_write (playback->pulseStream(), rsmpl_out, byteToGet, NULL, 0, PA_SEEK_RELATIVE);
+    AudioLoop *toneToPlay = _manager->getTelephoneTone();
+    if (toneToPlay) {
+		if (playback->getStreamState() == PA_STREAM_READY) {
+			SFLDataFormat *out = (SFLDataFormat*) pa_xmalloc (writeableSizeBytes);
+			toneToPlay->getNext (out, writeableSizeBytes / sizeof (SFLDataFormat), 100);
+			//spkrFile->write ( (const char *) out, writeableSize);
+			pa_stream_write (playback->pulseStream(), out, writeableSizeBytes, NULL, 0, PA_SEEK_RELATIVE);
+			pa_xfree (out);
+		}
+		return;
+    }
 
-                pa_xfree (rsmpl_out);
+	flushUrgent(); // flush remaining samples in _urgentRingBuffer
 
-            } else {
-		// write origin data
-                pa_stream_write (playback->pulseStream(), out, byteToGet, NULL, 0, PA_SEEK_RELATIVE);
-            }
+	int availSamples = getMainBuffer()->availForGet() / sizeof(SFLDataFormat);
+	if (availSamples == 0) {
+		// play silence
+		SFLDataFormat* zeros = (SFLDataFormat*) pa_xmalloc0(writeableSizeBytes);
+		pa_stream_write (playback->pulseStream(), zeros, writeableSizeBytes, NULL, 0, PA_SEEK_RELATIVE);
+		pa_xfree (zeros);
+		return;
+	}
 
-	    // free audio buffer used to get data from 
-            pa_xfree (out);
+	unsigned int mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
+	bool resample = _audioSampleRate != mainBufferSampleRate;
 
-        } else {
+	// how much samples we can write in the output
+	int outSamples = writeableSizeBytes / sizeof(SFLDataFormat);
 
-	    // Get ringtone
-            // AudioLoop *fileToPlay = _manager->getTelephoneTone();
+	// how much samples we want to read from the buffer
+	int inSamples = outSamples;
 
-	    // If audio stream is open and there is realy nothing to play (i.e. audio voce is late and audio layer is underrun)
-            if (toneToPlay == NULL) {
+	double resampleFactor = 1.;
+	if (resample) {
+		resampleFactor = (double) _audioSampleRate / mainBufferSampleRate;
+		inSamples = (double) inSamples / resampleFactor;
+	}
 
-                SFLDataFormat* zeros = (SFLDataFormat*) pa_xmalloc (writeableSize);
-                bzero (zeros, writeableSize);
+	if (inSamples > availSamples)
+		inSamples = availSamples;
+	int outBytes = (double)inSamples * resampleFactor * sizeof(SFLDataFormat);
 
-                pa_stream_write (playback->pulseStream(), zeros, writeableSize, NULL, 0, PA_SEEK_RELATIVE);
+	int inBytes = inSamples * sizeof (SFLDataFormat);
+	SFLDataFormat *out = (SFLDataFormat*) pa_xmalloc (inBytes);
+	getMainBuffer()->getData (out, inBytes);
 
-                pa_xfree (zeros);
+	// test if resampling is required
+	if (resample) {
+		SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (outBytes);
+		_converter->resample (out, rsmpl_out, mainBufferSampleRate, _audioSampleRate, inSamples);
+		pa_stream_write (playback->pulseStream(), rsmpl_out, outBytes, NULL, 0, PA_SEEK_RELATIVE);
+		pa_xfree (rsmpl_out);
 
-            }
-        }
+	} else {
+		pa_stream_write (playback->pulseStream(), out, inBytes, NULL, 0, PA_SEEK_RELATIVE);
+	}
 
-	_urgentRingBuffer.Discard (byteToGet);
-
-    }
+	pa_xfree (out);
 }
 
 void PulseLayer::readFromMic (void)
@@ -852,51 +806,37 @@ void PulseLayer::readFromMic (void)
     const char* data = NULL;
     size_t r;
 
-    int readableSize = pa_stream_readable_size (record->pulseStream());
-
+	unsigned int mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
+	bool resample = _audioSampleRate != mainBufferSampleRate;
 
     if (pa_stream_peek (record->pulseStream() , (const void**) &data , &r) < 0 || !data) {
-        _warn ("Audio: Error capture stream peek failed: %s" , pa_strerror (pa_context_errno (context)));
+        _error("Audio: Error capture stream peek failed: %s" , pa_strerror (pa_context_errno (context)));
+        goto end;
     }
 
-    if (data != 0) {
-
-        int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
-
-        // test if resampling is required
-        if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
-
-            SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (readableSize);
-            memset (rsmpl_out, 0, readableSize);
-
-            _converter->resample ( (SFLDataFormat *) data, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, r / sizeof (SFLDataFormat));
-
-            // remove dc offset
-            _audiofilter->processAudio (rsmpl_out, r);
+	if (resample) {
+		int inSamples = r / sizeof(SFLDataFormat);
+		double resampleFactor = (double) _audioSampleRate / mainBufferSampleRate;
+		int outSamples = (double) inSamples * resampleFactor;
+		int outBytes = outSamples * sizeof(SFLDataFormat);
 
-            getMainBuffer()->putData (rsmpl_out, r);
-
-            pa_xfree (rsmpl_out);
-
-        } else {
-
-
-            SFLDataFormat* filter_out = (SFLDataFormat*) pa_xmalloc (r);
-            memset (filter_out, 0, r);
-
-            // remove dc offset
-            _audiofilter->processAudio ( (SFLDataFormat *) data, filter_out, r);
-
-            getMainBuffer()->putData (filter_out, r);
-
-            pa_xfree (filter_out);
-        }
-    }
-
-    if (pa_stream_drop (record->pulseStream()) < 0) {
-        _warn ("Audio: Error: capture stream drop failed: %s" , pa_strerror (pa_context_errno (context)));
-    }
+		SFLDataFormat* rsmpl_out = (SFLDataFormat*) pa_xmalloc (outBytes);
+		_converter->resample ( (SFLDataFormat *) data, rsmpl_out, mainBufferSampleRate, _audioSampleRate, inSamples);
+		// remove dc offset
+		_audiofilter->processAudio (rsmpl_out, outBytes);
+		getMainBuffer()->putData (rsmpl_out, outBytes);
+		pa_xfree (rsmpl_out);
+	} else {
+		SFLDataFormat* filter_out = (SFLDataFormat*) pa_xmalloc (r);
+		// remove dc offset
+		_audiofilter->processAudio ( (SFLDataFormat *) data, filter_out, r);
+		getMainBuffer()->putData (filter_out, r);
+		pa_xfree (filter_out);
+	}
 
+end:
+    if (pa_stream_drop (record->pulseStream()) < 0)
+        _error ("Audio: Error: capture stream drop failed: %s" , pa_strerror (pa_context_errno (context)));
 }
 
 
@@ -923,12 +863,8 @@ void PulseLayer::ringtoneToSpeaker (void)
 
         memset (out, 0, writableSize);
 
-        int copied = fileToPlay->getNext (out, writableSize/sizeof (SFLDataFormat), 100);
-        if(copied == 0) {
-            copied = writableSize/sizeof(SFLDataFormat);
-        }
-
-        pa_stream_write (ringtone->pulseStream(), out, copied*sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
+        fileToPlay->getNext (out, writableSize/sizeof (SFLDataFormat), 100);
+        pa_stream_write (ringtone->pulseStream(), out, writableSize, NULL, 0, PA_SEEK_RELATIVE);
 
         pa_xfree (out);
     } 
@@ -940,10 +876,6 @@ void PulseLayer::ringtoneToSpeaker (void)
         }
 
         out = (SFLDataFormat*) pa_xmalloc (writableSize);
-        if(out == NULL) {
-        	_error("PulseAudio: Error: Could not allocate memory for buffer");
-        	return;
-        }
         memset (out, 0, writableSize);
 
         pa_stream_write (ringtone->pulseStream(), out, writableSize, NULL, 0, PA_SEEK_RELATIVE);
diff --git a/sflphone-common/src/audio/samplerateconverter.cpp b/sflphone-common/src/audio/samplerateconverter.cpp
index 411c20389c39b4b6e415f93a8ef3ca5085522e1c..ca4e54def666fd2ef60f2a90695b2b55afef214b 100644
--- a/sflphone-common/src/audio/samplerateconverter.cpp
+++ b/sflphone-common/src/audio/samplerateconverter.cpp
@@ -66,8 +66,8 @@ void SamplerateConverter::resample (SFLDataFormat* dataIn , SFLDataFormat* dataO
 {
 	assert(outputFreq <= _maxFreq);
 
-    double sampleFactor = (double) inputFreq / outputFreq;
-    if (sampleFactor == 1)
+    double sampleFactor = (double) outputFreq / inputFreq;
+    if (sampleFactor == 1.0)
 		return;
 
     int outSamples = nbSamples * sampleFactor;
diff --git a/sflphone-common/src/audio/sound/audiofile.cpp b/sflphone-common/src/audio/sound/audiofile.cpp
index b10382945d52fd9da91ec7af22011fa8d13f206c..9c8d4d25ddc41425fd5a700131b4499349bf00db 100644
--- a/sflphone-common/src/audio/sound/audiofile.cpp
+++ b/sflphone-common/src/audio/sound/audiofile.cpp
@@ -241,19 +241,9 @@ WaveFile::WaveFile (const std::string& fileName, unsigned int audioSamplingRate)
     }
 
     if (srate != audioSamplingRate) {
-        nbSamples = (int) ( (float) nbSamples * ( (float) audioSamplingRate / (float) srate));
-
-	    _buffer = new SFLDataFormat[nbSamples];
-	    if (_buffer == NULL) {
-	    	delete[] tempBuffer;
-	        throw AudioFileException("Could not allocate buffer for audio");
-	    }
-
-		if (srate < audioSamplingRate)
-			_converter.resample (tempBuffer, _buffer, srate, audioSamplingRate, nbSamples);
-		else if (srate > audioSamplingRate)
-			_converter.resample (tempBuffer, _buffer, audioSamplingRate, srate, nbSamples);
-
+        int outSamples = ((float) nbSamples * ( (float) audioSamplingRate / (float) srate));
+	    _buffer = new SFLDataFormat[outSamples];
+		_converter.resample (tempBuffer, _buffer, srate, audioSamplingRate, nbSamples);
 		delete[] tempBuffer;
     } else {
     	_buffer = tempBuffer;
diff --git a/sflphone-common/src/iax/iaxvoiplink.cpp b/sflphone-common/src/iax/iaxvoiplink.cpp
index ba70c8628ea47d4b11ab77f959e1dd38b567a45c..9c597dfb5652766a861025286a3d26c755fd2577 100644
--- a/sflphone-common/src/iax/iaxvoiplink.cpp
+++ b/sflphone-common/src/iax/iaxvoiplink.cpp
@@ -62,11 +62,6 @@ IAXVoIPLink::IAXVoIPLink (const std::string& accountID) : VoIPLink ()
     , _regSession (NULL)
     , _nextRefreshStamp (0)
     , audiolayer (NULL)
-    , micData (NULL)
-    , micDataConverted (NULL)
-    , micDataEncoded (NULL)
-    , spkrDataDecoded (NULL)
-    , spkrDataConverted (NULL)
     , converter (NULL)
     , converterSamplingRate (0)
     , urlhook (NULL)
@@ -78,17 +73,6 @@ IAXVoIPLink::IAXVoIPLink (const std::string& accountID) : VoIPLink ()
     srand (time (NULL));
 
     converter = new SamplerateConverter (44100);
-
-    // int nbSamplesMax = (int) (converter->getFrequence() * converter->getFramesize() / 1000);
-    int nbSamplesMax = (44100 * 20) / 1000;
-
-    micData = new SFLDataFormat[nbSamplesMax];
-    micDataConverted = new SFLDataFormat[nbSamplesMax];
-    micDataEncoded = new unsigned char[nbSamplesMax];
-
-    spkrDataConverted = new SFLDataFormat[nbSamplesMax];
-    spkrDataDecoded = new SFLDataFormat[nbSamplesMax];
-
     urlhook = new UrlHook ();
 }
 
@@ -102,11 +86,6 @@ IAXVoIPLink::~IAXVoIPLink()
     terminate();
 
 	delete converter;
-	delete [] micData;
-	delete [] micDataConverted;
-	delete [] micDataEncoded;
-	delete [] spkrDataDecoded;
-	delete [] spkrDataConverted;
 }
 
 bool
@@ -282,53 +261,50 @@ IAXVoIPLink::sendAudioFromMic (void)
     // do not use the current ID in Manager (it may refer to a conference also)
     // currentCall = getIAXCall (Manager::instance().getCurrentCallId());
 
-    CallMap::iterator iter_call = _callMap.begin();
-
-    while (iter_call != _callMap.end()) {
-        IAXCall *currentCall = (IAXCall*) iter_call->second;
-        iter_call++;
-
+    for (CallMap::iterator iter = _callMap.begin(); iter != _callMap.end() ; ++iter) {
+        IAXCall *currentCall = (IAXCall*) iter->second;
         if (!currentCall || currentCall->getState() != Call::Active)
 			continue;
 
 		AudioCodecType codecType = currentCall->getAudioCodec();
 	    sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(currentCall->getAudioCodecFactory().getCodec (codecType));
 
-		// Send sound here
-
 		if (!audioCodec || !audiolayer)
 			continue;
 
 		Manager::instance().getMainBuffer()->setInternalSamplingRate (audioCodec->getClockRate());
 
-		int _mainBufferSampleRate = audiolayer->getMainBuffer()->getInternalSamplingRate();
+		unsigned int mainBufferSampleRate = audiolayer->getMainBuffer()->getInternalSamplingRate();
 
 		// we have to get 20ms of data from the mic *20/1000 = /50
 		// rate/50 shall be lower than IAX__20S_48KHZ_MAX
-		int needed = _mainBufferSampleRate * audiolayer->getFrameSize() / 1000 * sizeof (SFLDataFormat);
-		if (audiolayer->getMainBuffer()->availForGet (currentCall->getCallId()) < needed)
+		int bytesNeeded = mainBufferSampleRate * 20 / 1000 * sizeof (SFLDataFormat);
+		if (audiolayer->getMainBuffer()->availForGet (currentCall->getCallId()) < bytesNeeded)
 			continue;
 
 		// Get bytes from micRingBuffer to data_from_mic
-        int bytes = audiolayer->getMainBuffer()->getData (micData, needed, currentCall->getCallId()) / sizeof (SFLDataFormat);
+        int bytes = audiolayer->getMainBuffer()->getData (decData, bytesNeeded, currentCall->getCallId());
+        int samples = bytes / sizeof(SFLDataFormat);
 
 		int compSize;
-		if (audioCodec->getClockRate() && ((int) audioCodec->getClockRate() != _mainBufferSampleRate)) {
-			// resample
-			converter->resample (micData , micDataConverted , (int) audioCodec->getClockRate(), _mainBufferSampleRate, bytes);
-			compSize = audioCodec->encode (micDataEncoded, micDataConverted , bytes);
+		unsigned int audioRate = audioCodec->getClockRate();
+		int outSamples;
+		if (audioRate != mainBufferSampleRate) {
+	        int outSamples = ((float) samples * ( (float) mainBufferSampleRate / (float) audioRate));
+			converter->resample (decData , resampledData , audioRate, mainBufferSampleRate, samples);
+			compSize = audioCodec->encode (encodedData, resampledData , outSamples * sizeof(SFLDataFormat));
 		} else {
-			compSize = audioCodec->encode (micDataEncoded, micData, bytes);
+			outSamples = samples;
+			compSize = audioCodec->encode (encodedData, decData, bytes);
 		}
 
 		// Send it out!
 		_mutexIAX.enterMutex();
 
 		// Make sure the session and the call still exists.
-		if (currentCall->getSession() && (micDataEncoded != NULL) && (bytes > 0)) {
-			if (iax_send_voice (currentCall->getSession(), currentCall->getFormat(), micDataEncoded, compSize, bytes) == -1) {
-				_debug ("IAX: Error sending voice data.");
-			}
+		if (currentCall->getSession() && (bytes > 0)) {
+			if (iax_send_voice (currentCall->getSession(), currentCall->getFormat(), encodedData, compSize, outSamples) == -1)
+				_error ("IAX: Error sending voice data.");
 		}
 
 		_mutexIAX.leaveMutex();
@@ -479,13 +455,12 @@ IAXVoIPLink::hangup (const std::string& id) throw (VoipLinkException)
     	throw VoipLinkException("Could not find call");
     }
 
-    std::string reason = "Dumped Call";
     CHK_VALID_CALL;
 
     Manager::instance().getMainBuffer()->unBindAll (call->getCallId());
 
     _mutexIAX.enterMutex();
-    iax_hangup (call->getSession(), (char*) reason.c_str());
+    iax_hangup (call->getSession(), (char*) "Dumped Call");
     _mutexIAX.leaveMutex();
 
     call->setSession (NULL);
@@ -505,7 +480,6 @@ IAXVoIPLink::peerHungup (const std::string& id) throw (VoipLinkException)
     	throw VoipLinkException("Could not find call");
     }
 
-    std::string reason = "Dumped Call";
     CHK_VALID_CALL;
 
     Manager::instance().getMainBuffer()->unBindAll (call->getCallId());
@@ -589,12 +563,11 @@ bool
 IAXVoIPLink::refuse (const std::string& id)
 {
     IAXCall* call = getIAXCall (id);
-    std::string reason = "Call rejected manually.";
 
     CHK_VALID_CALL;
 
     _mutexIAX.enterMutex();
-    iax_reject (call->getSession(), (char*) reason.c_str());
+    iax_reject (call->getSession(), (char*) "Call rejected manually.");
     _mutexIAX.leaveMutex();
 
     removeCall (id);
@@ -745,9 +718,8 @@ IAXVoIPLink::iaxHandleCallEvent (iax_event* event, IAXCall* call)
 
             /*
                _debug("IAXVoIPLink::iaxHandleCallEvent, peer hangup have been called");
-               std::string reason = "Dumped Call";
                _mutexIAX.enterMutex();
-               iax_hangup(call->getSession(), (char*)reason.c_str());
+               iax_hangup(call->getSession(), (char*)"Dumped Call");
                _mutexIAX.leaveMutex();
                call->setSession(NULL);
                audiolayer->stopStream();
@@ -905,39 +877,23 @@ IAXVoIPLink::iaxHandleCallEvent (iax_event* event, IAXCall* call)
 void
 IAXVoIPLink::iaxHandleVoiceEvent (iax_event* event, IAXCall* call)
 {
-
-    unsigned char *data;
-    unsigned int size, max, nbInt16;
-    int expandedSize, nbSample_;
-    sfl::AudioCodec *audioCodec;
-
-    if (!call) {
-        return;
-    }
-
     if (!event->datalen) {
         // Skip this empty packet.
         //_debug("IAX: Skipping empty jitter-buffer interpolated packet");
         return;
     }
 
-    AudioCodecType audioCodecType = call->getAudioCodec();
-    audioCodec = static_cast<sfl::AudioCodec *>(call->getAudioCodecFactory().getCodec (audioCodecType));
-
-    if (!audioCodec)
-        return;
-
     if (audiolayer) {
         _debug ("IAX: incoming audio, but no sound card open");
         return;
     }
 
-	Manager::instance().getMainBuffer ()->setInternalSamplingRate (audioCodec->getClockRate ());
-
-	// If we receive datalen == 0, some things of the jitter buffer in libiax2/iax.c
-	// were triggered
+    sfl::AudioCodec *audioCodec = static_cast<sfl::AudioCodec *>(call->getAudioCodecFactory().getCodec (call->getAudioCodec()));
+    if (!audioCodec)
+        return;
 
-	int _mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
+	Manager::instance().getMainBuffer ()->setInternalSamplingRate (audioCodec->getClockRate ());
+	unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
 
 	// On-the-fly codec changing (normally, when we receive a full packet)
 	// as per http://tools.ietf.org/id/draft-guy-iax-03.txt
@@ -948,26 +904,26 @@ IAXVoIPLink::iaxHandleVoiceEvent (iax_event* event, IAXCall* call)
 		call->setFormat (event->subclass);
 	}
 
-	data = (unsigned char*) event->data;
-
-	size   = event->datalen;
+	unsigned char *data = (unsigned char*) event->data;
+	unsigned int size = event->datalen;
 
 	// Decode data with relevant codec
-	max = (int) (audioCodec->getClockRate() * audiolayer->getFrameSize() / 1000);
+	unsigned int max = audioCodec->getClockRate() * audiolayer->getFrameSize() / 1000;
 
 	if (size > max) {
 		_debug ("The size %d is bigger than expected %d. Packet cropped. Ouch!", size, max);
 		size = max;
 	}
 
-	expandedSize = audioCodec->decode (spkrDataDecoded , data , size);
-
-	if (audioCodec->getClockRate() && ((int) audioCodec->getClockRate() != _mainBufferSampleRate)) {
-		converter->resample (spkrDataDecoded, spkrDataConverted, audioCodec->getClockRate(), _mainBufferSampleRate, expandedSize);
-		audiolayer->getMainBuffer()->putData (spkrDataConverted, expandedSize, call->getCallId());
-
+	int expandedSize = audioCodec->decode (decData, data , size);
+	unsigned int audioRate = audioCodec->getClockRate();
+	int inSamples = expandedSize / sizeof(SFLDataFormat);
+	if (audioRate != mainBufferSampleRate) {
+		int outSize = expandedSize * (mainBufferSampleRate / audioRate);
+		converter->resample (decData, resampledData, mainBufferSampleRate, audioRate, inSamples);
+		audiolayer->getMainBuffer()->putData (resampledData, outSize, call->getCallId());
 	} else {
-		audiolayer->getMainBuffer()->putData (spkrDataDecoded, expandedSize, call->getCallId());
+		audiolayer->getMainBuffer()->putData (decData, expandedSize, call->getCallId());
 	}
 }
 
@@ -1034,7 +990,6 @@ int IAXVoIPLink::processIAXMsgCount (int msgcount)
     // msgcount >= 256        => msgcount/256 old messages , msgcount%256 new messages (RULES)
 
     return msgcount%256;
-
 }
 
 
@@ -1043,7 +998,6 @@ IAXVoIPLink::iaxHandlePrecallEvent (iax_event* event)
 {
     IAXCall* call = NULL;
     std::string   id;
-    std::string reason = "Error ringing user.";
 
     switch (event->etype) {
 
@@ -1117,10 +1071,8 @@ IAXVoIPLink::iaxHandlePrecallEvent (iax_event* event)
 
             } else {
                 // reject call, unable to add it
-                iax_reject (event->session, (char*) reason.c_str());
-
+                iax_reject (event->session, (char*) "Error ringing user.");
                 delete call;
-                call = NULL;
             }
 
             break;
@@ -1150,7 +1102,6 @@ IAXVoIPLink::iaxHandlePrecallEvent (iax_event* event)
 void IAXVoIPLink::updateAudiolayer (void)
 {
     _mutexIAX.enterMutex();
-    audiolayer = NULL;
     audiolayer = Manager::instance().getAudioDriver();
     _mutexIAX.leaveMutex();
 }
diff --git a/sflphone-common/src/iax/iaxvoiplink.h b/sflphone-common/src/iax/iaxvoiplink.h
index 88da9088d337fe3a74b9d03d42f2e63d0c0639ef..245c09fa6cb1dcbc412766b83c2be820fe20a68f 100644
--- a/sflphone-common/src/iax/iaxvoiplink.h
+++ b/sflphone-common/src/iax/iaxvoiplink.h
@@ -306,14 +306,10 @@ class IAXVoIPLink : public VoIPLink
         /** Connection to audio card/device */
         AudioLayer* audiolayer;
 
-        /** Mic-data related buffers */
-        SFLDataFormat* micData;
-        SFLDataFormat* micDataConverted;
-        unsigned char* micDataEncoded;
-
-        /** Speaker-data related buffers */
-        SFLDataFormat* spkrDataDecoded;
-        SFLDataFormat* spkrDataConverted;
+        /** encoder/decoder/resampler buffers */
+        SFLDataFormat decData[DEC_BUFFER_SIZE];
+        SFLDataFormat resampledData[DEC_BUFFER_SIZE];
+        unsigned char encodedData[DEC_BUFFER_SIZE];
 
         /** Sample rate converter object */
         SamplerateConverter* converter;