diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp
index 92f2fba69ae38af047b3890326e25b938f1b28a6..fcd22045b26058cafa629946837a5abface97557 100644
--- a/sflphone-common/src/audio/alsa/alsalayer.cpp
+++ b/sflphone-common/src/audio/alsa/alsalayer.cpp
@@ -37,14 +37,14 @@ AlsaLayer::AlsaLayer (ManagerImpl* manager)
         , _is_running_capture (false)
         , _is_open_playback (false)
         , _is_open_capture (false)
-        , _trigger_request (false)
-	, _converterSamplingRate(0)
+        , _trigger_request (false)	
+	, _audioThread(NULL)
 
 {
     _debug (" Constructor of AlsaLayer called\n");
     /* Instanciate the audio thread */
-    _audioThread = new AudioThread (this);
-
+    // _audioThread = new AudioThread (this);
+    // _audioThread = NULL;
     _urgentRingBuffer.createReadPointer();
 
     dcblocker = new DcBlocker();
@@ -60,7 +60,9 @@ AlsaLayer::~AlsaLayer (void)
 	delete _converter; _converter = NULL;
     }
 
-    delete dcblocker; dcblocker = NULL;
+    if(dcblocker) {
+	delete dcblocker; dcblocker = NULL;
+    }
 }
 
 bool
@@ -71,6 +73,7 @@ AlsaLayer::closeLayer()
     try {
         /* Stop the audio thread first */
         if (_audioThread) {
+	    _debug("Stop Audio Thread\n");
             delete _audioThread;
             _audioThread=NULL;
         }
@@ -112,7 +115,7 @@ AlsaLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize,
 
     _frameSize = frameSize;
 
-    _audioPlugin = plugin;
+    _audioPlugin = std::string(plugin);
 
     _debugAlsa (" Setting AlsaLayer: device     in=%2d, out=%2d\n", _indexIn, _indexOut);
 
@@ -122,37 +125,76 @@ AlsaLayer::openDevice (int indexIn, int indexOut, int sampleRate, int frameSize,
 
     _debugAlsa ("                   : sample rate=%5d, format=%s\n", _audioSampleRate, SFLDataFormatString);
 
+    _audioThread = NULL;
+
     ost::MutexLock lock (_mutex);
 
     std::string pcmp = buildDeviceTopo (plugin, indexOut, 0);
 
-    std::string pcmc = buildDeviceTopo (PCM_PLUGHW, indexIn, 0);
+    std::string pcmc = buildDeviceTopo (plugin, indexIn, 0);
 
     _converter = new SamplerateConverter (_audioSampleRate, _frameSize);
 
-    return open_device (pcmp, pcmc, stream);
+    // open_device (pcmp, pcmc, stream);
+    return true; // open_device (pcmp, pcmc, stream);
 }
 
 void
 AlsaLayer::startStream (void)
 {
-    _debug ("Start ALSA streams\n");
+    _debug ("AlsaLayer:: startStream\n");
+
+    std::string pcmp = buildDeviceTopo (_audioPlugin, _indexOut, 0);
+    std::string pcmc = buildDeviceTopo (_audioPlugin, _indexIn, 0);
+
+    if(!is_playback_open()){
+	open_device (pcmp, pcmc, SFL_PCM_PLAYBACK);
+    }
+
+    if(!is_capture_open()){
+	open_device (pcmp, pcmc, SFL_PCM_CAPTURE);
+    }
+   
     prepareCaptureStream ();
+    preparePlaybackStream ();
     startCaptureStream ();
     startPlaybackStream ();
 
     _urgentRingBuffer.flush();
-    _mainBuffer.flush();
+    _mainBuffer.flushAllBuffers();
     _mainBuffer.flushDefault();
 
+    if(_audioThread == NULL) {
+	try {
+	    _debug("Start Audio Thread\n");
+	    _audioThread = new AudioThread (this);
+	    _audioThread->start();
+	} catch (...) {
+	    _debugException ("Fail to start audio thread\n");
+	}
+    }
+
 }
 
 void
 AlsaLayer::stopStream (void)
 {
-    _debug ("AlsaLayer::stopStream :: Stop ALSA streams\n");
-    stopCaptureStream ();
-    //stopPlaybackStream ();
+    _debug ("AlsaLayer:: stopStream\n");
+
+    try {
+        /* Stop the audio thread first */
+        if (_audioThread) {
+	    _debug("Stop Audio Thread\n");
+            delete _audioThread;
+            _audioThread=NULL;
+        }
+    } catch (...) {
+        _debugException ("! ARTP Exception: when stopping audiortp\n");
+        throw;
+    }
+
+    closeCaptureStream ();
+    closePlaybackStream ();
 
     /* Flush the ring buffers */
     flushUrgent ();
@@ -227,38 +269,52 @@ void AlsaLayer::stopCaptureStream (void)
     int err;
 
     if (_CaptureHandle) {
-        err = snd_pcm_drop (_CaptureHandle);
-
-        stop_capture ();
+	_debug("AlsaLayer:: stop Alsa capture\n");
+        if((err = snd_pcm_drop (_CaptureHandle)) < 0)
+	    _debug("AlsaLayer:: Error stopping ALSA capture: %s\n", snd_strerror(err));
+	else
+	    stop_capture ();
 
     }
 }
 
 void AlsaLayer::closeCaptureStream (void)
 {
+    int err;
+
     if (is_capture_prepared() == true && is_capture_running() == true)
         stopCaptureStream ();
 
-    if (is_capture_open())
-        snd_pcm_close (_CaptureHandle);
-
-    close_capture ();
+    if (is_capture_open()) {
+	_debug("AlsaLayer:: close ALSA capture\n");
+        if ((err = snd_pcm_close (_CaptureHandle)) < 0)
+	    _debug("Error closing ALSA capture: %s\n", snd_strerror(err));
+	else
+	    close_capture ();
+    }
 }
 
 void AlsaLayer::startCaptureStream (void)
 {
-    if (_CaptureHandle) {
-        _debug ("Start the capture\n");
-        snd_pcm_start (_CaptureHandle);
-        start_capture();
+    int err;
+
+    if (_CaptureHandle && !is_capture_running()) {
+        _debug ("AlsaLayer:: start ALSA capture\n");
+        if((err = snd_pcm_start (_CaptureHandle)) < 0)
+	    _debug("Error starting ALSA capture: %s\n",  snd_strerror(err));
+	else
+	    start_capture();
     }
 }
 
 void AlsaLayer::prepareCaptureStream (void)
 {
-    if (is_capture_open()) {
-        if (snd_pcm_prepare (_CaptureHandle) < 0)
-            _debug ("");
+    int err;
+
+    if (is_capture_open() && !is_capture_prepared()) {
+	_debug("AlsaLayer:: prepare ALSA capture\n");
+        if ((err = snd_pcm_prepare (_CaptureHandle)) < 0)
+            _debug ("Error preparing ALSA capture: %s\n", snd_strerror(err));
         else
             prepare_capture ();
     }
@@ -266,38 +322,57 @@ void AlsaLayer::prepareCaptureStream (void)
 
 void AlsaLayer::stopPlaybackStream (void)
 {
-    if (_PlaybackHandle) {
-        snd_pcm_drop (_PlaybackHandle);
-        stop_playback ();
+    int err;
+
+    if (_PlaybackHandle && is_playback_running()) {
+	_debug("AlsaLayer:: stop ALSA playback\n");
+        if((err = snd_pcm_drop (_PlaybackHandle)) < 0)
+	    _debug("Error stopping ALSA playback: %s\n", snd_strerror(err));
+	else
+	    stop_playback ();
     }
 }
 
 
 void AlsaLayer::closePlaybackStream (void)
 {
+    int err;
+
     if (is_playback_prepared() == true && is_playback_running() == true)
         stopPlaybackStream ();
 
-    if (is_playback_open())
-        snd_pcm_close (_PlaybackHandle);
-
-    close_playback ();
+    if (is_playback_open()) {
+	_debug("AlsaLayer:: close ALSA playback\n");
+        if ((err = snd_pcm_close (_PlaybackHandle)) < 0)
+	    _debug("Error closing ALSA playback: %s\n", snd_strerror(err));
+        else
+	    close_playback ();
+    }
 }
 
 void AlsaLayer::startPlaybackStream (void)
 {
-    if (_PlaybackHandle) {
-        snd_pcm_start (_PlaybackHandle);
-        start_playback();
+    int err;
+
+    if (_PlaybackHandle && !is_playback_running()) {
+	_debug ("AlsaLayer:: start ALSA playback\n");
+        if ((err = snd_pcm_start (_PlaybackHandle)) < 0)
+	    _debug("Error starting ALSA playback: %s\n", snd_strerror(err));
+	else
+	    start_playback();
     }
 }
 
 void AlsaLayer::preparePlaybackStream (void)
 {
-    if (is_playback_open()) {
-        if (snd_pcm_prepare (_PlaybackHandle) < 0)  _debug ("Error preparing the device\n");
+    int err;
 
-        prepare_playback ();
+    if (is_playback_open() && !is_playback_prepared()) {
+	_debug("AlsaLayer:: prepare playback stream\n");
+        if ((err = snd_pcm_prepare (_PlaybackHandle)) < 0)  
+	    _debug ("Error preparing the device: %s\n", snd_strerror(err));
+	else
+	    prepare_playback ();
     }
 }
 
@@ -431,6 +506,8 @@ AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, int flag)
     int err;
 
     if (flag == SFL_PCM_BOTH || flag == SFL_PCM_PLAYBACK) {
+
+	_debug("AlsaLayer:: open playback device\n");
         // if((err = snd_pcm_open(&_PlaybackHandle, pcm_p.c_str(),  SND_PCM_STREAM_PLAYBACK, 0 )) < 0){
         if ( (err = snd_pcm_open (&_PlaybackHandle, pcm_p.c_str(),  SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
             _debugAlsa ("Error while opening playback device %s\n",  pcm_p.c_str());
@@ -450,6 +527,8 @@ AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, int flag)
     }
 
     if (flag == SFL_PCM_BOTH || flag == SFL_PCM_CAPTURE) {
+
+	_debug("AlsaLayer:: open capture device\n");
         if ( (err = snd_pcm_open (&_CaptureHandle,  pcm_c.c_str(),  SND_PCM_STREAM_CAPTURE, 0)) < 0) {
             _debugAlsa ("Error while opening capture device %s\n",  pcm_c.c_str());
             setErrorMessage (ALSA_CAPTURE_DEVICE);
@@ -466,15 +545,17 @@ AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, int flag)
 
         open_capture ();
 
-        prepare_capture ();
+        // prepare_capture ();
     }
 
     /* Start the secondary audio thread for callbacks */
+    /*
     try {
         _audioThread->start();
     } catch (...) {
         _debugException ("Fail to start audio thread\n");
     }
+    */
 
     return true;
 }
@@ -570,6 +651,8 @@ AlsaLayer::read (void* buffer, int toCopy)
 void
 AlsaLayer::handle_xrun_capture (void)
 {
+    _debugAlsa("handle_xrun_capture\n");
+
     snd_pcm_status_t* status;
     snd_pcm_status_alloca (&status);
 
@@ -588,6 +671,8 @@ AlsaLayer::handle_xrun_capture (void)
 void
 AlsaLayer::handle_xrun_playback (void)
 {
+    _debugAlsa("AlsaLayer:: handle_xrun_playback\n");
+
     int state;
     snd_pcm_status_t* status;
     snd_pcm_status_alloca (&status);
@@ -729,6 +814,7 @@ void AlsaLayer::audioCallback (void)
     int toGet, urgentAvailBytes, normalAvailBytes, maxBytes;
     unsigned short spkrVolume, micVolume;
     AudioLoop *tone;
+    AudioLoop *file_tone;
 
     SFLDataFormat *out;
     SFLDataFormat *rsmpl_out;
@@ -759,8 +845,10 @@ void AlsaLayer::audioCallback (void)
     } else {
 
         tone = _manager->getTelephoneTone();
-        toGet = 940  ;
-        maxBytes = toGet * sizeof (SFLDataFormat)  ;
+	file_tone = _manager->getTelephoneFile();
+
+        toGet = framesPerBufferAlsa;
+        maxBytes = toGet * sizeof (SFLDataFormat);
 
         if (tone != 0) {
 
@@ -771,10 +859,10 @@ void AlsaLayer::audioCallback (void)
 	    free(out);
 	    out = 0;
 
-        } else if ( (tone=_manager->getTelephoneFile()) != 0) {
+        } else if (file_tone != 0) {
 
             out = (SFLDataFormat*) malloc (maxBytes * sizeof (SFLDataFormat));
-            tone->getNext (out, toGet, spkrVolume);
+            file_tone->getNext(out, toGet, spkrVolume);
             write (out , maxBytes);
 
 	    free(out);
@@ -822,7 +910,6 @@ void AlsaLayer::audioCallback (void)
 		    // Do sample rate conversion
 		    int nb_sample_down = toGet / sizeof(SFLDataFormat);
 
-
 		    int nbSample = _converter->upsampleData((SFLDataFormat*)out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_down);
 
 		    
@@ -840,7 +927,11 @@ void AlsaLayer::audioCallback (void)
 
             } else {
 
-		bzero (out, maxNbBytesToGet);
+		if((tone == 0) && (file_tone == 0)) {
+
+		    bzero (out, maxNbBytesToGet);
+		    write (out, maxNbBytesToGet);
+		}
             }
 
 	    _urgentRingBuffer.Discard (toGet); 
@@ -865,11 +956,11 @@ void AlsaLayer::audioCallback (void)
     {
 	
         micAvailBytes = snd_pcm_avail_update(_CaptureHandle);
-	
+	// _debug("micAvailBytes %i\n", micAvailBytes);
 	if(micAvailBytes > 0) 
 	{
             micAvailPut = _mainBuffer.availForPut();
-            toPut = (micAvailBytes <= micAvailPut) ? micAvailBytes : micAvailPut;
+            toPut = (micAvailBytes <= framesPerBufferAlsa) ? micAvailBytes : framesPerBufferAlsa;
             in = (SFLDataFormat*)malloc(toPut * sizeof(SFLDataFormat));
             toPut = read (in, toPut* sizeof(SFLDataFormat));
 
@@ -886,6 +977,7 @@ void AlsaLayer::audioCallback (void)
 		    int nbSample = toPut / sizeof(SFLDataFormat);
 		    int nb_sample_up = nbSample;
 
+		    // _debug("nb_sample_up %i\n", nb_sample_up);
 		    nbSample = _converter->downsampleData ((SFLDataFormat*)in, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_up);
 
 		    dcblocker->filter_signal(rsmpl_out, nbSample);
diff --git a/sflphone-common/src/audio/alsa/alsalayer.h b/sflphone-common/src/audio/alsa/alsalayer.h
index e1d4b189b78d3b79c7ae5194a3751e04fc4e7044..1f5167ede252b9516c55df316e10763c3dfcd036 100644
--- a/sflphone-common/src/audio/alsa/alsalayer.h
+++ b/sflphone-common/src/audio/alsa/alsalayer.h
@@ -265,13 +265,12 @@ class AlsaLayer : public AudioLayer {
     bool _is_open_capture;
     bool _trigger_request;
     
-    AudioThread *_audioThread;
+    AudioThread* _audioThread;
 
     /** Sample rate converter object */
-    SamplerateConverter * _converter;
-
-    int _converterSamplingRate;
+    SamplerateConverter* _converter;
 
+    // Allpass filter to remove DC offset
     DcBlocker* dcblocker;
 
 };
diff --git a/sflphone-common/src/audio/audiolayer.cpp b/sflphone-common/src/audio/audiolayer.cpp
index 9f1119ff694baf871e77d9fa9c17b4b13818a667..8966eb6aba086a30183d9dfa048ec3d42f5350f8 100644
--- a/sflphone-common/src/audio/audiolayer.cpp
+++ b/sflphone-common/src/audio/audiolayer.cpp
@@ -24,13 +24,13 @@ void AudioLayer::flushMain (void)
     ost::MutexLock guard (_mutex);
 
     // should pass call id 
-    _mainBuffer.flush();
+    _mainBuffer.flushAllBuffers();
 }
 
 void AudioLayer::flushUrgent (void)
 {
     ost::MutexLock guard (_mutex);
-    _urgentRingBuffer.flush();
+    _urgentRingBuffer.flushAll();
 }
 
 void AudioLayer::flushMic (void)
diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.h b/sflphone-common/src/audio/audiortp/AudioRtpSession.h
index bed84b1c3d3956e64170e2e2507f2dc14e0f9967..3ac8916b3aa4dbb20093b47d40500406647156ec 100644
--- a/sflphone-common/src/audio/audiortp/AudioRtpSession.h
+++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.h
@@ -498,10 +498,12 @@ namespace sfl {
         }
 
 	_ca->setRecordingSmplRate(_audiocodec->getClockRate());
-
+ 
         _audiolayer->startStream();
         static_cast<D*>(this)->startRunning();
 
+	_audiolayer->flushUrgent();
+
         _debug ("Entering RTP mainloop for callid %s\n",_ca->getCallId().c_str());
 
         while (!testCancel()) {
diff --git a/sflphone-common/src/audio/pulseaudio/audiostream.cpp b/sflphone-common/src/audio/pulseaudio/audiostream.cpp
index e30f40f78b200cdf0845cc5394b8c709a2a7af6e..deaab30f5b545228952e237fd4ba8c52b43f8ead 100644
--- a/sflphone-common/src/audio/pulseaudio/audiostream.cpp
+++ b/sflphone-common/src/audio/pulseaudio/audiostream.cpp
@@ -20,7 +20,7 @@
 #include <audiostream.h>
 #include "pulselayer.h"
 
-static pa_channel_map channel_map ;
+static pa_channel_map channel_map;
 
 
 AudioStream::AudioStream (PulseLayerType * driver)
@@ -31,7 +31,7 @@ AudioStream::AudioStream (PulseLayerType * driver)
         _volume(),
         flag (PA_STREAM_AUTO_TIMING_UPDATE),
         sample_spec(),
-        _mainloop (driver->mainloop)
+	_mainloop (driver->mainloop)
 {
     sample_spec.format = PA_SAMPLE_S16LE;
     sample_spec.rate = 44100;
@@ -99,7 +99,7 @@ AudioStream::disconnectStream (void)
 {
     _debug ("Destroy audio streams\n");
 
-    pa_threaded_mainloop_lock (_mainloop);
+    // pa_threaded_mainloop_lock (_mainloop);
 
     if (_audiostream) {
         pa_stream_disconnect (_audiostream);
@@ -107,7 +107,7 @@ AudioStream::disconnectStream (void)
         _audiostream = NULL;
     }
 
-    pa_threaded_mainloop_unlock (_mainloop);
+    // pa_threaded_mainloop_unlock (_mainloop);
 
     return true;
 }
@@ -136,7 +136,6 @@ AudioStream::stream_state_callback (pa_stream* s, void* user_data)
             break;
 
         case PA_STREAM_READY:
-
             _debug ("Stream successfully created, connected to %s\n", pa_stream_get_device_name (s));
             // pa_stream_cork( s, 0, NULL, NULL);
             break;
@@ -187,9 +186,9 @@ AudioStream::createStream (pa_context* c)
     if (_streamType == PLAYBACK_STREAM) {
         attributes->maxlength = 16000;
         attributes->tlength = 2048;
-        attributes->prebuf = 1024;
+        attributes->prebuf = 2048;
         attributes->minreq = 1024;
-        attributes->fragsize = 1024;
+        attributes->fragsize = 4096;
         pa_stream_connect_playback( s , NULL , attributes, PA_STREAM_INTERPOLATE_TIMING, &_volume, NULL);
         // pa_stream_connect_playback (s , NULL , attributes, PA_STREAM_START_CORKED, &_volume, NULL);
     } else if (_streamType == CAPTURE_STREAM) {
diff --git a/sflphone-common/src/audio/pulseaudio/audiostream.h b/sflphone-common/src/audio/pulseaudio/audiostream.h
index 3f6e25c66c27fb7221ea9740e4a1434432e121c0..40fa26e50e663300876f63478fcbe2d93c9941cc 100644
--- a/sflphone-common/src/audio/pulseaudio/audiostream.h
+++ b/sflphone-common/src/audio/pulseaudio/audiostream.h
@@ -183,6 +183,8 @@ class AudioStream {
     
     ost::Mutex _mutex;
 
+    bool _stream_is_ready;
+
 };
 
 #endif // _AUDIO_STREAM_H
diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
index cea5e4eeccff50329d87b621a2f4eef1561f00da..2ce375a3ca788d6e4d486fe37dd178190b3ed6cf 100644
--- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
+++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
@@ -25,7 +25,7 @@ int framesPerBuffer = 2048;
 
 static  void playback_callback (pa_stream* s, size_t bytes, void* userdata)
 {
-    _debug("playback_callback\n");
+    // _debug("playback_callback\n");
 
     assert (s && bytes);
     assert (bytes > 0);
@@ -112,10 +112,12 @@ PulseLayer::closeLayer (void)
     }
 
     // playback->disconnectStream();
-    closePlaybackStream();
+    // closePlaybackStream();
 
     // record->disconnectStream();
-    closeCaptureStream();
+    // closeCaptureStream();
+
+    disconnectAudioStream();
 
     if (context) {
         pa_context_disconnect (context);
@@ -154,6 +156,8 @@ PulseLayer::connectPulseAudioServer (void)
 
     pa_threaded_mainloop_unlock (m);
 
+    _urgentRingBuffer.flushAll();
+
     //serverinfo();
     //muteAudioApps(99);
     _debug ("Context creation done\n");
@@ -189,15 +193,15 @@ void PulseLayer::context_state_callback (pa_context* c, void* user_data)
 
         default:
             _debug (" Error : %s\n" , pa_strerror (pa_context_errno (c)));
-            pulse->disconnectPulseAudioServer();
+            pulse->disconnectAudioStream();
             exit (0);
             break;
     }
 }
 
-bool PulseLayer::disconnectPulseAudioServer (void)
+bool PulseLayer::disconnectAudioStream (void)
 {
-    _debug (" PulseLayer::disconnectPulseAudioServer( void ) \n");
+    _debug (" PulseLayer::disconnectAudioStream( void ) \n");
 
     closePlaybackStream();
     
@@ -212,7 +216,7 @@ bool PulseLayer::disconnectPulseAudioServer (void)
 
 bool PulseLayer::createStreams (pa_context* c)
 {
-    _debug ("--------------------------------- PulseLayer::createStreams ---------------------\n");
+    _debug ("PulseLayer::createStreams\n");
 
     PulseLayerType * playbackParam = new PulseLayerType();
     playbackParam->context = c;
@@ -246,6 +250,8 @@ bool PulseLayer::createStreams (pa_context* c)
 
     pa_threaded_mainloop_signal (m , 0);
 
+    _urgentRingBuffer.flushAll();
+
 
     return true;
 }
@@ -253,42 +259,23 @@ bool PulseLayer::createStreams (pa_context* c)
 
 bool PulseLayer::openDevice (int indexIn UNUSED, int indexOut UNUSED, int sampleRate, int frameSize , int stream UNUSED, std::string plugin UNUSED)
 {
-
-    _debug ("PulseLayer::openDevice \n");
     _audioSampleRate = sampleRate;
     _frameSize = frameSize;
 
-    /*
-    m = pa_threaded_mainloop_new();
-    assert (m);
-    if (pa_threaded_mainloop_start (m) < 0) {
-        _debug ("Failed starting the mainloop\n");
-    }
-    */
-
-    /*
-    // Instanciate a context
-    if (! (context = pa_context_new (pa_threaded_mainloop_get_api (m) , "SFLphone")))
-        _debug ("Error while creating the context\n");
-
-    assert (context);
-    */
-
-    // connectPulseAudioServer();
-
-    // startStream();
+    _urgentRingBuffer.flushAll();
 
     _converter = new SamplerateConverter (_audioSampleRate, _frameSize);
 
-    _debug ("Connection Done!! \n");
-
     return true;
 }
 
 void PulseLayer::closeCaptureStream (void)
 {
     if (record) {
+
+	pa_threaded_mainloop_lock (m);
 	delete record;
+	pa_threaded_mainloop_unlock (m);
 	record=NULL;
     }
 }
@@ -296,7 +283,10 @@ void PulseLayer::closeCaptureStream (void)
 void PulseLayer::closePlaybackStream (void)
 {
     if (playback) {
+
+	pa_threaded_mainloop_lock (m);
 	delete playback;
+	pa_threaded_mainloop_unlock (m);
 	playback=NULL;
     }
 }
@@ -323,9 +313,11 @@ void PulseLayer::startStream (void)
 
     if(!is_started) {
 
-	_debug ("------------------------ PulseLayer::Start stream ---------------\n");
+	_debug ("PulseLayer::Start Stream\n");
 
 	if (!m) {
+
+	    _debug("Creating PulseAudio MainLoop\n");
 	    m = pa_threaded_mainloop_new();
 	    assert (m);
 	
@@ -336,28 +328,22 @@ void PulseLayer::startStream (void)
 
 	if (!context) {
 
+	    _debug("Creating new PulseAudio Context\n");
+	    pa_threaded_mainloop_lock (m);
 	    // Instanciate a context
 	    if (! (context = pa_context_new (pa_threaded_mainloop_get_api (m) , "SFLphone")))
 		_debug ("Error while creating the context\n");
+	    pa_threaded_mainloop_unlock (m);
 	    
 	    assert (context);
 	}
 
 	_urgentRingBuffer.flush();
-
 	_mainBuffer.flushAllBuffers();
 
+	// Create Streams
 	connectPulseAudioServer();
 
-	// pa_threaded_mainloop_lock (m);
-
-	// pa_stream_cork (playback->pulseStream(), 0, NULL, NULL);
-	// pa_stream_cork (record->pulseStream(), 0, NULL, NULL);
-
-	// pa_threaded_mainloop_unlock (m);
-
-	// createStreams(context);
-
 	is_started = true;
     }
 
@@ -369,32 +355,30 @@ PulseLayer::stopStream (void)
 
     if(is_started) {
 
-	_debug ("------------------------ PulseLayer::Stop stream ---------------\n");
+	_debug ("PulseLayer::Stop Audio Stream\n");
 	pa_stream_flush (playback->pulseStream(), NULL, NULL);
 	pa_stream_flush (record->pulseStream(), NULL, NULL);
 
-	flushMic();
-	flushMain();
-	flushUrgent();
-
-	// closeCaptureStream();
-	// closePlaybackStream();
+	disconnectAudioStream();
 
-	disconnectPulseAudioServer();
+	if (m) {
+	    pa_threaded_mainloop_stop (m);
+	}
 
-	// pa_threaded_mainloop_lock (m);
-	
-	// pa_stream_cork (playback->pulseStream(), 1, NULL, NULL);
-	// pa_stream_cork (record->pulseStream(), 1, NULL, NULL);
 
-	// pa_threaded_mainloop_unlock (m);
+	_debug("Disconnecting PulseAudio context\n");
 
 	if (context) {
+
+	    pa_threaded_mainloop_lock (m);
 	    pa_context_disconnect (context);
 	    pa_context_unref (context);
+	    pa_threaded_mainloop_unlock (m);
 	    context = NULL;
 	}
 
+	_debug("Freeing Pulseaudio mainloop\n");
+
 	if (m) {
 	    pa_threaded_mainloop_free (m);
 	    m = NULL;
@@ -428,6 +412,8 @@ void PulseLayer::processPlaybackData (void)
     // Handle the data for the speakers
     if ( playback &&(playback->pulseStream()) && (pa_stream_get_state (playback->pulseStream()) == PA_STREAM_READY)) {
 
+	// _debug("PulseLayer::processPlaybackData()\n");
+
         // If the playback buffer is full, we don't overflow it; wait for it to have free space
         if (pa_stream_writable_size (playback->pulseStream()) == 0)
             return;
@@ -462,12 +448,12 @@ void PulseLayer::writeToSpeaker (void)
 
     if (urgentAvailBytes > 0) {
 
-        // Urgent data (dtmf, incoming call signal) come first.
-        //_debug("Play urgent!: %i\e" , urgentAvail);
+        
         toGet = (urgentAvailBytes < (int) (framesPerBuffer * sizeof (SFLDataFormat))) ? urgentAvailBytes : framesPerBuffer * sizeof (SFLDataFormat);
         out = (SFLDataFormat*) pa_xmalloc (toGet * sizeof (SFLDataFormat));
         _urgentRingBuffer.Get (out, toGet, 100);
         pa_stream_write (playback->pulseStream(), out, toGet, NULL, 0, PA_SEEK_RELATIVE);
+
         // Consume the regular one as well (same amount of bytes)
         _mainBuffer.discard (toGet);
 
@@ -476,26 +462,35 @@ void PulseLayer::writeToSpeaker (void)
     } else {
 
         AudioLoop* tone = _manager->getTelephoneTone();
+	AudioLoop* file_tone = _manager->getTelephoneFile();
 
         if (tone != 0) {
 
-            toGet = framesPerBuffer;
-            out = (SFLDataFormat*) pa_xmalloc (toGet * sizeof (SFLDataFormat));
-            tone->getNext (out, toGet , 100);
-            pa_stream_write (playback->pulseStream(), out, toGet  * sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
+	    if (playback->getStreamState() == PA_STREAM_READY)
+	    {
+
+		toGet = framesPerBuffer;
+		out = (SFLDataFormat*) pa_xmalloc (toGet * sizeof (SFLDataFormat));
+		tone->getNext (out, toGet , 100);
+		pa_stream_write (playback->pulseStream(), out, toGet  * sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
 
-	    pa_xfree (out);
+		pa_xfree (out);
+	    }
         }
 
-        if ( (tone=_manager->getTelephoneFile()) != 0) {
+        if (file_tone != 0) {
+
+	    if (playback->getStreamState() == PA_STREAM_READY)
+	    {
 
-            toGet = framesPerBuffer;
-            toPlay = ( (int) (toGet * sizeof (SFLDataFormat)) > framesPerBuffer) ? framesPerBuffer : toGet * sizeof (SFLDataFormat) ;
-            out = (SFLDataFormat*) pa_xmalloc (toPlay);
-            tone->getNext (out, toPlay/2 , 100);
-            pa_stream_write (playback->pulseStream(), out, toPlay, NULL, 0, PA_SEEK_RELATIVE);
+		toGet = framesPerBuffer;
+		toPlay = ( (int) (toGet * sizeof (SFLDataFormat)) > framesPerBuffer) ? framesPerBuffer : toGet * sizeof (SFLDataFormat);
+		out = (SFLDataFormat*) pa_xmalloc (toPlay);
+		file_tone->getNext(out, toPlay/2 , 100);
+		pa_stream_write (playback->pulseStream(), out, toPlay, NULL, 0, PA_SEEK_RELATIVE);
 
-	    pa_xfree (out);
+		pa_xfree (out);
+	    }
 
         } else {
 
@@ -549,10 +544,11 @@ void PulseLayer::writeToSpeaker (void)
 
             } else {
 
-		_debug("send zeros......................\n");
+		if((tone == 0) && (file_tone == 0)) {
 
-                bzero (out, maxNbBytesToGet);
-		pa_stream_write (playback->pulseStream(), out, maxNbBytesToGet, NULL, 0, PA_SEEK_RELATIVE);
+		    bzero (out, maxNbBytesToGet);
+		    pa_stream_write (playback->pulseStream(), out, maxNbBytesToGet, NULL, 0, PA_SEEK_RELATIVE);
+		}
             }
 
 	    _urgentRingBuffer.Discard(toGet);
diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.h b/sflphone-common/src/audio/pulseaudio/pulselayer.h
index 151fdec00591edae24a8bc1c52d408792663f4bc..e4a4981e570ff6af9a774e82e9a7b396082d270a 100644
--- a/sflphone-common/src/audio/pulseaudio/pulselayer.h
+++ b/sflphone-common/src/audio/pulseaudio/pulselayer.h
@@ -172,7 +172,7 @@ class PulseLayer : public AudioLayer {
     /**
      * Close the connection with the local pulseaudio server
      */
-    bool disconnectPulseAudioServer( void );
+    bool disconnectAudioStream( void );
 
     /**
      * Get some information about the pulseaudio server
diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp
index 4055a143f154e96379c5d56054ac22e76aa11eed..5491f2fe9d44ecc3c7ad645ba6bda9daf1dc3a07 100644
--- a/sflphone-common/src/managerimpl.cpp
+++ b/sflphone-common/src/managerimpl.cpp
@@ -372,6 +372,7 @@ ManagerImpl::answerCall (const CallID& call_id)
 
     }
 
+
     if (!getAccountLink (account_id)->answer (call_id)) {
         // error when receiving...
         removeCallAccount (call_id);
@@ -427,10 +428,12 @@ ManagerImpl::hangupCall (const CallID& call_id)
 
     int nbCalls = getCallList().size();
 
+    // _debug("nbCalls: %i\n", nbCalls);
+
     audiolayer = getAudioDriver();
 
     // stop streams
-    if (! (nbCalls >= 1))
+    if (nbCalls <= 1)
     {
 	_debug("    hangupCall: stop audio stream, ther is only %i call(s) remaining\n", nbCalls);
         audiolayer->stopStream();
@@ -775,7 +778,20 @@ ManagerImpl::refuseCall (const CallID& id)
     AccountID accountid;
     bool returnValue;
 
-    stopTone (true);
+    stopTone (false);
+
+
+    int nbCalls = getCallList().size();
+
+    // AudioLayer* audiolayer = getAudioDriver();
+    
+    if (nbCalls <= 1)
+    {
+	_debug("    hangupCall: stop audio stream, ther is only %i call(s) remaining\n", nbCalls);
+	
+	AudioLayer* audiolayer = getAudioDriver();
+	audiolayer->stopStream();
+    }
 
     /* Direct IP to IP call */
 
@@ -807,6 +823,8 @@ ManagerImpl::refuseCall (const CallID& id)
         switchCall ("");
     }
 
+    
+
     return returnValue;
 }
 
@@ -1683,6 +1701,8 @@ ManagerImpl::playDtmf (char code, bool isTalking)
         // Put buffer to urgentRingBuffer
         // put the size in bytes...
         // so size * 1 channel (mono) * sizeof (bytes for the data)
+	audiolayer->flushUrgent();
+
         audiolayer->startStream();
         audiolayer->putUrgent (buf, size * sizeof (SFLDataFormat));
     }
@@ -1895,6 +1915,18 @@ ManagerImpl::peerHungupCall (const CallID& call_id)
 	if (isCurrentCall(call_id)) 
 	{
 	    stopTone (true);
+
+	    int nbCalls = getCallList().size();
+
+	    // stop streams
+	    if (nbCalls <= 1)
+	    {
+		_debug("    hangupCall: stop audio stream, ther is only %i call(s) remaining\n", nbCalls);
+		
+		AudioLayer* audiolayer = getAudioDriver();
+		audiolayer->stopStream();
+	    }
+	    
 	    switchCall ("");
 	}
     }
@@ -1998,6 +2030,12 @@ bool ManagerImpl::playATone (Tone::TONEID toneId)
 
     audiolayer = getAudioDriver();
 
+    
+    if (audiolayer) {
+	audiolayer->startStream();
+	audiolayer->flushUrgent();
+    }
+
     if (_telephoneTone != 0) {
         _toneMutex.enterMutex();
         _telephoneTone->setCurrentTone (toneId);
@@ -2007,6 +2045,7 @@ bool ManagerImpl::playATone (Tone::TONEID toneId)
         nbSamples = audioloop->getSize();
         SFLDataFormat buf[nbSamples];
 
+	
         if (audiolayer) {
             audiolayer->putUrgent (buf, nbSamples);
         } else
@@ -2130,12 +2169,8 @@ ManagerImpl::ringtone()
             _audiofile.start();
             _toneMutex.leaveMutex();
 
-            if (CHECK_INTERFACE (layer, ALSA)) {
-                //ringback();
-
-            } else {
-                audiolayer->startStream();
-            }
+            audiolayer->startStream();
+ 
         } else {
             ringback();
         }
@@ -2186,6 +2221,7 @@ void ManagerImpl::notificationIncomingCall (void)
         SFLDataFormat buf[nbSampling];
         tone.getNext (buf, tone.getSize());
         /* Put the data in the urgent ring buffer */
+	audiolayer->flushUrgent();
         audiolayer->putUrgent (buf, sizeof (SFLDataFormat) *nbSampling);
     }
 }
diff --git a/sflphone-common/test/audiolayerTest.cpp b/sflphone-common/test/audiolayerTest.cpp
index 92648bc20166977365ad0d5b0a34b7954f9e575e..1cdb792598329c7cbf492b68d5bc4cd4435a89c3 100644
--- a/sflphone-common/test/audiolayerTest.cpp
+++ b/sflphone-common/test/audiolayerTest.cpp
@@ -169,7 +169,7 @@ void AudioLayerTest::testPulseConnect()
     CPPUNIT_ASSERT (_pulselayer->getRecordStream()->getStreamState() == 1);
 
     // usleep(1000000);
-    CPPUNIT_ASSERT (_pulselayer->disconnectPulseAudioServer() == true);
+    CPPUNIT_ASSERT (_pulselayer->disconnectAudioStream() == true);
 }