diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c
index 4e59a56808a27253e914d730d1151f30fc5350dd..2fcb0862a199101517d2c86698333632ffa6cc95 100644
--- a/linphone/coreapi/linphonecore.c
+++ b/linphone/coreapi/linphonecore.c
@@ -1565,6 +1565,7 @@ static void post_configure_audio_streams(LinphoneCore *lc){
 		float speed=lp_config_get_float(lc->config,"sound","el_speed",-1);
 		float thres=lp_config_get_float(lc->config,"sound","el_thres",-1);
 		float force=lp_config_get_float(lc->config,"sound","el_force",-1);
+		int sustain=lp_config_get_int(lc->config,"sound","el_sustain",-1);
 		float gain=lp_config_get_float(lc->config,"sound","mic_gain",-1);
 		MSFilter *f=NULL;
 		if (st->el_type==ELControlMic){
@@ -1583,6 +1584,8 @@ static void post_configure_audio_streams(LinphoneCore *lc){
 			ms_filter_call_method(f,MS_VOLUME_SET_EA_THRESHOLD,&thres);
 		if (force!=-1)
 			ms_filter_call_method(f,MS_VOLUME_SET_EA_FORCE,&force);
+		if (sustain!=-1)
+			ms_filter_call_method(f,MS_VOLUME_SET_EA_SUSTAIN,&sustain);
 		if (gain!=-1)
 			audio_stream_set_mic_gain(st,gain);
 	}
diff --git a/linphone/mediastreamer2/include/mediastreamer2/msvolume.h b/linphone/mediastreamer2/include/mediastreamer2/msvolume.h
index 7fc46cdcdbac6104fb2edd6b8eba599d6995956f..052e3d1b99eeb325244c0a2cb9ab50ebee9a2e10 100644
--- a/linphone/mediastreamer2/include/mediastreamer2/msvolume.h
+++ b/linphone/mediastreamer2/include/mediastreamer2/msvolume.h
@@ -54,6 +54,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #define MS_VOLUME_SET_NOISE_GATE_THRESHOLD	MS_FILTER_METHOD(MS_VOLUME_ID,10,float)
 
+#define MS_VOLUME_SET_EA_SUSTAIN	MS_FILTER_METHOD(MS_VOLUME_ID,11,int)
+
+
 extern MSFilterDesc ms_volume_desc;
 
 #endif
diff --git a/linphone/mediastreamer2/src/msvolume.c b/linphone/mediastreamer2/src/msvolume.c
index ae642bde08a5ae0fcb1e81827cfe87f1be4b6069..1deb38b58d06ef33cd5f37d7241653c2dc339420 100644
--- a/linphone/mediastreamer2/src/msvolume.c
+++ b/linphone/mediastreamer2/src/msvolume.c
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #endif
 
 #include "mediastreamer2/msvolume.h"
+#include "mediastreamer2/msticker.h"
 #include <math.h>
 
 #ifdef HAVE_SPEEXDSP
@@ -44,6 +45,9 @@ typedef struct Volume{
 	float thres;
 	float force;
 	float target_gain; /*the target gain choosed by echo limiter and noise gate*/
+	float last_peer_en;
+	int sustain_time; /* time in ms for which echo limiter remains active after resuming from speech to silence.*/
+	uint64_t sustain_start;
 	MSFilter *peer;
 #ifdef HAVE_SPEEXDSP
 	SpeexPreprocessState *speex_pp;
@@ -69,6 +73,9 @@ static void volume_init(MSFilter *f){
 	v->thres=noise_thres;
 	v->force=en_weight;
 	v->peer=NULL;
+	v->last_peer_en=0;
+	v->sustain_time=200;
+	v->sustain_start=0;
 	v->agc_enabled=FALSE;
 	v->buffer=ms_bufferizer_new();
 	v->sample_rate=8000;
@@ -126,7 +133,15 @@ static inline float compute_gain(float static_gain, float energy, float weight){
 	return ret;
 }
 
-static void volume_echo_avoider_process(Volume *v){
+/*
+The principle of this algorithm is that we apply a gain to the input signal which is opposite to the 
+energy measured by the peer MSVolume.
+For example if some noise is played by the speaker, then the signal captured by the microphone will be lowered.
+The gain changes smoothly when the peer energy is decreasing, but is immediately changed when the peer energy is 
+increasing.
+*/
+
+static void volume_echo_avoider_process(Volume *v, uint64_t curtime){
 	float peer_e;
 	float gain;
 	ms_filter_call_method(v->peer,MS_VOLUME_GET_LINEAR,&peer_e);
@@ -135,9 +150,12 @@ static void volume_echo_avoider_process(Volume *v){
 		if (peer_e>v->thres){
 			/*lower our output*/
 			gain=compute_gain(v->static_gain,peer_e,v->force);
+			if (peer_e>v->last_peer_en)
+				v->gain=gain;
 		}else {
-			gain=v->static_gain;
+			v->sustain_start=curtime;
 			v->ea_active=FALSE;
+			gain=v->gain;
 		}
 	}else{
 		int peer_active=FALSE;
@@ -148,9 +166,15 @@ static void volume_echo_avoider_process(Volume *v){
 			v->ea_active=TRUE;
 			v->gain=gain;
 		}else {
-			gain=v->static_gain;
+			if (curtime!=0 && (curtime-v->sustain_start)<v->sustain_time){
+				gain=v->gain;
+			}else{/*restore normal gain*/
+				gain=v->static_gain;
+				v->sustain_start=0;
+			}
 		}
 	}
+	v->last_peer_en=peer_e;
 	v->target_gain=gain;
 	ms_message("ea_active=%i, peer_e=%f gain=%f gain_k=%f force=%f",v->ea_active,peer_e,v->gain, v->gain_k,v->force);
 }
@@ -225,6 +249,12 @@ static int volume_set_ea_force(MSFilter *f, void*arg){
 	return 0;
 }
 
+static int volume_set_ea_sustain(MSFilter *f, void *arg){
+	Volume *v=(Volume*)f->data;
+	v->sustain_time=*(int*)arg;
+	return 0;
+}
+
 static int volume_enable_noise_gate(MSFilter *f, void *arg){
 	Volume *v=(Volume*)f->data;
 	v->noise_gate_enabled=*(int*)arg;
@@ -308,7 +338,7 @@ static void volume_process(MSFilter *f){
 			volume_agc_process(v,om);
 	
 			if (v->peer){
-				volume_echo_avoider_process(v);	
+				volume_echo_avoider_process(v,f->ticker->time);
 			}else v->target_gain=v->static_gain;
 
 			if (v->noise_gate_enabled)
@@ -321,7 +351,7 @@ static void volume_process(MSFilter *f){
 		while((m=ms_queue_get(f->inputs[0]))!=NULL){
 			en=update_energy((int16_t*)m->b_rptr,(m->b_wptr-m->b_rptr)/2,en);
 			if (v->peer){
-				volume_echo_avoider_process(v);	
+				volume_echo_avoider_process(v,f->ticker->time);	
 			}else v->target_gain=v->static_gain;
 
 			if (v->noise_gate_enabled)
@@ -342,6 +372,7 @@ static MSFilterMethod methods[]={
 	{	MS_VOLUME_SET_EA_THRESHOLD , 	volume_set_ea_threshold	},
 	{	MS_VOLUME_SET_EA_SPEED	,	volume_set_ea_speed	},
 	{	MS_VOLUME_SET_EA_FORCE	, 	volume_set_ea_force	},
+	{	MS_VOLUME_SET_EA_SUSTAIN,	volume_set_ea_sustain	},
 	{	MS_FILTER_SET_SAMPLE_RATE,	volume_set_sample_rate	},
 	{	MS_VOLUME_ENABLE_AGC	,	volume_set_agc		},
 	{	MS_VOLUME_ENABLE_NOISE_GATE,	volume_enable_noise_gate},