diff --git a/sflphone-common/src/audio/echocancel.cpp b/sflphone-common/src/audio/echocancel.cpp
index 1eeb7b96c8916b3d17153b5f5aa13b9fc9c5023c..66e8780172a4db082dbdfaad9788cdfd727cfcef 100644
--- a/sflphone-common/src/audio/echocancel.cpp
+++ b/sflphone-common/src/audio/echocancel.cpp
@@ -52,6 +52,9 @@ EchoCancel::EchoCancel(int smplRate, int frameLength) : _samplingRate(smplRate),
   spkrFile = new ofstream("spkrData", ofstream::binary);
   */
 
+  micLearningData = new ofstream("micLearningData", ofstream::binary);
+  spkrLearningData = new ofstream("spkrLearningData", ofstream::binary);
+
   _micData = new RingBuffer(50000);
   _spkrData = new RingBuffer(50000);
 
@@ -115,11 +118,17 @@ EchoCancel::~EchoCancel()
   delete echoFile;
   */
 
+  micLearningData->close();
+  spkrLearningData->close();
+  delete micLearningData;
+  delete spkrLearningData;
+
 }
 
 void EchoCancel::reset()
 {
   _debug("EchoCancel: Reset internal state, Sampling rate %d, Frame size %d", _samplingRate, _smplPerFrame);
+  _debug("SIZEOF INT %d", sizeof(int));
   
   memset(_avgSpkrLevelHist, 0, BUFF_SIZE*sizeof(int));
   memset(_avgMicLevelHist, 0, BUFF_SIZE*sizeof(int));
@@ -139,11 +148,22 @@ void EchoCancel::reset()
   memset(_delayLineAmplify, 0, MAX_DELAY_LINE_AMPL*sizeof(float));
 
   _amplDelayIndexIn = 0;
-  _amplDelayIndexOut = DELAY_AMPLIFY / SEGMENT_LENGTH;
+  _amplDelayIndexOut = 0;
+
+  _adaptDone = false;
+  _adaptStarted = false;
+  _adaptCnt = 0;
+  _spkrAdaptCnt = 0;
+  _micAdaptCnt = 0;
 
   _micData->flushAll();
   _spkrData->flushAll();
 
+  // SFLDataFormat delay[960];
+  // memset(delay, 0, sizeof(SFLDataFormat));
+
+  // _micData->Put(delay, 960*2);
+
   speex_preprocess_state_destroy(_noiseState);
 
   _noiseState = speex_preprocess_state_init(_smplPerFrame, _samplingRate);
@@ -169,6 +189,7 @@ void EchoCancel::putData(SFLDataFormat *inputData, int nbBytes)
   // std::cout << "putData nbBytes: " << nbBytes << std::endl;
 
   if(_spkrStoped) {
+      _debug("EchoCancel: Flush data");
       _micData->flushAll();
       _spkrData->flushAll();
       _spkrStoped = false;
@@ -202,6 +223,8 @@ int EchoCancel::process(SFLDataFormat *inputData, SFLDataFormat *outputData, int
   int spkrAvail = _spkrData->AvailForGet();
   int micAvail = _micData->AvailForGet();
 
+  _debug("EchoCancel: speaker avail %d, mic avail %d", spkrAvail, micAvail);
+
   // Init number of frame processed
   int nbFrame = 0;
 
@@ -263,7 +286,8 @@ void EchoCancel::performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDa
 	increaseFactor(0.05);
       }
       else {
-	decreaseFactor();
+	// decreaseFactor();
+	_amplFactor = 0.0;
       }
     }
     else {
@@ -271,13 +295,13 @@ void EchoCancel::performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDa
 	increaseFactor(0.02);
       }
       else {
-	decreaseFactor();
+	// decreaseFactor();
+	_amplFactor = 0.0;
       }
     }
 
     // lowpass filtering
     float amplify = (_lastAmplFactor + _amplFactor) / 2;
-
     _lastAmplFactor = _amplFactor;
 
     amplifySignal(micData+(k*_smplPerSeg), outputData+(k*_smplPerSeg), amplify);
@@ -323,7 +347,8 @@ void EchoCancel::updateEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDat
   // perform correlation if spkr size is reached
   if(_adaptCnt > _spkrAdaptSize) {
       int k = _adaptCnt - _spkrAdaptSize;
-      _correlationArray[k] = performCorrelation(_spkrAdaptArray, _micAdaptArray+k, _correlationSize);   
+      _correlationArray[k] = performCorrelation(_spkrAdaptArray, _micAdaptArray+k, _correlationSize); 
+      _debug("EchoCancel: Correlation: %d", _correlationArray[k]);
   }
 
   _adaptCnt++;
@@ -333,6 +358,9 @@ void EchoCancel::updateEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrDat
     _debug("EchoCancel: Echo path adaptation completed");
     _adaptDone = true;
     _amplDelayIndexOut = getMaximumIndex(_correlationArray, _correlationSize);
+    _debug("EchoCancel: Echo length %d", _amplDelayIndexOut);
+    spkrLearningData->write((const char *)_spkrAdaptArray, _spkrAdaptSize*sizeof(int));
+    micLearningData->write((const char *)_micAdaptArray, _micAdaptSize*sizeof(int));
   }
     
 }
@@ -373,9 +401,23 @@ void EchoCancel::amplifySignal(SFLDataFormat *micData, SFLDataFormat *outputData
 
   // Use delayed amplification factor due to sound card latency 
   for(int i = 0; i < _smplPerSeg; i++) {
-    outputData[i] = (SFLDataFormat)(((float)micData[i])*_delayLineAmplify[_amplDelayIndexOut]);
+      outputData[i] = (SFLDataFormat)(((float)micData[i])*_delayLineAmplify[_amplDelayIndexOut]);
   }
 
+  // do not increment amplitude array if adaptation is not done 
+  if (_adaptDone) {
+    for(int i = 0; i < _smplPerSeg; i++) {
+        outputData[i] = (SFLDataFormat)(((float)micData[i])*_delayLineAmplify[_amplDelayIndexOut]);
+    }
+  }
+  else {
+    for(int i = 0; i < _smplPerSeg; i++) {
+        outputData[i] = micData[i];
+    }
+    return;
+  }
+
+
   _amplDelayIndexOut++;
   _delayLineAmplify[_amplDelayIndexIn++] = amplify;
 
diff --git a/sflphone-common/src/audio/echocancel.h b/sflphone-common/src/audio/echocancel.h
index 204aab32622c13dec5922715bfdb22f342527f91..a06863fa19d7d6e68aab2b8504ffce8b71c03795 100644
--- a/sflphone-common/src/audio/echocancel.h
+++ b/sflphone-common/src/audio/echocancel.h
@@ -32,7 +32,7 @@
 #define SEGMENT_LENGTH 10
 
 // Length of the echo tail in ms
-#define ECHO_LENGTH 100
+#define ECHO_LENGTH 50
 
 // Voice level threashold 
 #define MIN_SIG_LEVEL 100
@@ -41,7 +41,7 @@
 #define DELAY_AMPLIFY 60
 
 // maximum in segment size (segment are SEGMENT_LENGTH long)
-#define MAX_DELAY_LINE_AMPL 100
+#define MAX_DELAY_LINE_AMPL 100 // 1 sec
 
 // Internal buffer size
 #define BUFF_SIZE 10000
@@ -50,8 +50,8 @@
 
 #define DEFAULT_FRAME_LENGTH 20
 
-#define MIC_ADAPT_SIZE 100
-#define SPKR_ADAPT_SIZE 50
+#define MIC_ADAPT_SIZE 100 // 1 sec
+#define SPKR_ADAPT_SIZE 20 // 200 ms
 
 class EchoCancel : public Algorithm {
 
@@ -280,6 +280,9 @@ class EchoCancel : public Algorithm {
     ofstream *echoFile;
     */
 
+    ofstream *micLearningData;
+    ofstream *spkrLearningData;
+
     /**
      * Noise reduction processing state
      */
diff --git a/sflphone-common/src/audio/pulseaudio/audiostream.cpp b/sflphone-common/src/audio/pulseaudio/audiostream.cpp
index 1e10ed4ec0aa06b7dece2c8f126a080223aeefb3..8071844ffd820b96bb98ba3138b056456374caa3 100644
--- a/sflphone-common/src/audio/pulseaudio/audiostream.cpp
+++ b/sflphone-common/src/audio/pulseaudio/audiostream.cpp
@@ -204,6 +204,7 @@ AudioStream::createStream (pa_context* c, std::string *deviceName)
 	else
 	  pa_stream_connect_playback (s , NULL, attributes, (pa_stream_flags_t)(PA_STREAM_ADJUST_LATENCY|PA_STREAM_AUTO_TIMING_UPDATE), NULL, NULL);
 
+
 	pa_threaded_mainloop_unlock(_mainloop);
 
     } else if (_streamType == CAPTURE_STREAM) {
@@ -218,6 +219,7 @@ AudioStream::createStream (pa_context* c, std::string *deviceName)
 	else 
 	  pa_stream_connect_record (s, NULL, attributes, (pa_stream_flags_t) (PA_STREAM_ADJUST_LATENCY|PA_STREAM_AUTO_TIMING_UPDATE));
 
+
         pa_threaded_mainloop_unlock(_mainloop);
         
     } else if (_streamType == RINGTONE_STREAM) {
diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
index 5f9b6cb19366de3c500a0b8416b9cc8cf1a2359d..05ea09ec60082493a698536c9a1537bf4c8013fe 100644
--- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
+++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp
@@ -64,6 +64,24 @@ static void pa_success_callback(pa_context *c, int success, void *userdata) {
   _debug("Audio: Success callback");
 }
 
+static void latency_update_callback(pa_stream *p, void *userdata) {
+
+  pa_usec_t r_usec;
+  pa_buffer_attr *buffattr;
+
+  pa_stream_get_latency (p, &r_usec, NULL);	
+
+  // buffattr = pa_stream_get_buffer_attr(p);   	
+  
+    _debug("Audio: Stream letency update %0.0f ms for device %s", (float)r_usec/1000, pa_stream_get_device_name(p));
+  // _debug("Audio: maxlength %d", buffattr->maxlength);
+  // _debug("Audio: tlength %d", buffattr->tlength);
+  // _debug("Audio: prebug %d", buffattr->prebuf);
+  // _debug("Audio: minreq %d", buffattr->minreq);
+  // _debug("Audio: fragsize %d", buffattr->fragsize);
+  
+}
+
 static void sink_input_info_callback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) {
   char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
 
@@ -517,6 +535,7 @@ bool PulseLayer::createStreams (pa_context* c)
     pa_stream_set_underflow_callback (playback->pulseStream(), playback_underflow_callback, this);
     // pa_stream_set_suspended_callback(playback->pulseStream(), stream_suspended_callback, this);
     pa_stream_set_moved_callback(playback->pulseStream(), stream_moved_callback, this);
+    pa_stream_set_latency_update_callback(playback->pulseStream(), latency_update_callback, this);
     delete playbackParam;
 
     PulseLayerType * recordParam = new PulseLayerType();
@@ -536,6 +555,7 @@ bool PulseLayer::createStreams (pa_context* c)
     pa_stream_set_read_callback (record->pulseStream() , capture_callback, this);
     // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this);
     pa_stream_set_moved_callback(record->pulseStream(), stream_moved_callback, this);
+    pa_stream_set_latency_update_callback(record->pulseStream(), latency_update_callback, this);
     delete recordParam;
     
     PulseLayerType * ringtoneParam = new PulseLayerType();
@@ -896,8 +916,6 @@ void PulseLayer::readFromMic (void)
         _warn("Audio: Error capture stream peek failed: %s" , pa_strerror (pa_context_errno (context)));
     }
 
-    _debug("*********************** Read from mic: %d **************************", readableSize);
-
     if (data != 0) {
 
         int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
@@ -925,8 +943,6 @@ void PulseLayer::readFromMic (void)
 	    // echo cancellation processing
 	    int sampleready = _echoCanceller->processAudio(rsmpl_out, echoCancelledMic, nbSample*sizeof(SFLDataFormat));
 
-	    _debug("Read from mic: sampleReady %d", sampleready);
-
             // getMainBuffer()->putData ( (void*) rsmpl_out, nbSample*sizeof (SFLDataFormat), 100);
 	    if(sampleready)
 	      getMainBuffer()->putData ( echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100);
@@ -960,8 +976,6 @@ void PulseLayer::ringtoneToSpeaker(void)
 
   int writableSize = pa_stream_writable_size(ringtone->pulseStream());
 
-  _debug("writable size: %d", writableSize);
-
   if (file_tone) {
 
     if(ringtone->getStreamState() == PA_STREAM_READY) {