/*-----------------------------------------------------------* * procedure dec_cng: * * ~~~~~~~~ * * Receives frame type * * 0 : for untransmitted frames * * 2 : for SID frames * * Decodes SID frames * * Computes current frame excitation * * Computes current frame LSPs *-----------------------------------------------------------*/ void dec_cng( int past_ftyp, /* (i) : past frame type */ FLOAT sid_sav, /* (i) : energy to recover SID gain */ int *parm, /* (i) : coded SID parameters */ FLOAT *exc, /* (i/o) : excitation array */ FLOAT *lsp_old, /* (i/o) : previous lsp */ FLOAT *A_t, /* (o) : set of interpolated LPC coefficients */ INT16 *seed, /* (i/o) : random generator seed */ FLOAT freq_prev[MA_NP][M] /* (i/o) : previous LPS for quantization */ ) { FLOAT temp; int ind; /* SID Frame */ /*************/ if(parm[0] != 0) { sid_gain = tab_Sidgain[parm[4]]; /* Inverse quantization of the LSP */ sid_lsfq_decode(&parm[1], lspSid, freq_prev); } /* non SID Frame */ /*****************/ else { /* Case of 1st SID frame erased : quantize-decode */ /* energy estimate stored in sid_gain */ if(past_ftyp > 1) { qua_Sidgain(&sid_sav, 0, &temp, &ind); sid_gain = tab_Sidgain[ind]; } } if(past_ftyp > 1) { cur_gain = sid_gain; } else { cur_gain *= A_GAIN0; cur_gain += A_GAIN1 * sid_gain; } calc_exc_rand(cur_gain, exc, seed, FLAG_DEC); /* Interpolate the Lsp vectors */ int_qlpc(lsp_old, lspSid, A_t); copy(lspSid, lsp_old, M); 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; }