Changeset 331:b2248f9c7bdb in mediastreamer2


Ignore:
Timestamp:
Mar 11, 2009 6:45:54 PM (4 years ago)
Author:
aymeric <aymeric@…>
Branch:
default
Message:

work on half duplex and detection of signal outside the 8KHz signal

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@334 3f6dc0c8-ddfe-455d-9043-3cd528dc4637

File:
1 edited

Legend:

Unmodified
Added
Removed
  • linphone/mediastreamer2/src/msconf.c

    r330 r331  
    4242#endif 
    4343 
    44 static const float max_e=32767*32767; 
    45 static const float coef=0.1; 
     44static const float max_e=(float)32767*32767; 
     45static const float coef=(float)0.1; 
    4646 
    4747typedef struct Channel{ 
     
    9595        ms_bufferizer_init(&chan->buff); 
    9696#ifndef DISABLE_SPEEX 
    97         //chan->speex_pp = speex_preprocess_state_init((s->conf_gran/2) *(s->samplerate/8000), s->samplerate); 
    9897        chan->speex_pp = speex_preprocess_state_init(s->conf_gran/2, s->samplerate); 
    9998        if (chan->speex_pp==NULL) 
     
    138137                val=1; 
    139138        if (s->agc_level>0) 
    140                 f=s->agc_level; 
     139                f=(float)s->agc_level; 
    141140 
    142141 
     
    151150#endif 
    152151        speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_DEREVERB, &val); 
    153         f=.4; 
     152        f=(float).4; 
    154153        speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); 
    155         f=.3; 
     154        f=(float).3; 
    156155        speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); 
    157156 
     
    250249        return FALSE; 
    251250} 
     251 
     252#ifndef DISABLE_SPEEX 
     253static double powerspectrum_stat_beyond8K(struct Channel *chan) 
     254{ 
     255        spx_int32_t ps_size = 0; 
     256        spx_int32_t *ps = NULL; 
     257        double mystat = 0; 
     258        float fftmul = 1.0 / (32768.0); 
     259 
     260        speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_GET_PSD_SIZE, &ps_size); 
     261        ps = (spx_int32_t*)ortp_malloc(sizeof(spx_int32_t)*ps_size); 
     262        speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_GET_PSD, ps); 
     263 
     264 
     265        mystat = 0; 
     266        for (int i=ps_size/2;i < ps_size; i++) { 
     267                double yp; 
     268                yp = sqrtf(sqrtf(static_cast<float>(ps[i]))) - 1.0f; 
     269                yp = yp * fftmul; 
     270                yp = MIN(yp * 3000.0, 1.0); 
     271                mystat = yp + mystat; 
     272        } 
     273 
     274        ortp_free(ps); 
     275 
     276        /* value between 0 and 100? */ 
     277        mystat = mystat*100*2/ps_size; 
     278        if (mystat<0) 
     279                mystat=0; 
     280        if (mystat>100) 
     281                mystat=100; 
     282 
     283        return mystat; 
     284} 
     285#endif 
    252286 
    253287static void conf_sum(MSFilter *f, ConfState *s){ 
     
    322356                        } 
    323357 
    324  
    325                         if (s->enable_halfduplex>0) 
    326                         { 
    327 #if 0 
    328                                 ms_message("prob=%i", loudness); 
    329 #endif 
    330                                 // LIMITATION: 
    331                                 // HALF DUPLEX MODE IS TO BE USED WITH ONLY  
    332                                 // ONE SOUND CARD AND ONE RTP STREAM. 
    333                                 if (vad>0) // && loudness>20) 
    334                                 { 
    335                                         /* speech detected */ 
    336                                         s->channels[0].is_speaking++; 
    337                                         if (s->channels[0].is_speaking>2) 
    338                                                 s->channels[0].is_speaking=2; 
    339                                 } 
    340                                 else 
    341                                 { 
    342                                         s->channels[0].is_speaking--; 
    343                                         if (s->channels[0].is_speaking<-2) 
    344                                                 s->channels[0].is_speaking=-2; 
    345                                 } 
    346  
    347                                 //if (s->channels[0].is_speaking<=0) 
    348                                 //      ms_message("silence on! (%i)", s->channels[0].is_speaking); 
    349                                 //else 
    350                                 //      ms_message("speech on! (%i)", s->channels[0].is_speaking); 
    351                         } 
    352  
    353358                        for(j=0;j<s->conf_nsamples;++j){ 
    354359                                s->sum[j]+=chan->input[j]; 
     
    360365                else if (ms_bufferizer_get_avail(&chan->buff)>=s->conf_gran) 
    361366                { 
     367                        struct channel_volume { 
     368                                float energy; 
     369                                int channel; 
     370                        }; 
     371                        struct channel_volume vol; 
     372                        float en; 
     373 
    362374                        ms_bufferizer_read(&chan->buff,(uint8_t*)chan->input,s->conf_gran); 
     375 
     376                        en=chan->energy; 
     377                        for(j=0;j<s->conf_nsamples;++j){ 
     378                                float s=chan->input[j]; 
     379                                en=(s*s*coef) + ((float)1.0-coef)*en; 
     380                        } 
     381                        chan->energy=en; 
     382                        vol.energy = 10*log10f(chan->energy/max_e); 
     383                        vol.channel = i; 
     384                        ms_filter_notify(f, MS_CONF_CHANNEL_VOLUME, (void*)&vol); 
     385 
    363386#ifndef DISABLE_SPEEX 
    364387                        if (chan->speex_pp!=NULL && s->enable_vad==TRUE && i==0) 
    365388                        { 
    366                                 struct channel_volume { 
    367                                         float energy; 
    368                                         int channel; 
    369                                 }; 
    370                                 struct channel_volume vol; 
    371                                 float en; 
    372389                                int vad; 
    373  
    374                                 en=chan->energy; 
    375                                 for(j=0;j<s->conf_nsamples;++j){ 
    376                                         float s=chan->input[j]; 
    377                                         en=(s*s*coef) + (1.0-coef)*en; 
    378                                 } 
    379                                 chan->energy=en; 
    380                                 vol.energy = 10*log10f(chan->energy/max_e); 
    381                                 vol.channel = i; 
    382                                 ms_filter_notify(f, MS_CONF_CHANNEL_VOLUME, (void*)&vol); 
    383  
    384390                                vad = speex_preprocess(chan->speex_pp, (short*)chan->input, NULL); 
    385391                                ms_filter_notify(f, MS_CONF_SPEEX_PREPROCESS_MIC, (void*)chan->speex_pp); 
    386                         } 
    387                         else if (chan->speex_pp!=NULL && s->enable_vad==TRUE) 
    388                         { 
    389                                 struct channel_volume { 
    390                                         float energy; 
    391                                         int channel; 
    392                                 }; 
    393                                 struct channel_volume vol; 
    394                                 float en; 
    395  
    396                                 int vad; 
    397  
    398                                 en=chan->energy; 
    399                                 for(j=0;j<s->conf_nsamples;++j){ 
    400                                         float s=chan->input[j]; 
    401                                         en=(s*s*coef) + (1.0-coef)*en; 
    402                                 } 
    403                                 chan->energy=en; 
    404                                 vol.energy = 10*log10f(chan->energy/max_e); 
    405                                 vol.channel = i; 
    406                                 ms_filter_notify(f, MS_CONF_CHANNEL_VOLUME, (void*)&vol); 
    407392 
    408393                                if (s->enable_halfduplex>0) 
    409394                                { 
    410                                         vad = speex_preprocess(chan->speex_pp, (short*)chan->input, NULL); 
    411 #if 0 
    412                                         speex_preprocess_ctl(chan->speex_pp, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness); 
    413                                         ms_message("prob=%i", loudness); 
    414 #endif 
    415                                         // LIMITATION: 
    416                                         // HALF DUPLEX MODE IS TO BE USED WITH ONLY  
    417                                         // ONE SOUND CARD AND ONE RTP STREAM. 
    418                                         if (vad>0) //&& loudness>20) 
     395                                        double mystat = powerspectrum_stat_beyond8K(chan); 
     396                                        if (mystat>10) 
    419397                                        { 
    420                                                 s->channels[0].is_speaking++; 
    421                                                 if (s->channels[0].is_speaking>2) 
    422                                                         s->channels[0].is_speaking=2; 
     398                                                ms_message("is_speaking (chan=%i) -> on/stat=%d", i, mystat); 
     399                                                s->channels[0].is_speaking=20; /* keep RTP muted for the next few ms */ 
    423400                                        } 
    424401                                        else 
    425402                                        { 
    426403                                                s->channels[0].is_speaking--; 
    427                                                 if (s->channels[0].is_speaking<-2) 
    428                                                         s->channels[0].is_speaking=-2; 
    429404                                        } 
    430  
    431                                         //if (s->channels[0].is_speaking<=0) 
    432                                         //      ms_message("silence on! (%i)", s->channels[0].is_speaking); 
    433                                         //else 
    434                                         //      ms_message("speech on! (%i)", s->channels[0].is_speaking); 
     405                                } 
     406 
     407                        } 
     408                        else if (chan->speex_pp!=NULL && s->enable_vad==TRUE) 
     409                        { 
     410                                int vad; 
     411 
     412                                if (s->enable_halfduplex>0) 
     413                                { 
     414                                        vad = speex_preprocess(chan->speex_pp, (short*)chan->input, NULL); 
    435415                                } 
    436416                                else 
     
    475455} 
    476456 
    477 static mblk_t * conf_output(ConfState *s, Channel *chan){ 
     457static mblk_t * conf_output(ConfState *s, Channel *chan, int16_t attenuation){ 
    478458        mblk_t *m=allocb(s->conf_gran,0); 
    479459        int i; 
     
    482462                for (i=0;i<s->conf_nsamples;++i){ 
    483463                        tmp=s->sum[i]-(int)chan->input[i]; 
    484                         *((int16_t*)m->b_wptr)=saturate(tmp); 
     464                        *((int16_t*)m->b_wptr)=saturate(tmp)/attenuation; 
    485465                        m->b_wptr+=2; 
    486466                } 
     
    488468                for (i=0;i<s->conf_nsamples;++i){ 
    489469                        tmp=s->sum[i]; 
    490                         *((int16_t*)m->b_wptr)=saturate(tmp); 
     470                        *((int16_t*)m->b_wptr)=saturate(tmp)/attenuation; 
    491471                        m->b_wptr+=2; 
    492472                } 
     
    503483                if (f->outputs[i]!=NULL){ 
    504484                        chan=&s->channels[i]; 
    505                         //if (s->channels[0].is_speaking<=0 || i%2==0) // RTP is silent, work as usual 
    506                                 m=conf_output(s,chan); 
    507                         //else 
    508                         //{ 
    509                         //      int k; 
    510                         //      m=allocb(s->conf_gran,0); 
    511                         //      for (k=0;k<s->conf_nsamples;++k){ 
    512                         //              *((int16_t*)m->b_wptr)=0; 
    513                         //              m->b_wptr+=2; 
    514                         //      } 
    515                         //} 
     485                        if (s->channels[0].is_speaking<0 && i%2==1) // MIC is NOT speaking -> send silence on RTP 
     486                                m=conf_output(s,chan, 5); 
     487                        else 
     488                                m=conf_output(s,chan, 1); 
    516489                        ms_queue_put(f->outputs[i],m); 
    517490                } 
     
    796769 
    797770MS_FILTER_DESC_EXPORT(ms_conf_desc) 
     771 
Note: See TracChangeset for help on using the changeset viewer.