/*-----------------------------------------------------------* * procedure Cod_cng: * * ~~~~~~~~ * * computes DTX decision * * encodes SID frames * * computes CNG excitation for encoder update * *-----------------------------------------------------------*/ void Cod_cng( DtxStatus *handle, Word16 *exc, /* (i/o) : excitation array */ Word16 pastVad, /* (i) : previous VAD decision */ Word16 *lsp_old_q, /* (i/o) : previous quantized lsp */ Word16 *Aq, /* (o) : set of interpolated LPC coefficients */ Word16 *ana, /* (o) : coded SID parameters */ Word16 freq_prev[MA_NP][M], /* (i/o) : previous LPS for quantization */ Word16 *seed /* (i/o) : random generator seed */ ) { Word16 i; Word16 curAcf[MP1]; Word16 bid[M], zero[MP1]; Word16 curCoeff[MP1]; Word16 lsp_new[M]; Word16 *lpcCoeff; Word16 cur_igain; Word16 energyq, temp; /* Update Ener and sh_ener */ for(i = NB_GAIN-1; i>=1; i--) { handle->ener[i] = handle->ener[i-1]; handle->sh_ener[i] = handle->sh_ener[i-1]; } /* Compute current Acfs */ Calc_sum_acf(handle->Acf, handle->sh_Acf, curAcf, &(handle->sh_ener[0]), NB_CURACF); /* Compute LPC coefficients and residual energy */ if(curAcf[0] == 0) { handle->ener[0] = 0; /* should not happen */ } else { Set_zero(zero, MP1); Levinson(handle, curAcf, zero, curCoeff, bid, &(handle->ener[0])); } /* if first frame of silence => SID frame */ if(pastVad != 0) { ana[0] = 2; handle->count_fr0 = 0; handle->nb_ener = 1; Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain); } else { handle->nb_ener = add(handle->nb_ener, 1); if(sub(handle->nb_ener, NB_GAIN) > 0) handle->nb_ener = NB_GAIN; Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain); /* Compute stationarity of current filter */ /* versus reference filter */ if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH1) != 0) { handle->flag_chang = 1; } /* compare energy difference between current frame and last frame */ temp = abs_s(sub(handle->prev_energy, energyq)); temp = sub(temp, 2); if (temp > 0) handle->flag_chang = 1; handle->count_fr0 = add(handle->count_fr0, 1); if(sub(handle->count_fr0, FR_SID_MIN) < 0) { ana[0] = 0; /* no transmission */ } else { if(handle->flag_chang != 0) { ana[0] = 2; /* transmit SID frame */ } else{ ana[0] = 0; } handle->count_fr0 = FR_SID_MIN; /* to avoid overflow */ } } if(sub(ana[0], 2) == 0) { /* Reset frame count and change flag */ handle->count_fr0 = 0; handle->flag_chang = 0; /* Compute past average filter */ Calc_pastfilt(handle, handle->pastCoeff); Calc_RCoeff(handle->pastCoeff, handle->RCoeff, &(handle->sh_RCoeff)); /* Compute stationarity of current filter */ /* versus past average filter */ /* if stationary */ /* transmit average filter => new ref. filter */ if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH2) == 0) { lpcCoeff = handle->pastCoeff; } /* else */ /* transmit current filter => new ref. filter */ else { lpcCoeff = curCoeff; Calc_RCoeff(curCoeff, handle->RCoeff, &(handle->sh_RCoeff)); } /* Compute SID frame codes */ Az_lsp(lpcCoeff, lsp_new, lsp_old_q); /* From A(z) to lsp */ /* LSP quantization */ lsfq_noise(lsp_new, handle->lspSid_q, freq_prev, &ana[1]); handle->prev_energy = energyq; ana[4] = cur_igain; handle->sid_gain = tab_Sidgain[cur_igain]; } /* end of SID frame case */ /* Compute new excitation */ if(pastVad != 0) { handle->cur_gain = handle->sid_gain; } else { handle->cur_gain = mult_r(handle->cur_gain, A_GAIN0); handle->cur_gain = add(handle->cur_gain, mult_r(handle->sid_gain, A_GAIN1)); } Calc_exc_rand(handle->L_exc_err, handle->cur_gain, exc, seed, FLAG_COD); Int_qlpc(lsp_old_q, handle->lspSid_q, Aq); for(i=0; i<M; i++) { lsp_old_q[i] = handle->lspSid_q[i]; } /* Update sumAcf if fr_cur = 0 */ if(handle->fr_cur == 0) { Update_sumAcf(handle); } return; }
/*-----------------------------------------------------------* * procedure cod_cng: * * ~~~~~~~~ * * computes DTX decision * * encodes SID frames * * computes CNG excitation for encoder update * *-----------------------------------------------------------*/ void cod_cng(float * exc, /* (i/o) : excitation array */ int pastVad, /* (i) : previous VAD decision */ float * lsp_old_q, /* (i/o) : previous quantized lsp */ float * old_A, /* (i/o) : last stable filter LPC coefficients */ float * old_rc, /* (i/o) : last stable filter Reflection coefficients. */ float * Aq, /* (o) : set of interpolated LPC coefficients */ int *ana, /* (o) : coded SID parameters */ float freq_prev[MA_NP][M], /* (i/o) : previous LPS for quantization */ int16_t * seed /* (i/o) : random generator seed */ ) { int i; float curAcf[MP1]; float bid[MP1]; float curCoeff[MP1]; float lsp_new[M]; float *lpcCoeff; int cur_igain; float energyq; /* Update Ener */ for (i = NB_GAIN - 1; i >= 1; i--) { ener[i] = ener[i - 1]; } /* Compute current Acfs */ calc_sum_acf(Acf, curAcf, NB_CURACF); /* Compute LPC coefficients and residual energy */ if (curAcf[0] == (float) 0.) { ener[0] = (float) 0.; /* should not happen */ } else { ener[0] = levinsone(M, curAcf, curCoeff, bid, old_A, old_rc); } /* if first frame of silence => SID frame */ if (pastVad != 0) { ana[0] = 1; count_fr0 = 0; nb_ener = 1; qua_Sidgain(ener, nb_ener, &energyq, &cur_igain); } else { nb_ener++; if (nb_ener > NB_GAIN) nb_ener = NB_GAIN; qua_Sidgain(ener, nb_ener, &energyq, &cur_igain); /* Compute stationarity of current filter */ /* versus reference filter */ if (cmp_filt(RCoeff, curAcf, ener[0], THRESH1) != 0) { flag_chang = 1; } /* compare energy difference between current frame and last frame */ if ((float) fabs(prev_energy - energyq) > (float) 2.0) flag_chang = 1; count_fr0++; if (count_fr0 < FR_SID_MIN) { ana[0] = 0; /* no transmission */ } else { if (flag_chang != 0) { ana[0] = 1; /* transmit SID frame */ } else { ana[0] = 0; } count_fr0 = FR_SID_MIN; /* to avoid overflow */ } } if (ana[0] == 1) { /* Reset frame count and change flag */ count_fr0 = 0; flag_chang = 0; /* Compute past average filter */ calc_pastfilt(pastCoeff, old_A, old_rc); calc_RCoeff(pastCoeff, RCoeff); /* Compute stationarity of current filter */ /* versus past average filter */ /* if stationary */ /* transmit average filter => new ref. filter */ if (cmp_filt(RCoeff, curAcf, ener[0], THRESH2) == 0) { lpcCoeff = pastCoeff; } /* else */ /* transmit current filter => new ref. filter */ else { lpcCoeff = curCoeff; calc_RCoeff(curCoeff, RCoeff); } /* Compute SID frame codes */ az_lsp(lpcCoeff, lsp_new, lsp_old_q); /* From A(z) to lsp */ /* LSP quantization */ lsfq_noise(lsp_new, lspSid_q, freq_prev, &ana[1]); prev_energy = energyq; ana[4] = cur_igain; sid_gain = tab_Sidgain[cur_igain]; } /* end of SID frame case */ /* Compute new excitation */ if (pastVad != 0) { cur_gain = sid_gain; } else { cur_gain *= A_GAIN0; cur_gain += A_GAIN1 * sid_gain; } calc_exc_rand(cur_gain, exc, seed, FLAG_COD); int_qlpc(lsp_old_q, lspSid_q, Aq); for (i = 0; i < M; i++) { lsp_old_q[i] = lspSid_q[i]; } /* Update sumAcf if fr_cur = 0 */ if (fr_cur == 0) { update_sumAcf(); } return; }