/*==================================================================================== EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006 ====================================================================================*/ #include #include "options.h" #include "cnst.h" #include "rom_com.h" #include "prot.h" /*-------------------------------------------------------------------* * Local constants *-------------------------------------------------------------------*/ #define RANGE 64 /*---------------------------------------------------------------------* * Es_pred_enc() * * Calculation and quantization of average predicted innovation energy to be *---------------------------------------------------------------------*/ void Es_pred_enc( float *Es_pred, /* o : predicited scaled innovation energy */ int *Es_pred_indice, /* o : indice corresponding to above parameter */ const short L_frame, /* i : length of the frame */ const short L_subfr, /* i : length of the subframe */ const float *res, /* i : residual signal */ const float *voicing, /* i : normalized correlation in three 1/2frames */ const short nb_bits, /* i : allocated number of bits */ const short no_ltp /* i : no_ltp flag */ ) { short i, i_subfr, size; float tmp, dist, mean_ener_code, ener; float weight; const float *qua_table; /*----------------------------------------------------------* * calculate the average residual signal energy *----------------------------------------------------------*/ if( L_frame == L_FRAME ) { weight = 0.25f; } else /* L_frame == L_FRAME16k */ { weight = 0.2f; } mean_ener_code = 0.0f; for (i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr) { /* calculate the energy of residual signal */ ener = sum2_f(&res[i_subfr], L_subfr) + 0.01f; ener = 10 * (float)log10( ener / ((float) L_subfr)); if ((ener < 0) && !(no_ltp)) { ener = 0; } /* update the average energy of residual signal */ mean_ener_code += weight * ener; } if( !no_ltp ) { /*----------------------------------------------------------* * subtract an estimate of adaptive codebook contribution *----------------------------------------------------------*/ mean_ener_code -= 10.0f * (0.5f * voicing[0] + 0.5f * voicing[1]); /*----------------------------------------------------------* * quantize the average predicted innovation energy *----------------------------------------------------------*/ switch ( nb_bits ) { case 5: { qua_table = Es_pred_qua_5b; break; } case 4: { qua_table = Es_pred_qua_4b; break; } case 3: { qua_table = Es_pred_qua_3b; break; } default: { qua_table = Es_pred_qua_5b; break; } } } else { qua_table = Es_pred_qua_4b_no_ltp; } /* select codebook, size and number of bits */ size = (short)pow2[nb_bits]; /* find the nearest neighbour (codevector) */ tmp = 1e30f; *Es_pred_indice=0; for (i=0; i, -2,, -2 and 2 */ const short clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ float *past_qua_en /* i/o: gain quantization memory (4 words) */ ) { short index, i, j, min_ind, size, nBits; float dist, dist_min, g_pitch, g_code, qua_en, gcode0; const float *p, *t_qua_gain; /*-----------------------------------------------------------------* * gain computation correlations * find raw innovation energy *-----------------------------------------------------------------*/ E_corr_xy2( xn, y1, y2, g_corr,L_SUBFR); g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F; *gain_inov = 1.0f / (float)sqrt( ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR ); /*-----------------------------------------------------------------* * find the initial quantization pitch index * set gains search range *-----------------------------------------------------------------*/ if ( core_brate < ACELP_12k65 ) { t_qua_gain = t_qua_gain6b; nBits = 6; min_ind = 0; size = RANGE; if (clip_gain == 1) { size -= 16; /* limit pitch gain to 1.0 */ } } else { t_qua_gain = t_qua_gain7b; nBits = 7; p = t_qua_gain7b + RANGE; /* pt at 1/4th of table */ j = NB_QUA_GAIN7B - RANGE; if (clip_gain == 1) { j -= 27; /* limit pitch gain to 1.0 */ } min_ind = 0; g_pitch = *gain_pit; for (i=0; i *p) { min_ind++; } } size = RANGE; } /*-----------------------------------------------------------------* * predicted code gain *-----------------------------------------------------------------*/ /* start with predicting code energy in dB */ gcode0 = MEAN_ENER; for (i=0; i0; i--) { past_qua_en[i] = past_qua_en[i-1]; } past_qua_en[0] = (float)(20.0*log10(qua_en)); push_indice( st, IND_GAIN, index, nBits ); *norm_gain_code = *gain_code / *gain_inov; return; } /*---------------------------------------------------------------------* * gain_enc_mless() * * Quantization of pitch and codebook gains without prediction (memory-less) * - an initial predicted gain, gcode0, is first determined based on * the predicted average innovation energy * - a correction factor gamma = g_code / gcode0 is then vector quantized along with gain_pit * - the mean-squared weighted error criterion is used for codebook search *---------------------------------------------------------------------*/ void gain_enc_mless( Encoder_State *st, /* i/o: encoder state structure */ const long core_brate, /* i : core bitrate */ const short L_frame, /* i : length of the frame */ const short coder_type, /* i : coding type */ const short i_subfr, /* i : subframe index */ const short tc_subfr, /* i : TC subframe index */ const float *xn, /* i : target vector */ const float *y1, /* i : zero-memory filtered adaptive excitation */ const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ const float *code, /* i : algebraic excitation */ const float Es_pred, /* i : predicted scaled innovation energy */ float *gain_pit, /* o : quantized pitch gain */ float *gain_code, /* o : quantized codebook gain */ float *gain_inov, /* o : gain of the innovation (used for normalization) */ float *norm_gain_code, /* o : norm. gain of the codebook excitation */ float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ const short clip_gain /* i : gain pitch clipping flag (1 = clipping) */ ) { short index, i, size, nBits; float dist, dist_min, g_pitch, g_code, gcode0, Ei, Ecode; short nBits2; float tmp1, tmp2; const float *p, *qua_table; /*-----------------------------------------------------------------* * calculate the rest of the correlation coefficients * c2 = , c3 = -2, c4 = 2 *-----------------------------------------------------------------*/ E_corr_xy2( xn, y1, y2, g_corr,L_SUBFR); g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F; /*-----------------------------------------------------------------* * calculate the unscaled innovation energy * calculate the predicted gain code *-----------------------------------------------------------------*/ Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR; *gain_inov = 1.0f / (float)sqrt( Ecode ); Ei = 10 * (float)log10( Ecode ); gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei)); /*-----------------------------------------------------------------* * select the codebook, size and number of bits * set the gains searching range *-----------------------------------------------------------------*/ if( L_frame == L_FRAME ) { nBits = gain_bits_tbl[BIT_ALLOC_IDX(core_brate, coder_type, i_subfr, TC_SUBFR2IDX(tc_subfr))]; } else /* L_frame == L_FRAME16k */ { nBits = gain_bits_16kHz_tbl[ BIT_ALLOC_IDX_16KHZ(core_brate, coder_type, i_subfr, TC_SUBFR2IDX_16KHZ(tc_subfr)) ]; } if( (tc_subfr == 3*L_SUBFR && i_subfr == 3*L_SUBFR && L_frame == L_FRAME) || (tc_subfr == 4*L_SUBFR && i_subfr == 4*L_SUBFR && L_frame == L_FRAME16k) ) { /* in case of attack at the end of the frame, use scalar gain quantizers */ tmp1 = (g_corr[0]*g_corr[2]) - (0.25f*g_corr[4]*g_corr[4]); tmp2 = -0.5f*g_corr[1]/tmp1; tmp1 = -0.5f*g_corr[3]/tmp1; *gain_pit = (g_corr[2]*tmp2) - (0.5f*g_corr[4]*tmp1); *gain_code = (g_corr[0]*tmp1) - (0.5f*g_corr[4]*tmp2); *gain_pit = max(G_PITCH_MIN_TC192,min(*gain_pit,G_PITCH_MAX_TC192)); /* set number of bits for two SQs */ nBits2 = (nBits+1)>>1; nBits = nBits>>1; /* gain_pit Q */ tmp1 = (G_PITCH_MAX_TC192 - G_PITCH_MIN_TC192) / ((1 << nBits) - 1); /* set quantization step */ index = usquant( *gain_pit, gain_pit, G_PITCH_MIN_TC192, tmp1, (1 << nBits) ); push_indice( st, IND_GAIN_PIT, index, nBits ); /* gain_code Q */ *gain_code /= gcode0; index = gain_quant( gain_code, G_CODE_MIN_TC192, G_CODE_MAX_TC192, nBits2 ); push_indice( st, IND_GAIN_CODE, index, nBits2 ); *gain_code *= gcode0; } else { size = (short)pow2[nBits]; switch ( nBits ) { case 7: { qua_table = gain_qua_mless_7b; if ( clip_gain == 1 ) size -= 30; break; } case 6: { qua_table = gain_qua_mless_6b; if ( clip_gain == 1 ) size -= 14; break; } case 5: { qua_table = gain_qua_mless_5b; if ( clip_gain == 1 ) size -= 6; break; } default: { qua_table = gain_qua_mless_6b; if ( clip_gain == 1 ) size -= 14; break; } } /* in case of AVQ inactive, limit the gain_pit to 0.65 */ if( clip_gain == 2 && nBits == 6 ) { size -= 36; nBits--; } /*-----------------------------------------------------------------* * search for the best quantizer *-----------------------------------------------------------------*/ p = qua_table; dist_min = 3.402823466e+38F; index = 0; for (i = 0; i, -2,, -2 and 2 */ const short clip_gain /* i : gain pitch clipping flag (1 = clipping) */ ) { short index, nBits_pitch, nBits_code; float g_code, gcode0, Ei, Ecode, tmp1, tmp2; /*-----------------------------------------------------------------* * calculate the rest of the correlation coefficients * c2 = , c3 = -2, c4 = 2 *-----------------------------------------------------------------*/ g_corr[1] *= -0.5; g_corr[2] = dotp( y2, y2, L_SUBFR ) + 0.01f; g_corr[3] = dotp( xn, y2, L_SUBFR ) - 0.02f; g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f; /*-----------------------------------------------------------------* * calculate the unscaled innovation energy * calculate the predicted gain code * calculate optimal gains *-----------------------------------------------------------------*/ Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR; *gain_inov = 1.0f / (float)sqrt( Ecode ); Ei = 10 * (float)log10( Ecode ); gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei)); tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]); tmp2 = g_corr[1]/tmp1; tmp1 = g_corr[3]/tmp1; *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp1); *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2); *gain_pit = max(G_PITCH_MIN,min(*gain_pit,G_PITCH_MAX)); /*-----------------------------------------------------------------* * limit the pitch gain searching range (if indicated by clip_gain) *-----------------------------------------------------------------*/ if( clip_gain == 1 && *gain_pit > 0.95f ) { *gain_pit = 0.95f; } else if( clip_gain == 2 && *gain_pit > 0.65f ) { *gain_pit = 0.65f; } /*-----------------------------------------------------------------* * search for the best quantized values *-----------------------------------------------------------------*/ nBits_pitch = gain_bits_16kHz_tbl[ BIT_ALLOC_IDX_16KHZ(core_brate, coder_type, i_subfr, TC_SUBFR2IDX_16KHZ(tc_subfr)) ]; nBits_code = (nBits_pitch+1)>>1; nBits_pitch = nBits_pitch>>1; tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1); /* set quantization step */ index = usquant( *gain_pit, gain_pit, G_PITCH_MIN, tmp1, (1 << nBits_pitch) ); push_indice( st, IND_GAIN_PIT, index, nBits_pitch ); g_code = *gain_code / gcode0; index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits_code ); *gain_code = g_code * gcode0; push_indice( st, IND_GAIN_CODE, index, nBits_code); *norm_gain_code = *gain_code / *gain_inov; return; } /*-------------------------------------------------------------------* * gain_enc_gaus() * * Quantization of gain for Gaussian codebook *-------------------------------------------------------------------*/ short gain_enc_gaus( /* o : Return index of quantization */ float *gain, /* i/o: Code gain to quantize */ const short bits, /* i : number of bits to quantize */ const float lowBound, /* i : lower bound of quantizer (dB) */ const float topBound /* i : upper bound of quantizer (dB) */ ) { short index; float enr, stepSize; enr = (float)( 20.0 * log10( *gain + 0.001f ) ); /* codebook gain in dB */ /*-----------------------------------------------------------------* * quantize linearly the log E *-----------------------------------------------------------------*/ stepSize = (topBound-lowBound)/((float)(1<= (1< 3 ) { g_code = *gain_code / gcode0; index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits ); *gain_code = g_code * gcode0; push_indice( st, IND_GAIN_CODE, index, nBits ); } else { index = N_GAIN_CODE_TC-1; for( i=0; i < N_GAIN_CODE_TC-1; i++ ) { if( *gain_code < ((tbl_gain_code_tc[i]+(tbl_gain_code_tc[i+1]-tbl_gain_code_tc[i])/2) * gcode0) ) { index = i; break; } } /*----------------------------------------------------------------* * 3-bit -> 2-bit encoding *----------------------------------------------------------------*/ if( nBits == 2 ) { index /= 2; *gain_code = tbl_gain_code_tc[index*2] * gcode0; push_indice( st, IND_GAIN_CODE, index, nBits ); } else { *gain_code = tbl_gain_code_tc[index] * gcode0; push_indice( st, IND_GAIN_CODE, index, nBits ); } } *norm_gain_code = *gain_code / *gain_inov; return; } /*---------------------------------------------------------------------* * E_corr_xy2() * * Find the correlations between the target xn[], the filtered adaptive * codebook exc. y1[], and the filtered fixed codebook innovation y2[]. * ( , -2 and 2 ) (stored in g_corr[2..4]) *---------------------------------------------------------------------*/ void E_corr_xy2( const float xn[], /* i : target vector */ const float y1[], /* i : filtered excitation components 1 */ const float y2[], /* i : filtered excitation components 2 */ float g_corr[],/* o : correlations between x, y1, y2, y3, y4 */ const short L_subfr /* i : subframe size */ ) { g_corr[2] = dotp(y2, y2, L_subfr); g_corr[3] = -2.0f * dotp(xn, y2, L_subfr); g_corr[4] = 2.0f * dotp(y1, y2, L_subfr); return; } /*---------------------------------------------------------------------* * gain_enc_lbr() * * Quantization of pitch and codebook gains without prediction (memory-less) * in ACELP at 7.2 and 8.0 kbps * - the gain codebooks and gain estimation constants are different in each subframe * - the estimated gain, gcode0, is first determined based on * classification and/or previous quantized gains (from previous subframes in the current frame) * - a correction factor gamma = g_code / gcode0 is then vector quantized * along with gain_pit * - the mean-squared error criterion is used for codebook search *---------------------------------------------------------------------*/ void gain_enc_lbr( Encoder_State *st, /* i/o: encoder state structure */ const long core_brate, /* i : core bitrate */ const short coder_type, /* i : coding type */ const short i_subfr, /* i : subframe index */ const float *xn, /* i : target vector */ const float *y1, /* i : zero-memory filtered adaptive excitation */ const float *y2, /* i : zero-memory filtered algebraic codebook excitation */ const float *code, /* i : algebraic excitation */ float *gain_pit, /* o : quantized pitch gain */ float *gain_code, /* o : quantized codebook gain */ float *gain_inov, /* o : gain of the innovation (used for normalization) */ float *norm_gain_code, /* o : norm. gain of the codebook excitation */ float *g_corr, /* i/o: correlations , -2,, -2 and 2 */ float gains_mem[], /* i/o: pitch gain and code gain from previous subframes */ const short clip_gain /* i : gain pitch clipping flag (1 = clipping) */ ) { short index = 0, i, size, nBits, n_pred, ctype; float dist, dist_min, g_pitch, g_code, gcode0, aux[10], Ecode; short rf_flag = 0; const float *p, *b, *cdbk = 0; /*-----------------------------------------------------------------* * calculate the rest of the correlation coefficients * c2 = , c3 = -2, c4 = 2, c5* = * c5* - not necessary to calculate *-----------------------------------------------------------------*/ E_corr_xy2( xn, y1, y2, g_corr,L_SUBFR); g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F; Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR; *gain_inov = 1.0f / (float)sqrt(Ecode); /*-----------------------------------------------------------------* * select the codebook, size and number of bits * set the gains searching range *-----------------------------------------------------------------*/ nBits = gain_bits_tbl[BIT_ALLOC_IDX(core_brate, coder_type, i_subfr, 0)]; size = (short)pow2[nBits]; /*-----------------------------------------------------------------* * calculate prediction of gcode * search for the best codeword *-----------------------------------------------------------------*/ ctype = 2*(coder_type - 1); if (i_subfr == 0) { b = b_1sfr; n_pred = 2; switch ( nBits ) { case 8: { cdbk = gp_gamma_1sfr_8b; if ( clip_gain == 1 ) size -= 60; break; } case 7: { cdbk = gp_gamma_1sfr_7b; if ( clip_gain == 1 ) size -= 27; break; } case 6: { cdbk = gp_gamma_1sfr_6b; if ( clip_gain == 1 ) size -= 10; break; } } /* calculate predicted gain */ aux[0] = 1.0f; aux[1] = ctype; gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode)); /* searching of codebook */ p = cdbk; dist_min = 3.402823466e+38F; index = 0; for (i = 0; i