Changeset 1331:498cc1c1ce41 in mediastreamer2
- Timestamp:
- Mar 29, 2011 6:22:54 PM (2 years ago)
- Branch:
- default
- Files:
-
- 2 edited
-
src/speexec.c (modified) (9 diffs)
-
tests/mediastream.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/speexec.c
r1328 r1331 20 20 21 21 #include "mediastreamer2/msfilter.h" 22 #include "mediastreamer2/msticker.h" 22 23 #include <speex/speex_echo.h> 23 24 #include <speex/speex_preprocess.h> … … 44 45 MSBufferizer delayed_ref; 45 46 MSBufferizer echo; 46 int ref_bytes_limit;47 47 int framesize; 48 48 int filterlength; … … 50 50 int delay_ms; 51 51 int tail_length_ms; 52 float ref_bufsize_ms; 52 int nominal_ref_samples; 53 int min_ref_samples; 53 54 #ifdef EC_DUMP 54 55 FILE *echofile; 55 56 FILE *reffile; 56 57 #endif 57 bool_t using_silence;58 58 bool_t echostarted; 59 59 bool_t bypass_mode; 60 bool_t using_zeroes; 60 61 }SpeexECState; 61 62 … … 71 72 s->framesize=framesize; 72 73 s->den = NULL; 73 s->using_ silence=FALSE;74 s->using_zeroes=FALSE; 74 75 s->echostarted=FALSE; 75 76 s->bypass_mode=FALSE; … … 121 122 m->b_wptr+=delay_samples*2; 122 123 ms_bufferizer_put (&s->delayed_ref,m); 123 s-> ref_bufsize_ms=s->delay_ms;124 } 125 126 /* inputs[0]= reference signal (sent to soundcard)124 s->min_ref_samples=-1; 125 } 126 127 /* inputs[0]= reference signal from far end (sent to soundcard) 127 128 * inputs[1]= near speech & echo signal (read from soundcard) 128 * outputs[0]= far end speech129 * outputs[0]= is a copy of inputs[0] to be sent to soundcard 129 130 * outputs[1]= near end speech, echo removed - towards far end 130 131 */ … … 134 135 mblk_t *refm; 135 136 uint8_t *ref,*echo; 136 int size;137 float ref_bufsize_ms;138 int diff;139 int idiff;140 int drift;141 int threshold;142 137 143 138 if (s->bypass_mode) { … … 165 160 while (ms_bufferizer_read(&s->echo,echo,nbytes)>=nbytes){ 166 161 mblk_t *oecho=allocb(nbytes,0); 167 162 int avail; 163 164 if ((avail=ms_bufferizer_get_avail(&s->delayed_ref))<(s->nominal_ref_samples+nbytes)){ 165 /*we don't have enough to read in a reference signal buffer, inject silence instead*/ 166 refm=allocb(nbytes,0); 167 memset(refm->b_wptr,0,nbytes); 168 refm->b_wptr+=nbytes; 169 ms_bufferizer_put(&s->delayed_ref,refm); 170 if (!s->using_zeroes){ 171 ms_warning("Not enough ref samples, using zeroes"); 172 s->using_zeroes=TRUE; 173 } 174 }else if (s->using_zeroes){ 175 ms_message("Samples are back."); 176 s->using_zeroes=FALSE; 177 } 178 179 /*now read a valid buffer of ref samples*/ 168 180 if (ms_bufferizer_read(&s->delayed_ref,ref,nbytes)==0){ 169 /* if we don't have enough ref samples, use silence instead */ 170 ms_warning("Not enough ref samples, using zeroes"); 171 memset(ref,0,nbytes); 181 ms_fatal("Should never happen"); 182 } 183 avail-=nbytes; 184 if (avail<s->min_ref_samples || s->min_ref_samples==-1){ 185 s->min_ref_samples=avail; 172 186 } 173 187 … … 184 198 } 185 199 186 /* control the size of the delayed_ref bufferizer, we should always have in the long term a size 187 that corresponds to the echo delay*/ 188 size=ms_bufferizer_get_avail(&s->delayed_ref); 189 ref_bufsize_ms=((size/2)*1000.0)/(float)s->samplerate; 190 s->ref_bufsize_ms=smooth_factor*ref_bufsize_ms + (1-smooth_factor)*s->ref_bufsize_ms; 191 //ms_message("Averaged reference bufsize is %f, instant value is %f",s->ref_bufsize_ms,ref_bufsize_ms); 192 diff=((int)s->ref_bufsize_ms) - s->delay_ms; 193 idiff=((int)ref_bufsize_ms) - s->delay_ms; 194 threshold=s->tail_length_ms/4; 195 drift=diff; 196 if (diff > threshold && idiff>threshold) { 197 nbytes=2*(int)((drift*s->samplerate)/1000.0); 198 ms_warning("Averaged reference bufsize is %f while expected delay is %i, diff=%i, need to drop %i bytes",s->ref_bufsize_ms,s->delay_ms,diff,nbytes); 199 ms_bufferizer_skip_bytes(&s->delayed_ref,nbytes); 200 s->ref_bufsize_ms=s->delay_ms; 201 }else if ((diff < (-threshold)) && (idiff < (-threshold))){ 202 nbytes=2*(int)((-drift*s->samplerate)/1000.0); 203 ms_warning("Averaged reference bufsize is %f while expected delay is %i, diff=%i, need to add %i bytes",s->ref_bufsize_ms,s->delay_ms,diff,nbytes); 204 refm=allocb(nbytes,0); 205 memset(refm->b_wptr,0,nbytes); 206 refm->b_wptr+=nbytes; 207 ms_bufferizer_put(&s->delayed_ref,refm); 208 s->ref_bufsize_ms=s->delay_ms; 200 /*verify our ref buffer does not become too big, meaning that we are receiving more samples than we are sending*/ 201 if (f->ticker->time % 5000 == 0 && s->min_ref_samples!=-1){ 202 int diff=s->min_ref_samples-s->nominal_ref_samples; 203 if (diff>nbytes){ 204 ms_warning("echo canceller: we are accumulating too much reference signal, purging now %i bytes",nbytes); 205 ms_bufferizer_skip_bytes(&s->delayed_ref,nbytes); 206 } 207 s->min_ref_samples=-1; 209 208 } 210 209 } … … 306 305 307 306 MS_FILTER_DESC_EXPORT(ms_speex_ec_desc) 307 -
tests/mediastream.c
r1327 r1331 145 145 "[ --ec-tail <echo canceller tail length in ms> ]\n" 146 146 "[ --ec-delay <echo canceller delay in ms> ]\n" 147 "[ --ec-framesize <echo canceller framesize in samples> ]\n" 147 148 "[ --agc (enable automatic gain control)]\n" 148 149 "[ --ng (enable noise gate)]\n" … … 236 237 i++; 237 238 ec_delay_ms=atoi(argv[i]); 239 }else if (strcmp(argv[i],"--ec-framesize")==0){ 240 i++; 241 ec_framesize=atoi(argv[i]); 238 242 }else if (strcmp(argv[i],"--agc")==0){ 239 243 agc=TRUE; … … 332 336 #endif 333 337 } 334 if (eq || ec){ /*read from stdin interactive commands */ 335 char commands[128]; 336 commands[127]='\0'; 337 ms_sleep(1); /* ensure following text be printed after ortp messages */ 338 if (eq) 339 printf("\nPlease enter equalizer requests, such as 'eq active 1', 'eq active 0', 'eq 1200 0.1 200'\n"); 340 if (ec) 341 printf("\nPlease enter echo canceller requests: ec reset; ec <delay ms> <tail_length ms'\n"); 342 while(fgets(commands,sizeof(commands)-1,stdin)!=NULL){ 343 int active,freq,freq_width; 344 int delay_ms, tail_ms; 345 float gain; 346 if (sscanf(commands,"eq active %i",&active)==1){ 347 audio_stream_enable_equalizer(audio,active); 348 printf("OK\n"); 349 }else if (sscanf(commands,"eq %i %f %i",&freq,&gain,&freq_width)==3){ 350 audio_stream_equalizer_set_gain(audio,freq,gain,freq_width); 351 printf("OK\n"); 352 }else if (sscanf(commands,"eq %i %f",&freq,&gain)==2){ 353 audio_stream_equalizer_set_gain(audio,freq,gain,0); 354 printf("OK\n"); 355 }else if (strstr(commands,"dump")){ 356 int n=0,i; 357 float *t; 358 ms_filter_call_method(audio->equalizer,MS_EQUALIZER_GET_NUM_FREQUENCIES,&n); 359 t=(float*)alloca(sizeof(float)*n); 360 ms_filter_call_method(audio->equalizer,MS_EQUALIZER_DUMP_STATE,t); 361 for(i=0;i<n;++i){ 362 if (fabs(t[i]-1)>0.01){ 363 printf("%i:%f:0 ",(i*pt->clock_rate)/(2*n),t[i]); 364 } 365 } 366 printf("\nOK\n"); 367 }else if (sscanf(commands,"ec reset %i",&active)==1){ 368 //audio_stream_enable_equalizer(audio,active); 369 //printf("OK\n"); 370 }else if (sscanf(commands,"ec active %i",&active)==1){ 371 //audio_stream_enable_equalizer(audio,active); 372 //printf("OK\n"); 373 }else if (sscanf(commands,"ec %i %i",&delay_ms,&tail_ms)==2){ 374 audio_stream_set_echo_canceller_params(audio,tail_ms,delay_ms,128); 375 // revisit: workaround with old method call to force echo reset 376 delay_ms*=8; 377 ms_filter_call_method(audio->ec,MS_FILTER_SET_PLAYBACKDELAY,&delay_ms); 378 printf("OK\n"); 379 }else if (strstr(commands,"quit")){ 380 break; 381 }else printf("Cannot understand this.\n"); 382 } 338 if (eq){ /*read from stdin interactive commands */ 339 char commands[128]; 340 commands[127]='\0'; 341 ms_sleep(1); /* ensure following text be printed after ortp messages */ 342 if (eq) 343 printf("\nPlease enter equalizer requests, such as 'eq active 1', 'eq active 0', 'eq 1200 0.1 200'\n"); 344 345 while(fgets(commands,sizeof(commands)-1,stdin)!=NULL){ 346 int active,freq,freq_width; 347 348 float gain; 349 if (sscanf(commands,"eq active %i",&active)==1){ 350 audio_stream_enable_equalizer(audio,active); 351 printf("OK\n"); 352 }else if (sscanf(commands,"eq %i %f %i",&freq,&gain,&freq_width)==3){ 353 audio_stream_equalizer_set_gain(audio,freq,gain,freq_width); 354 printf("OK\n"); 355 }else if (sscanf(commands,"eq %i %f",&freq,&gain)==2){ 356 audio_stream_equalizer_set_gain(audio,freq,gain,0); 357 printf("OK\n"); 358 }else if (strstr(commands,"dump")){ 359 int n=0,i; 360 float *t; 361 ms_filter_call_method(audio->equalizer,MS_EQUALIZER_GET_NUM_FREQUENCIES,&n); 362 t=(float*)alloca(sizeof(float)*n); 363 ms_filter_call_method(audio->equalizer,MS_EQUALIZER_DUMP_STATE,t); 364 for(i=0;i<n;++i){ 365 if (fabs(t[i]-1)>0.01){ 366 printf("%i:%f:0 ",(i*pt->clock_rate)/(2*n),t[i]); 367 } 368 } 369 printf("\nOK\n"); 370 } else if (strstr(commands,"quit")){ 371 break; 372 }else printf("Cannot understand this.\n"); 373 } 383 374 }else{ /* no interactive stuff - continuous debug output */ 384 375 rtp_session_register_event_queue(session,q); … … 423 414 rtp_profile_destroy(profile); 424 415 } 416
Note: See TracChangeset
for help on using the changeset viewer.
