Changeset 1331:498cc1c1ce41 in mediastreamer2


Ignore:
Timestamp:
Mar 29, 2011 6:22:54 PM (2 years ago)
Author:
Simon Morlat <simon.morlat@…>
Branch:
default
Message:

speex echo improvements about delay

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/speexec.c

    r1328 r1331  
    2020 
    2121#include "mediastreamer2/msfilter.h" 
     22#include "mediastreamer2/msticker.h" 
    2223#include <speex/speex_echo.h> 
    2324#include <speex/speex_preprocess.h> 
     
    4445        MSBufferizer delayed_ref; 
    4546        MSBufferizer echo; 
    46         int ref_bytes_limit; 
    4747        int framesize; 
    4848        int filterlength; 
     
    5050        int delay_ms; 
    5151        int tail_length_ms; 
    52         float ref_bufsize_ms; 
     52        int nominal_ref_samples; 
     53        int min_ref_samples; 
    5354#ifdef EC_DUMP 
    5455        FILE *echofile; 
    5556        FILE *reffile; 
    5657#endif 
    57         bool_t using_silence; 
    5858        bool_t echostarted; 
    5959        bool_t bypass_mode; 
     60        bool_t using_zeroes; 
    6061}SpeexECState; 
    6162 
     
    7172        s->framesize=framesize; 
    7273        s->den = NULL; 
    73         s->using_silence=FALSE; 
     74        s->using_zeroes=FALSE; 
    7475        s->echostarted=FALSE; 
    7576        s->bypass_mode=FALSE; 
     
    121122        m->b_wptr+=delay_samples*2; 
    122123        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) 
    127128 *      inputs[1]= near speech & echo signal    (read from soundcard) 
    128  *      outputs[0]=  far end speech 
     129 *      outputs[0]=  is a copy of inputs[0] to be sent to soundcard 
    129130 *      outputs[1]=  near end speech, echo removed - towards far end 
    130131*/ 
     
    134135        mblk_t *refm; 
    135136        uint8_t *ref,*echo; 
    136         int size; 
    137         float ref_bufsize_ms; 
    138         int diff; 
    139         int idiff; 
    140         int drift; 
    141         int threshold; 
    142137         
    143138        if (s->bypass_mode) { 
     
    165160        while (ms_bufferizer_read(&s->echo,echo,nbytes)>=nbytes){ 
    166161                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*/ 
    168180                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; 
    172186                } 
    173187                 
     
    184198        } 
    185199 
    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; 
    209208        } 
    210209} 
     
    306305 
    307306MS_FILTER_DESC_EXPORT(ms_speex_ec_desc) 
     307 
  • tests/mediastream.c

    r1327 r1331  
    145145                                                                "[ --ec-tail <echo canceller tail length in ms> ]\n" 
    146146                                                                "[ --ec-delay <echo canceller delay in ms> ]\n" 
     147                                                                "[ --ec-framesize <echo canceller framesize in samples> ]\n" 
    147148                                                                "[ --agc (enable automatic gain control)]\n" 
    148149                                                                "[ --ng (enable noise gate)]\n" 
     
    236237                        i++; 
    237238                        ec_delay_ms=atoi(argv[i]); 
     239                }else if (strcmp(argv[i],"--ec-framesize")==0){ 
     240                        i++; 
     241                        ec_framesize=atoi(argv[i]); 
    238242                }else if (strcmp(argv[i],"--agc")==0){ 
    239243                        agc=TRUE; 
     
    332336#endif 
    333337        } 
    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                } 
    383374        }else{  /* no interactive stuff - continuous debug output */ 
    384375                rtp_session_register_event_queue(session,q); 
     
    423414        rtp_profile_destroy(profile); 
    424415} 
     416 
Note: See TracChangeset for help on using the changeset viewer.