diff --git a/linphone/linphone.kdevelop b/linphone/linphone.kdevelop
index e5a3d2ce64470f3d5d5c5f2354464093384670a9..ee96b41389ccb3e138ad9010a8f80f4df922be08 100644
--- a/linphone/linphone.kdevelop
+++ b/linphone/linphone.kdevelop
@@ -387,6 +387,7 @@
       <path>win32acm/wine/winuser.h</path>
       <path>win32acm/wineacm.h</path>
       <path>win32acm/wrapper.h</path>
+      <path>builddate.h</path>
     </blacklist>
     <build>
       <buildtool>make</buildtool>
diff --git a/linphone/mediastreamer2/include/mediastreamer2/mediastream.h b/linphone/mediastreamer2/include/mediastreamer2/mediastream.h
index bdc3eff71d7ea56a19df0c88fc328111defd4691..9224d920a2f7abf20131e6471fede521d60bc617 100644
--- a/linphone/mediastreamer2/include/mediastreamer2/mediastream.h
+++ b/linphone/mediastreamer2/include/mediastreamer2/mediastream.h
@@ -57,6 +57,7 @@ struct _AudioStream
 	bool_t use_gc;
 	bool_t use_agc;
 	bool_t eq_active;
+	bool_t use_ng;/*noise gate*/
 };
 
 #ifdef __cplusplus
@@ -114,6 +115,9 @@ void audio_stream_enable_automatic_gain_control(AudioStream *stream, bool_t val)
 
 void audio_stream_set_mic_gain(AudioStream *stream, float gain);
 
+/*enable noise gate, must be done before start()*/
+void audio_stream_enable_noise_gate(AudioStream *stream, bool_t val);
+
 /*enable parametric equalizer in the stream that goes to the speaker*/
 void audio_stream_enable_equalizer(AudioStream *stream, bool_t enabled);
 
diff --git a/linphone/mediastreamer2/include/mediastreamer2/msvolume.h b/linphone/mediastreamer2/include/mediastreamer2/msvolume.h
index 14574eecdd1785029d24403ab14e022d337d68d9..9599a810717aa6daadc48d37ffeb80c866d2a44c 100644
--- a/linphone/mediastreamer2/include/mediastreamer2/msvolume.h
+++ b/linphone/mediastreamer2/include/mediastreamer2/msvolume.h
@@ -50,6 +50,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #define MS_VOLUME_ENABLE_AGC		MS_FILTER_METHOD(MS_VOLUME_ID,8,int)
 
+#define MS_VOLUME_ENABLE_NOISE_GATE	MS_FILTER_METHOD(MS_VOLUME_ID,9,int)
+
 extern MSFilterDesc ms_volume_desc;
 
 #endif
diff --git a/linphone/mediastreamer2/src/audiostream.c b/linphone/mediastreamer2/src/audiostream.c
index 6105140c73167f84eaa0db5700e24f85e08eb62f..4eec84a1b7e0f8d6bb2aa1c772e620d1d2e9c9be 100644
--- a/linphone/mediastreamer2/src/audiostream.c
+++ b/linphone/mediastreamer2/src/audiostream.c
@@ -250,7 +250,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
 		ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
 	}
 
-	if (stream->el_type!=ELInactive || stream->use_gc){
+	if (stream->el_type!=ELInactive || stream->use_gc || stream->use_ng){
 		stream->volsend=ms_filter_new(MS_VOLUME_ID);
 		stream->volrecv=ms_filter_new(MS_VOLUME_ID);
 		if (stream->el_type!=ELInactive){
@@ -258,6 +258,10 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
 				ms_filter_call_method(stream->volrecv,MS_VOLUME_SET_PEER,stream->volsend);
 			else ms_filter_call_method(stream->volsend,MS_VOLUME_SET_PEER,stream->volrecv);
 		}
+		if (stream->use_ng){
+			int tmp=1;
+			ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_NOISE_GATE,&tmp);
+		}
 	}
 
 	if (stream->use_agc){
@@ -409,6 +413,7 @@ AudioStream *audio_stream_new(int locport, bool_t ipv6){
 	stream->play_dtmfs=TRUE;
 	stream->use_gc=FALSE;
 	stream->use_agc=FALSE;
+	stream->use_ng=FALSE;
 	return stream;
 }
 
@@ -437,6 +442,10 @@ void audio_stream_enable_automatic_gain_control(AudioStream *stream, bool_t val)
 	stream->use_agc=val;
 }
 
+void audio_stream_enable_noise_gate(AudioStream *stream, bool_t val){
+	stream->use_ng=val;
+}
+
 void audio_stream_set_mic_gain(AudioStream *stream, float gain){
 	if (stream->volsend){
 		ms_filter_call_method(stream->volsend,MS_VOLUME_SET_GAIN,&gain);
diff --git a/linphone/mediastreamer2/src/msvolume.c b/linphone/mediastreamer2/src/msvolume.c
index 664eb94c9b5c231ace77e615d51d216928c23699..3c59553a3fb0a388fde51d60e4cedbcd3588da72 100644
--- a/linphone/mediastreamer2/src/msvolume.c
+++ b/linphone/mediastreamer2/src/msvolume.c
@@ -38,20 +38,24 @@ static const float noise_thres=0.1;
 typedef struct Volume{
 	float energy;
 	float norm_en;
-	float gain;
-	float static_gain;
+	float gain; /*the one really applied, smoothed by noise gate and echo limiter*/
+	float static_gain; /*the one fixed by the user*/
 	float gain_k;
 	float thres;
 	float force;
+	float target_gain; /*the target gain choosed by echo limiter and noise gate*/
 	MSFilter *peer;
 #ifdef HAVE_SPEEXDSP
 	SpeexPreprocessState *speex_pp;
 #endif
 	int sample_rate;
 	int nsamples;
+	int ng_cut_time; /*noise gate cut time, after last speech detected*/
+	int ng_noise_dur;
 	MSBufferizer *buffer;
 	bool_t ea_active;
 	bool_t agc_enabled;
+	bool_t noise_gate_enabled;
 }Volume;
 
 static void volume_init(MSFilter *f){
@@ -68,6 +72,9 @@ static void volume_init(MSFilter *f){
 	v->buffer=ms_bufferizer_new();
 	v->sample_rate=8000;
 	v->nsamples=80;
+	v->noise_gate_enabled=FALSE;
+	v->ng_cut_time=100;/*milliseconds*/
+	v->ng_noise_dur=0;
 #ifdef HAVE_SPEEXDSP
 	v->speex_pp=NULL;
 #endif
@@ -130,7 +137,6 @@ static void volume_echo_avoider_process(Volume *v){
 			gain=v->static_gain;
 			v->ea_active=FALSE;
 		}
-		v->gain=(v->gain*(1-v->gain_k)) + (v->gain_k*gain);
 	}else{
 		int peer_active=FALSE;
 		ms_filter_call_method(v->peer,MS_VOLUME_GET_EA_STATE,&peer_active);
@@ -141,17 +147,29 @@ static void volume_echo_avoider_process(Volume *v){
 			v->gain=gain;
 		}else {
 			gain=v->static_gain;
-			v->gain=(v->gain*(1-v->gain_k)) + (v->gain_k*gain);
 		}
 	}
-	
+	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);
 }
 
+static void volume_noise_gate_process(Volume *v , float energy, mblk_t *om){
+	int nsamples=((om->b_wptr-om->b_rptr)/2);
+	if ((energy/max_e)<v->thres){
+		v->ng_noise_dur+=(nsamples*1000)/v->sample_rate;
+		if (v->ng_noise_dur>v->ng_cut_time){
+			v->target_gain=0;
+		}
+	}else{
+		v->ng_noise_dur=0;
+		/*let the target gain unchanged, ie let the echo-limiter choose the gain*/
+	}
+}
+
 static int volume_set_gain(MSFilter *f, void *arg){
 	float *farg=(float*)arg;
 	Volume *v=(Volume*)f->data;
-	v->gain=v->static_gain=*farg;
+	v->gain=v->static_gain=v->target_gain=*farg;
 	return 0;
 }
 
@@ -205,6 +223,12 @@ static int volume_set_ea_force(MSFilter *f, void*arg){
 	return 0;
 }
 
+static int volume_enable_noise_gate(MSFilter *f, void *arg){
+	Volume *v=(Volume*)f->data;
+	v->noise_gate_enabled=*(int*)arg;
+	return 0;
+}
+
 static inline int16_t saturate(float val){
 	return (val>32767) ? 32767 : ( (val<-32767) ? -32767 : val);
 }
@@ -219,13 +243,17 @@ static float update_energy(int16_t *signal, int numsamples, float last_energy_va
 	return en;
 }
 
-static void apply_gain(mblk_t *m, float gain){
+static void apply_gain(Volume *v, mblk_t *m){
 	int16_t *sample;
+	float gain=v->target_gain;
+
+	if (gain==1 && v->gain==1) return;
+	v->gain=(v->gain*(1-v->gain_k)) + (v->gain_k*gain);
 	for (	sample=(int16_t*)m->b_rptr;
 				sample<(int16_t*)m->b_wptr;
 				++sample){
 		float s=*sample;
-		*sample=saturate(s*gain);
+		*sample=saturate(s*v->gain);
 	}
 }
 
@@ -273,10 +301,11 @@ static void volume_process(MSFilter *f){
 	
 			if (v->peer){
 				volume_echo_avoider_process(v);	
-			}
-			if (v->gain!=1){
-				apply_gain(om,v->gain);
-			}
+			}else v->target_gain=v->static_gain;
+
+			if (v->noise_gate_enabled)
+				volume_noise_gate_process(v,en,om);
+			apply_gain(v,om);
 			ms_queue_put(f->outputs[0],om);
 		}
 	}else{
@@ -285,10 +314,11 @@ static void volume_process(MSFilter *f){
 			en=update_energy((int16_t*)m->b_rptr,(m->b_wptr-m->b_rptr)/2,en);
 			if (v->peer){
 				volume_echo_avoider_process(v);	
-			}
-			if (v->gain!=1){
-				apply_gain(m,v->gain);
-			}
+			}else v->target_gain=v->static_gain;
+
+			if (v->noise_gate_enabled)
+				volume_noise_gate_process(v,en,m);
+			apply_gain(v,m);
 			ms_queue_put(f->outputs[0],m);
 		}
 	}
@@ -306,6 +336,7 @@ static MSFilterMethod methods[]={
 	{	MS_VOLUME_SET_EA_FORCE	, 	volume_set_ea_force	},
 	{	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},
 	{	0			,	NULL			}
 };
 
diff --git a/linphone/mediastreamer2/tests/mediastream.c b/linphone/mediastreamer2/tests/mediastream.c
index b02df047e968dbc7bf6225736d66d6ba4c56d81a..0b1a58f758e917b41fd4dbee67faeeb54e01419d 100644
--- a/linphone/mediastreamer2/tests/mediastream.c
+++ b/linphone/mediastreamer2/tests/mediastream.c
@@ -40,6 +40,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 static int cond=1;
 
+static const char * capture_card=NULL;
+static bool_t use_ng=FALSE;
+
 static void stop_handler(int signum)
 {
 	cond--;
@@ -127,7 +130,9 @@ const char *usage="mediastream --local <port> --remote <ip:port> --payload <payl
 								"[ --height <pixels> ]\n"
 								"[ --bitrate <bits per seconds>]\n"
 								"[ --ec (enable echo canceller)]\n"
-								"[ --agc (enable automatic gain control)]\n";
+								"[ --agc (enable automatic gain control)]\n"
+								"[ --ng (enable noise gate)]\n"
+								"[ --capture-card <index>] \n";
 static void run_media_streams(int localport, const char *remote_ip, int remoteport, int payload, const char *fmtp, int jitter, bool_t ec, int bitrate, MSVideoSize vs, bool_t agc, bool_t eq);
 
 
@@ -193,12 +198,17 @@ int main(int argc, char * argv[])
 		}else if (strcmp(argv[i],"--height")==0){
 			i++;
 			vs.height=atoi(argv[i]);
+		}else if (strcmp(argv[i],"--capture-card")==0){
+			i++;
+			capture_card=argv[i];
 		}else if (strcmp(argv[i],"--ec")==0){
 			ec=TRUE;
 		}else if (strcmp(argv[i],"--agc")==0){
 			agc=TRUE;
 		}else if (strcmp(argv[i],"--eq")==0){
 			eq=TRUE;
+		}else if (strcmp(argv[i],"--ng")==0){
+			use_ng=1;
 		}
 	}
 
@@ -230,11 +240,14 @@ void run_media_streams(int localport,  const char *remote_ip, int remoteport, in
 	if (pt->type!=PAYLOAD_VIDEO){
 		printf("Starting audio stream.\n");
 		MSSndCardManager *manager=ms_snd_card_manager_get();
+		MSSndCard *capt= capture_card==NULL ? ms_snd_card_manager_get_default_capture_card(manager) :
+				ms_snd_card_manager_get_card(manager,capture_card);
 		audio=audio_stream_new(localport,ms_is_ipv6(remote_ip));
 		audio_stream_enable_automatic_gain_control(audio,agc);
+		audio_stream_enable_noise_gate(audio,use_ng);
 		audio_stream_start_now(audio,profile,remote_ip,remoteport,remoteport+1,payload,jitter,
 			ms_snd_card_manager_get_default_playback_card(manager),
-			ms_snd_card_manager_get_default_capture_card(manager),
+			capt,
 			 ec);
 		if (audio) session=audio->session;
 	}else{