예제 #1
0
파일: vad.c 프로젝트: ZF0085/onionphone
void vad(float rc,
         float * lsf,
         float * rxx,
         float * sigpp,
         int frm_count,
         int prev_marker, int pprev_marker, int *marker, float * Energy_db)
{
    float tmp[M];
    float SD;
    float E_low;
    float dtemp;
    float dSE;
    float dSLE;
    float ZC;
    float COEF;
    float COEFZC;
    float COEFSD;
    float dSZC;
    float norm_energy;
    int i;

    /* compute the frame energy */
    norm_energy =
        (float) 10.0 *(float) log10((float) (rxx[0] / (float) 240.0 + EPSI));
    *Energy_db = norm_energy;

    /* compute the low band energy */
    E_low = (float) 0.0;
    for (i = 1; i <= NP; i++)
        E_low = E_low + rxx[i] * lbf_corr[i];

    E_low = rxx[0] * lbf_corr[0] + (float) 2.0 *E_low;
    if (E_low < (float) 0.0)
        E_low = (float) 0.0;
    E_low = (float) 10.0 *(float) log10((float) (E_low / (float) 240.0 + EPSI));

    /* compute SD */
    /* Normalize lsfs */
    for (i = 0; i < M; i++)
        lsf[i] /= (float) 2. *PI;
    dvsub(lsf, MeanLSF, tmp, M);
    SD = dvdot(tmp, tmp, M);

    /* compute # zero crossing */
    ZC = (float) 0.0f;
    dtemp = sigpp[ZC_START];
    for (i = ZC_START + 1; i <= ZC_END; i++) {
        if (dtemp * sigpp[i] < (float) 0.0) {
            ZC = ZC + (float) 1.0;
        }
        dtemp = sigpp[i];
    }
    ZC = ZC / (float) 80.0;

    /* Initialize and update Mins */
    if (frm_count < 129) {
        if (norm_energy < Min) {
            Min = norm_energy;
            Prev_Min = norm_energy;
        }
        if ((frm_count % 8) == 0) {
            Min_buffer[(int)frm_count / 8 - 1] = Min;
            Min = FLT_MAX_G729;
        }
    }
    if ((frm_count % 8) == 0) {
        Prev_Min = Min_buffer[0];
        for (i = 1; i < 15; i++) {
            if (Min_buffer[i] < Prev_Min)
                Prev_Min = Min_buffer[i];
        }
    }

    if (frm_count >= 129) {
        if ((frm_count % 8) == 1) {
            Min = Prev_Min;
            Next_Min = FLT_MAX_G729;
        }
        if (norm_energy < Min)
            Min = norm_energy;
        if (norm_energy < Next_Min)
            Next_Min = norm_energy;
        if ((frm_count % 8) == 0) {
            for (i = 0; i < 15; i++)
                Min_buffer[i] = Min_buffer[i + 1];
            Min_buffer[15] = Next_Min;
            Prev_Min = Min_buffer[0];
            for (i = 1; i < 16; i++) {
                if (Min_buffer[i] < Prev_Min)
                    Prev_Min = Min_buffer[i];
            }

        }
    }

    if (frm_count <= INIT_FRAME) {
        if (norm_energy < (float) 21.0) {
            less_count++;
            *marker = NOISE;
        } else {
            *marker = VOICE;
            MeanE =
                (MeanE * ((float) (frm_count - less_count - 1)) +
                 norm_energy) / (float) (frm_count - less_count);
            MeanSZC =
                (MeanSZC * ((float) (frm_count - less_count - 1)) +
                 ZC) / (float) (frm_count - less_count);
            dvwadd(MeanLSF, (float) (frm_count - less_count - 1),
                   lsf, (float) 1.0, MeanLSF, M);
            dvsmul(MeanLSF,
                   (float) 1.0 / (float) (frm_count - less_count),
                   MeanLSF, M);
        }
    }

    if (frm_count >= INIT_FRAME) {
        if (frm_count == INIT_FRAME) {
            MeanSE = MeanE - (float) 10.0;
            MeanSLE = MeanE - (float) 12.0;
        }

        dSE = MeanSE - norm_energy;
        dSLE = MeanSLE - E_low;
        dSZC = MeanSZC - ZC;

        if (norm_energy < (float) 21.0) {
            *marker = NOISE;
        } else {
            *marker = MakeDec(dSLE, dSE, SD, dSZC);
        }

        v_flag = 0;
        if ((prev_marker == VOICE) && (*marker == NOISE) &&
                (norm_energy > MeanSE + (float) 2.0)
                && (norm_energy > (float) 21.0)) {
            *marker = VOICE;
            v_flag = 1;
        }

        if (flag == 1) {
            if ((pprev_marker == VOICE) && (prev_marker == VOICE) &&
                    (*marker == NOISE)
                    && (fabs(prev_energy - norm_energy) <= (float) 3.0)) {
                count_ext++;
                *marker = VOICE;
                v_flag = 1;
                if (count_ext <= 4)
                    flag = 1;
                else {
                    flag = 0;
                    count_ext = 0;
                }
            }
        } else
            flag = 1;

        if (*marker == NOISE)
            count_sil++;

        if ((*marker == VOICE) && (count_sil > 10) &&
                ((norm_energy - prev_energy) <= (float) 3.0)) {
            *marker = NOISE;
            count_sil = 0;
        }

        if (*marker == VOICE)
            count_sil = 0;

        if ((norm_energy < MeanSE + (float) 3.0) && (frm_count > 128)
                && (!v_flag) && (rc < (float) 0.6))
            *marker = NOISE;

        if ((norm_energy < MeanSE + (float) 3.0) && (rc < (float) 0.75)
                && (SD < (float) 0.002532959)) {
            count_update++;
            if (count_update < INIT_COUNT) {
                COEF = (float) 0.75;
                COEFZC = (float) 0.8;
                COEFSD = (float) 0.6;
            } else if (count_update < INIT_COUNT + 10) {
                COEF = (float) 0.95;
                COEFZC = (float) 0.92;
                COEFSD = (float) 0.65;
            } else if (count_update < INIT_COUNT + 20) {
                COEF = (float) 0.97;
                COEFZC = (float) 0.94;
                COEFSD = (float) 0.70;
            } else if (count_update < INIT_COUNT + 30) {
                COEF = (float) 0.99;
                COEFZC = (float) 0.96;
                COEFSD = (float) 0.75;
            } else if (count_update < INIT_COUNT + 40) {
                COEF = (float) 0.995;
                COEFZC = (float) 0.99;
                COEFSD = (float) 0.75;
            } else {
                COEF = (float) 0.995;
                COEFZC = (float) 0.998;
                COEFSD = (float) 0.75;
            }
            dvwadd(MeanLSF, COEFSD, lsf, (float) 1.0 - COEFSD, MeanLSF,
                   M);
            MeanSE = COEF * MeanSE + ((float) 1.0 - COEF) * norm_energy;
            MeanSLE = COEF * MeanSLE + ((float) 1.0 - COEF) * E_low;
            MeanSZC = COEFZC * MeanSZC + ((float) 1.0 - COEFZC) * ZC;
        }

        if (((frm_count > 128)
                && ((MeanSE < Min) && (SD < (float) 0.002532959)))
                || (MeanSE > Min + (float) 10.0)) {
            MeanSE = Min;
            count_update = 0;
        }
    }

    prev_energy = norm_energy;
    return;
}
예제 #2
0
void vad(struct vad_state_t * state,
    GFLOAT  rc,
    GFLOAT *lsf,
    GFLOAT *rxx, 
    GFLOAT *sigpp,
    int frm_count,
    int prev_marker,
    int pprev_marker,
    int *marker,
    GFLOAT *Energy_db)
{
    GFLOAT tmp[M];
    GFLOAT SD;
    GFLOAT E_low;
    GFLOAT  dtemp;
    GFLOAT  dSE;
    GFLOAT  dSLE;
    GFLOAT   ZC;
    GFLOAT  COEF;
    GFLOAT COEFZC;
    GFLOAT COEFSD;
    GFLOAT  dSZC;
    GFLOAT norm_energy;
    int i;
    
    /* compute the frame energy */
    norm_energy = (F)10.0*(GFLOAT) log10((GFLOAT)( rxx[0]/(F)240.0 +EPSI));
    *Energy_db = norm_energy ;

    /* compute the low band energy */
    E_low = (F)0.0;
    for( i=1; i<= NP; i++)
        E_low = E_low + rxx[i]*lbf_corr[i];

    E_low= rxx[0]*lbf_corr[0] + (F)2.0*E_low;
    if (E_low < (F)0.0) E_low = (F)0.0;
    E_low= (F)10.0*(GFLOAT) log10((GFLOAT) (E_low/(F)240.0+EPSI));

    /* compute SD */
    /* Normalize lsfs */
    for(i=0; i<M; i++) lsf[i] /= (F)2.*PI;
    dvsub(lsf, state->MeanLSF,tmp,M);
    SD = dvdot(tmp,tmp,M);
    
    /* compute # zero crossing */
    ZC = (F)0.0f;
    dtemp = sigpp[ZC_START];
    for (i=ZC_START+1 ; i <= ZC_END ; i++) {
        if (dtemp*sigpp[i] < (F)0.0) {
            ZC= ZC +(F)1.0;
        }
        dtemp = sigpp[i];
    }
    ZC = ZC/(F)80.0;
    
    /* Initialize and update Mins */
    if( frm_count < 129 ) {
        if( norm_energy < state->Min ){
            state->Min = norm_energy;
            state->Prev_Min = norm_energy;
        }
        if( (frm_count % 8) == 0){
            state->Min_buffer[(int)frm_count/8 -1] = state->Min;
            state->Min = FLT_MAX_G729;
        }
    }
    if( (frm_count % 8) == 0){
        state->Prev_Min = state->Min_buffer[0];
        for ( i =1; i< 15; i++){
            if ( state->Min_buffer[i] <  state->Prev_Min )
                state->Prev_Min = state->Min_buffer[i];
        }
    }
    
    if( frm_count >= 129 ) {
        if( (frm_count % 8 ) == 1) {
            state->Min = state->Prev_Min;
            state->Next_Min = FLT_MAX_G729;
        }
        if( norm_energy < state->Min )
            state->Min = norm_energy;
        if( norm_energy < state->Next_Min )
            state->Next_Min = norm_energy;
        if( (frm_count % 8) == 0){
            for ( i =0; i< 15; i++)
                state->Min_buffer[i] = state->Min_buffer[i+1];
            state->Min_buffer[15]  = state->Next_Min;
            state->Prev_Min = state->Min_buffer[0];
            for ( i =1; i< 16; i++){
                if ( state->Min_buffer[i] <  state->Prev_Min )
                    state->Prev_Min = state->Min_buffer[i];
            }
            
        }
    }
    
    if (frm_count <= INIT_FRAME){
        if( norm_energy < (F)21.0){
            state->less_count++;
            *marker = NOISE;
        }
        else{
            *marker = VOICE;
            state->MeanE = (state->MeanE * ( (GFLOAT)(frm_count - state->less_count -1)) +
                norm_energy)/(GFLOAT) (frm_count - state->less_count);
            state->MeanSZC = (state->MeanSZC * ( (GFLOAT)(frm_count - state->less_count -1)) +
                ZC)/(GFLOAT) (frm_count - state->less_count);
            dvwadd(state->MeanLSF,(GFLOAT) (frm_count - state->less_count -1),lsf,(F)1.0,state->MeanLSF,M);
            dvsmul(state->MeanLSF,(F)1.0/(GFLOAT) (frm_count - state->less_count ), state->MeanLSF,M);
        }
    }

    if (frm_count >= INIT_FRAME ){
        if (frm_count == INIT_FRAME ){
            state->MeanSE = state->MeanE -(F)10.0;
            state->MeanSLE = state->MeanE -(F)12.0;
        }

        dSE = state->MeanSE - norm_energy;
        dSLE = state->MeanSLE - E_low;
        dSZC = state->MeanSZC - ZC;

        if( norm_energy < (F)21.0 ){
            *marker = NOISE;
        }
        else{
            *marker = vad_make_dec(dSLE, dSE, SD, dSZC );
        }
        
        state->v_flag =0;
        if( (prev_marker == VOICE) && (*marker == NOISE) &&
            (norm_energy > state->MeanSE + (F)2.0) && ( norm_energy>(F)21.0)){
            *marker = VOICE;
            state->v_flag=1;
        }
        
        if((state->flag == 1) ){
            if( (pprev_marker == VOICE) && (prev_marker == VOICE) &&
                (*marker == NOISE) && (fabs(state->prev_energy - norm_energy)<= (F)3.0)){
                state->count_ext++;
                *marker = VOICE;
                state->v_flag=1;
                if(state->count_ext <=4)
                    state->flag =1;
                else{
                    state->flag =0;
                    state->count_ext=0;
                }
            }
        }
        else
            state->flag =1;
        
        if(*marker == NOISE)
            state->count_sil++;
        
        if((*marker == VOICE) && (state->count_sil > 10) &&
            ((norm_energy - state->prev_energy) <= (F)3.0)){
            *marker = NOISE;
            state->count_sil=0;
        }
        
        
        if(*marker == VOICE)
            state->count_sil=0;
        
        if ((norm_energy < state->MeanSE + (F)3.0) && ( frm_count >128) &&( !state->v_flag) && (rc <(F)0.6) )
			*marker = NOISE;

        if ((norm_energy < state->MeanSE + (F)3.0) && (rc <(F)0.75) && ( SD<(F)0.002532959)){
            state->count_update++;
            if (state->count_update < INIT_COUNT){
                COEF = (F)0.75;
                COEFZC = (F)0.8;
                COEFSD = (F)0.6;
            }
            else
                if (state->count_update < INIT_COUNT+10){
                    COEF = (F)0.95;
                    COEFZC = (F)0.92;
                    COEFSD = (F)0.65;
                }
                else
                    if (state->count_update < INIT_COUNT+20){
                        COEF = (F)0.97;
                        COEFZC = (F)0.94;
                        COEFSD = (F)0.70;
                    }
                    else
                        if (state->count_update < INIT_COUNT+30){
                            COEF = (F)0.99;
                            COEFZC = (F)0.96;
                            COEFSD = (F)0.75;
                        }
                        else
                            if (state->count_update < INIT_COUNT+40){
                                COEF = (F)0.995;
                                COEFZC = (F)0.99;
                                COEFSD = (F)0.75;
                            }
                            else{
                                COEF = (F)0.995;
                                COEFZC = (F)0.998;
                                COEFSD = (F)0.75;
                            }
            dvwadd(state->MeanLSF,COEFSD,lsf,(F)1.0 -COEFSD,state->MeanLSF,M);
            state->MeanSE = COEF * state->MeanSE+((F)1.0- COEF)*norm_energy;
            state->MeanSLE = COEF * state->MeanSLE+((F)1.0- COEF)*E_low;
            state->MeanSZC = COEFZC * state->MeanSZC+((F)1.0- COEFZC)*ZC;
        }
        
        if(((frm_count > 128) && (state->MeanSE < state->Min) && (SD < (F)0.002532959)) || (state->MeanSE > state->Min + (F)10.0) )
		{
            state->MeanSE = state->Min;
            state->count_update = 0;
        }
    }
  
    state->prev_energy = norm_energy;

    return;
}