static void search_2i40( Word16 dn[], /* i : correlation between target and h[] */ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ Word16 codvec[], /* o : algebraic codebook vector */ Flag * pOverflow /* o : Flag set when overflow occurs */ ) { Word16 i0; Word16 i1; Word16 ix = 0; /* initialization only needed to keep gcc silent */ Word16 track1; Word16 track2; Word16 ipos[NB_PULSE]; Word16 psk; Word16 ps0; Word16 ps1; Word16 sq; Word16 sq1; Word16 alpk; Word16 alp; Word16 alp_16; Word32 s; Word32 alp0; Word32 alp1; Word16 i; Word16 *p_codvec = &codvec[0]; psk = -1; alpk = 1; for (i = 0; i < NB_PULSE; i++) { *(p_codvec++) = i; } /*------------------------------------------------------------------* * main loop: try 2x4 tracks. * *------------------------------------------------------------------*/ for (track1 = 0; track1 < 2; track1++) { for (track2 = 0; track2 < 4; track2++) { /* fix starting position */ ipos[0] = startPos1[track1]; ipos[1] = startPos2[track2]; /*----------------------------------------------------------------* * i0 loop: try 8 positions. * *----------------------------------------------------------------*/ for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) { ps0 = dn[i0]; /* alp0 = L_mult(rr[i0][i0], _1_4, pOverflow); */ alp0 = (Word32) rr[i0][i0] << 14; /*-------------------------------------------------------------* * i1 loop: 8 positions. * *-------------------------------------------------------------*/ sq = -1; alp = 1; ix = ipos[1]; /*---------------------------------------------------------------* * These index have low complexity address computation because * * they are, in fact, pointers with fixed increment. For example,* * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" * * and incremented by "STEP". * *---------------------------------------------------------------*/ for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) { /* idx increment = STEP */ ps1 = add_16(ps0, dn[i1], pOverflow); /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */ /* idx incr = STEP */ /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */ alp1 = alp0 + ((Word32) rr[i1][i1] << 14); /* idx incr = STEP */ /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */ alp1 += (Word32) rr[i0][i1] << 15; /* sq1 = mult(ps1, ps1, pOverflow); */ sq1 = (Word16)(((Word32) ps1 * ps1) >> 15); /* alp_16 = pv_round(alp1, pOverflow); */ alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16); /* s = L_mult(alp, sq1, pOverflow); */ s = ((Word32) alp * sq1) << 1; /* s =L_msu(s, sq, alp_16, pOverflow); */ s -= (((Word32) sq * alp_16) << 1); if (s > 0) { sq = sq1; alp = alp_16; ix = i1; } } /* for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) */ /* memorize codevector if this one is better than the last one. */ /* s = L_mult(alpk, sq, pOverflow); */ s = ((Word32) alpk * sq) << 1; /* s = L_msu(s, psk, alp, pOverflow); */ s -= (((Word32) psk * alp) << 1); if (s > 0) { psk = sq; alpk = alp; p_codvec = &codvec[0]; *(p_codvec++) = i0; *(p_codvec) = ix; } } /* for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) */ } /* for (track2 = 0; track2 < 4; track2++) */ } /* for (track1 = 0; track1 < 2; track1++) */ return; } /* search_2i40 */
/* ------------------------------------------------------------------------------ FUNCTION NAME: build_code ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: codvec, position of pulses, array of type Word16 dn_sign, sign of pulses, array of type Word16 h, impulse response of weighted synthesis filter, Word16 array Outputs: cod, innovative code vector, array of type Word16 y[], filtered innovative code, array of type Word16 sign[], sign of 2 pulses, array of type Word16 pOverflow, Flag set when overflow occurs, pointer of type Flag * Returns: Global Variables Used: None Local Variables Needed: None ------------------------------------------------------------------------------ FUNCTION DESCRIPTION Builds the codeword, the filtered codeword and index of the codevector, based on the signs and positions of 2 pulses. ------------------------------------------------------------------------------ REQUIREMENTS None ------------------------------------------------------------------------------ REFERENCES c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ static Word16 build_code( Word16 codvec[], /* i : position of pulses */ Word16 dn_sign[], /* i : sign of pulses */ Word16 cod[], /* o : innovative code vector */ Word16 h[], /* i : impulse response of weighted synthesis filter */ Word16 y[], /* o : filtered innovative code */ Word16 sign[], /* o : sign of 2 pulses */ Flag * pOverflow /* o : Flag set when overflow occurs */ ) { Word16 i; Word16 j; Word16 k; Word16 track; Word16 index; Word16 _sign[NB_PULSE]; Word16 indx; Word16 rsign; Word16 tempWord; Word16 *p0; Word16 *p1; Word32 s; for (i = 0; i < L_CODE; i++) { cod[i] = 0; } indx = 0; rsign = 0; for (k = 0; k < NB_PULSE; k++) { i = codvec[k]; /* read pulse position */ j = dn_sign[i]; /* read sign */ /* index = pos/5 */ /* index = mult(i, 6554, pOverflow); */ index = (Word16)(((Word32) i * 6554) >> 15); /* track = pos%5 */ /* tempWord = L_mult( index, 5, pOverflow); */ tempWord = (index << 3) + (index << 1); /* tempWord = L_shr( tempWord, 1, pOverflow); */ tempWord >>= 1; /* track = sub( i, tempWord, pOverflow); */ track = i - tempWord; tempWord = track; if (tempWord == 0) { track = 1; /* index = shl( index, 6, pOverflow); */ index <<= 6; } else if (track == 1) { tempWord = k; if (tempWord == 0) { track = 0; /* index = shl( index, 1, pOverflow); */ index <<= 1; } else { track = 1; /* tempWord = shl( index, 6, pOverflow); */ tempWord = index << 6; /* index = add( tempWord, 16, pOverflow); */ index = tempWord + 16; } } else if (track == 2) { track = 1; /* tempWord = shl( index, 6, pOverflow); */ tempWord = index << 6; /* index = add( tempWord, 32, pOverflow); */ index = tempWord + 32; } else if (track == 3) { track = 0; /* tempWord = shl( index, 1, pOverflow); */ tempWord = index << 1; /* index = add( tempWord, 1, pOverflow); */ index = tempWord + 1; } else if (track == 4) { track = 1; /* tempWord = shl( index, 6, pOverflow); */ tempWord = index << 6; /* index = add( tempWord, 48, pOverflow); */ index = tempWord + 48; } if (j > 0) { cod[i] = 8191; _sign[k] = 32767; tempWord = shl( 1, track, pOverflow); rsign = add_16( rsign, tempWord, pOverflow); } else { cod[i] = -8192; _sign[k] = (Word16) - 32768L; } indx = add_16( indx, index, pOverflow); } *sign = rsign; p0 = h - codvec[0]; p1 = h - codvec[1]; for (i = 0; i < L_CODE; i++) { s = 0; s = L_mac( s, *p0++, _sign[0], pOverflow); s = L_mac( s, *p1++, _sign[1], pOverflow); y[i] = pv_round( s, pOverflow); } return indx; }
Word16 Cb_gain_average( Cb_gain_averageState *st, /* i/o : State variables for CB gain averaging */ enum Mode mode, /* i : AMR mode */ Word16 gain_code, /* i : CB gain Q1 */ Word16 lsp[], /* i : The LSP for the current frame Q15 */ Word16 lspAver[], /* i : The average of LSP for 8 frames Q15 */ Word16 bfi, /* i : bad frame indication flag */ Word16 prev_bf, /* i : previous bad frame indication flag */ Word16 pdfi, /* i : potential degraded bad frame ind flag */ Word16 prev_pdf, /* i : prev pot. degraded bad frame ind flag */ Word16 inBackgroundNoise, /* i : background noise decision */ Word16 voicedHangover, /* i : # of frames after last voiced frame */ Flag *pOverflow ) { Word16 i; Word16 cbGainMix; Word16 diff; Word16 tmp_diff; Word16 bgMix; Word16 cbGainMean; Word32 L_sum; Word16 tmp[M]; Word16 tmp1; Word16 tmp2; Word16 shift1; Word16 shift2; Word16 shift; /*---------------------------------------------------------* * Compute mixed cb gain, used to make cb gain more * * smooth in background noise for modes 5.15, 5.9 and 6.7 * * states that needs to be updated by all * *---------------------------------------------------------*/ /* set correct cbGainMix for MR74, MR795, MR122 */ cbGainMix = gain_code; /*-------------------------------------------------------* * Store list of CB gain needed in the CB gain * * averaging * *-------------------------------------------------------*/ for (i = 0; i < (L_CBGAINHIST - 1); i++) { st->cbGainHistory[i] = st->cbGainHistory[i+1]; } st->cbGainHistory[L_CBGAINHIST-1] = gain_code; diff = 0; /* compute lsp difference */ for (i = 0; i < M; i++) { tmp1 = abs_s(sub(*(lspAver + i), *(lsp + i), pOverflow)); /* Q15 */ shift1 = norm_s(tmp1) - 1 ; /* Qn */ tmp1 = shl(tmp1, shift1, pOverflow); /* Q15+Qn */ shift2 = norm_s(*(lspAver + i)); /* Qm */ tmp2 = shl(*(lspAver + i), shift2, pOverflow); /* Q15+Qm */ tmp[i] = div_s(tmp1, tmp2); /* Q15+(Q15+Qn)-(Q15+Qm) */ shift = 2 + shift1 - shift2; if (shift >= 0) { *(tmp + i) = shr(*(tmp + i), shift, pOverflow); /* Q15+Qn-Qm-Qx=Q13 */ } else { *(tmp + i) = shl(*(tmp + i), negate(shift), pOverflow); /* Q15+Qn-Qm-Qx=Q13 */ } diff = add_16(diff, *(tmp + i), pOverflow); /* Q13 */ } /* Compute hangover */ if (diff > 5325) /* 0.65 in Q11 */ { st->hangVar += 1; } else { st->hangVar = 0; } if (st->hangVar > 10) { /* Speech period, reset hangover variable */ st->hangCount = 0; } /* Compute mix constant (bgMix) */ bgMix = 8192; /* 1 in Q13 */ if ((mode <= MR67) || (mode == MR102)) /* MR475, MR515, MR59, MR67, MR102 */ { /* if errors and presumed noise make smoothing probability stronger */ if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) || (prev_bf != 0)) && (voicedHangover > 1) && (inBackgroundNoise != 0) && ((mode == MR475) || (mode == MR515) || (mode == MR59)))) { /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */ tmp_diff = diff - 4506; /* 0.55 in Q13 */ } else { /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */ tmp_diff = diff - 3277; /* 0.4 in Q13 */ } /* max(0.0, diff-0.55) or */ /* max(0.0, diff-0.40) */ if (tmp_diff > 0) { tmp1 = tmp_diff; } else { tmp1 = 0; } /* min(0.25, tmp1) */ if (2048 < tmp1) { bgMix = 8192; } else { bgMix = shl(tmp1, 2, pOverflow); } if ((st->hangCount < 40) || (diff > 5325)) /* 0.65 in Q13 */ { /* disable mix if too short time since */ bgMix = 8192; } /* Smoothen the cb gain trajectory */ /* smoothing depends on mix constant bgMix */ L_sum = L_mult(6554, st->cbGainHistory[2], pOverflow); /* 0.2 in Q15; L_sum in Q17 */ for (i = 3; i < L_CBGAINHIST; i++) { L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i], pOverflow); } cbGainMean = pv_round(L_sum, pOverflow); /* Q1 */ /* more smoothing in error and bg noise (NB no DFI used here) */ if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0) && ((mode == MR475) || (mode == MR515) || (mode == MR59))) { /* 0.143 in Q15; L_sum in Q17 */ L_sum = L_mult(4681, st->cbGainHistory[0], pOverflow); for (i = 1; i < L_CBGAINHIST; i++) { L_sum = L_mac(L_sum, 4681, st->cbGainHistory[i], pOverflow); } cbGainMean = pv_round(L_sum, pOverflow); /* Q1 */ } /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */ /* L_sum in Q15 */ L_sum = L_mult(bgMix, cbGainMix, pOverflow); L_sum = L_mac(L_sum, 8192, cbGainMean, pOverflow); L_sum = L_msu(L_sum, bgMix, cbGainMean, pOverflow); cbGainMix = pv_round(L_shl(L_sum, 2, pOverflow), pOverflow); /* Q1 */ } st->hangCount += 1; return (cbGainMix); }
/* ------------------------------------------------------------------------------ FUNCTION NAME: code_2i40_11bits ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: x, target vector, array of type Word16 h, impulse response of weighted synthesis filter, array of type Word16 T0, Pitch lag, variable of type Word16 pitch_sharp, Last quantized pitch gain, variable of type Word16 Outputs: code[], Innovative codebook, array of type Word16 y[], filtered fixed codebook excitation, array of type Word16 sign, Signs of 2 pulses, pointer of type Word16 * pOverflow Flag set when overflow occurs, pointer of type Flag * Returns: index Global Variables Used: None Local Variables Needed: None ------------------------------------------------------------------------------ FUNCTION DESCRIPTION Searches a 11 bit algebraic codebook containing 2 pulses in a frame of 40 samples. The code length is 40, containing 2 nonzero pulses: i0...i1. All pulses can have two possible amplitudes: +1 or -1. Pulse i0 can have 2x8=16 possible positions, pulse i1 can have 4x8=32 positions. i0 : 1, 6, 11, 16, 21, 26, 31, 36. 3, 8, 13, 18, 23, 28, 33, 38. i1 : 0, 5, 10, 15, 20, 25, 30, 35. 1, 6, 11, 16, 21, 26, 31, 36. 2, 7, 12, 17, 22, 27, 32, 37. 4, 9, 14, 19, 24, 29, 34, 39. ------------------------------------------------------------------------------ REQUIREMENTS None ------------------------------------------------------------------------------ REFERENCES c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 ------------------------------------------------------------------------------ PSEUDO-CODE ------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function] ------------------------------------------------------------------------------ */ Word16 code_2i40_11bits( Word16 x[], /* i : target vector */ Word16 h[], /* i : impulse response of weighted synthesis filter */ /* h[-L_subfr..-1] must be set to zero. */ Word16 T0, /* i : Pitch lag */ Word16 pitch_sharp, /* i : Last quantized pitch gain */ Word16 code[], /* o : Innovative codebook */ Word16 y[], /* o : filtered fixed codebook excitation */ Word16 * sign, /* o : Signs of 2 pulses */ Flag * pOverflow /* o : Flag set when overflow occurs */ ) { Word16 codvec[NB_PULSE]; Word16 dn[L_CODE]; Word16 dn2[L_CODE]; Word16 dn_sign[L_CODE]; Word16 rr[L_CODE][L_CODE]; Word16 i; Word16 index; Word16 sharp; Word16 tempWord; sharp = pitch_sharp << 1; if (T0 < L_CODE) { for (i = T0; i < L_CODE; i++) { tempWord = mult( h[i - T0], sharp, pOverflow); h[i] = add_16( h[i], tempWord, pOverflow); } } cor_h_x( h, x, dn, 1, pOverflow); set_sign( dn, dn_sign, dn2, 8); /* dn2[] not used in this codebook search */ cor_h( h, dn_sign, rr, pOverflow); search_2i40( dn, rr, codvec, pOverflow); /* function result */ index = build_code( codvec, dn_sign, code, h, y, sign, pOverflow); /* * Compute innovation vector gain. * Include fixed-gain pitch contribution into code[]. */ if (T0 < L_CODE) { for (i = T0; i < L_CODE; i++) { tempWord = mult( code[i - T0], sharp, pOverflow); code[i] = add_16( code[i], tempWord, pOverflow); } } return index; }
void cbsearch(Word16 x[], /* i : target vector, Q0 */ Word16 h[], /* i : impulse response of weighted synthesis*/ /* filter h[-L_subfr..-1] must be set to */ /* zero. Q12 */ Word16 T0, /* i : Pitch lag */ Word16 pitch_sharp,/* i : Last quantized pitch gain, Q14 */ Word16 gain_pit, /* i : Pitch gain, Q14 */ Word16 res2[], /* i : Long term prediction residual, Q0 */ Word16 code[], /* o : Innovative codebook, Q13 */ Word16 y[], /* o : filtered fixed codebook excitation */ /* Q12 */ Word16 **anap, /* o : Signs of the pulses */ enum Mode mode, /* i : coder mode */ Word16 subNr, /* i : subframe number */ CommonAmrTbls* common_amr_tbls, /* ptr to struct of tables */ Flag *pOverflow) /* o : Flag set when overflow occurs */ { Word16 index; Word16 i; Word16 temp; Word16 pit_sharpTmp; /* For MR74, the pre and post CB pitch sharpening is included in the * codebook search routine, while for MR122 is it not. */ if ((mode == MR475) || (mode == MR515)) { /* MR475, MR515 */ *(*anap)++ = code_2i40_9bits( subNr, x, h, T0, pitch_sharp, code, y, &index, common_amr_tbls->startPos_ptr, pOverflow); *(*anap)++ = index; /* sign index */ } else if (mode == MR59) { /* MR59 */ *(*anap)++ = code_2i40_11bits( x, h, T0, pitch_sharp, code, y, &index, pOverflow); *(*anap)++ = index; /* sign index */ } else if (mode == MR67) { /* MR67 */ *(*anap)++ = code_3i40_14bits( x, h, T0, pitch_sharp, code, y, &index, pOverflow); *(*anap)++ = index; /* sign index */ } else if ((mode == MR74) || (mode == MR795)) { /* MR74, MR795 */ *(*anap)++ = code_4i40_17bits( x, h, T0, pitch_sharp, code, y, &index, common_amr_tbls->gray_ptr, pOverflow); *(*anap)++ = index; /* sign index */ } else if (mode == MR102) { /* MR102 */ /*-------------------------------------------------------------* * - include pitch contribution into impulse resp. h1[] * *-------------------------------------------------------------*/ /* pit_sharpTmp = pit_sharp; */ /* if (pit_sharpTmp > 1.0) pit_sharpTmp = 1.0; */ pit_sharpTmp = shl( pitch_sharp, 1, pOverflow); for (i = T0; i < L_SUBFR; i++) { temp = mult( h[i - T0], pit_sharpTmp, pOverflow); h[i] = add_16( h[i], temp, pOverflow); } /*--------------------------------------------------------------* * - Innovative codebook search (find index and gain) * *--------------------------------------------------------------*/ code_8i40_31bits( x, res2, h, code, y, *anap, pOverflow); *anap += 7; /*-------------------------------------------------------* * - Add the pitch contribution to code[]. * *-------------------------------------------------------*/ for (i = T0; i < L_SUBFR; i++) { temp = mult( code[i - T0], pit_sharpTmp, pOverflow); code[i] = add_16( code[i], temp, pOverflow); } } else { /* MR122 */ /*-------------------------------------------------------------* * - include pitch contribution into impulse resp. h1[] * *-------------------------------------------------------------*/ /* pit_sharpTmp = gain_pit; */ /* if (pit_sharpTmp > 1.0) pit_sharpTmp = 1.0; */ pit_sharpTmp = shl(gain_pit, 1, pOverflow); for (i = T0; i < L_SUBFR; i++) { temp = ((Word32)h[i - T0] * pit_sharpTmp) >> 15; /* mult( h[i - T0], , pOverflow); */ h[i] = add_16( h[i], temp, pOverflow); } /*--------------------------------------------------------------* * - Innovative codebook search (find index and gain) * *--------------------------------------------------------------*/ code_10i40_35bits( x, res2, h, code, y, *anap, common_amr_tbls->gray_ptr, pOverflow); *anap += 10; /*-------------------------------------------------------* * - Add the pitch contribution to code[]. * *-------------------------------------------------------*/ for (i = T0; i < L_SUBFR; i++) { temp = mult( code[i - T0], pit_sharpTmp, pOverflow); code[i] = add_16( code[i], temp, pOverflow); } } }
static Word16 MR795_gain_code_quant_mod( /* o : index of quantization. */ Word16 gain_pit, /* i : pitch gain, Q14 */ Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ Word16 frac_en[], /* i : energy coefficients (4), fraction part, Q15 */ Word16 exp_en[], /* i : energy coefficients (4), eponent part, Q0 */ Word16 alpha, /* i : gain adaptor factor (>0), Q15 */ Word16 gain_cod_unq, /* i : Code gain (unquantized) */ /* (scaling: Q10 - exp_gcode0) */ Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */ Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ /* (for MR122 MA predictor update) */ Word16 *qua_ener, /* o : quantized energy error, Q10 */ /* (for other MA predictor update) */ const Word16* qua_gain_code_ptr, /* i : ptr to read-only ptr */ Flag *pOverflow /* o : overflow indicator */ ) { const Word16 *p; Word16 i; Word16 index; Word16 tmp; Word16 one_alpha; Word16 exp; Word16 e_max; Word16 g2_pitch; Word16 g_code; Word16 g2_code_h; Word16 g2_code_l; Word16 d2_code_h; Word16 d2_code_l; Word16 coeff[5]; Word16 coeff_lo[5]; Word16 exp_coeff[5]; Word32 L_tmp; Word32 L_t0; Word32 L_t1; Word32 dist_min; Word16 gain_code; /* Steps in calculation of the error criterion (dist): --------------------------------------------------- underlined = constant; alp = FLP value of alpha, alpha = FIP ---------- ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn; ------------ ------ -- ----- aExEn= alp * ExEn = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2 -------------- ------------- --------- = t[1] + t[2] + t[3] dist = d1 + d2; d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4] ------------------- --- d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn); --- ----- --- ----- = alp * (sqrt(ExEn) - sqrt(ResEn))^2 --- ----------- = (sqrt(aExEn) - sqrt(alp*ResEn))^2 --------------- = (sqrt(aExEn) - t[0] )^2 ---- */ /* * calculate scalings of the constant terms */ gain_code = shl(*gain_cod, (10 - exp_gcode0), pOverflow); /* Q1 -> Q11 (-ec0) */ g2_pitch = mult(gain_pit, gain_pit, pOverflow); /* Q14 -> Q13 */ /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */ one_alpha = add_16((32767 - alpha), 1, pOverflow); /* 32768 - alpha */ /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ L_t1 = L_mult(alpha, frac_en[1], pOverflow); L_t1 = L_shl(L_t1, 1, pOverflow); tmp = (Word16)(L_t1 >> 16); /* directly store in 32 bit variable because no further mult. required */ L_t1 = L_mult(tmp, g2_pitch, pOverflow); exp_coeff[1] = exp_en[1] - 15; tmp = (Word16)(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow) >> 16); coeff[2] = mult(tmp, gain_pit, pOverflow); exp = exp_gcode0 - 10; exp_coeff[2] = add_16(exp_en[2], exp, pOverflow); /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ coeff[3] = (Word16)(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow) >> 16); exp = shl(exp_gcode0, 1, pOverflow) - 7; exp_coeff[3] = add_16(exp_en[3], exp, pOverflow); coeff[4] = mult(one_alpha, frac_en[3], pOverflow); exp_coeff[4] = add_16(exp_coeff[3], 1, pOverflow); L_tmp = L_mult(alpha, frac_en[0], pOverflow); /* sqrt_l returns normalized value and 2*exponent -> result = val >> (exp/2) exp_coeff holds 2*exponent for c[0] */ /* directly store in 32 bit variable because no further mult. required */ L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow); /* normalization included in sqrt_l_exp */ exp += 47; exp_coeff[0] = exp_en[0] - exp; /* * Determine the maximum exponent occuring in the distance calculation * and adjust all fractions accordingly (including a safety margin) * */ /* find max(e[1..4],e[0]+31) */ e_max = exp_coeff[0] + 31; for (i = 1; i <= 4; i++) { if (exp_coeff[i] > e_max) { e_max = exp_coeff[i]; } } /* scale c[1] (requires no further multiplication) */ tmp = e_max - exp_coeff[1]; L_t1 = L_shr(L_t1, tmp, pOverflow); /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */ for (i = 2; i <= 4; i++) { tmp = e_max - exp_coeff[i]; L_tmp = ((Word32)coeff[i] << 16); L_tmp = L_shr(L_tmp, tmp, pOverflow); L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); } /* scale c[0] (requires no further multiplication) */ exp = e_max - 31; /* new exponent */ tmp = exp - exp_coeff[0]; L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow); /* perform correction by 1/sqrt(2) if exponent difference is odd */ if ((tmp & 0x1) != 0) { L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow); L_t0 = Mpy_32_16(coeff[0], coeff_lo[0], 23170, pOverflow); /* 23170 Q15 = 1/sqrt(2)*/ } /* search the quantizer table for the lowest value of the search criterion */ dist_min = MAX_32; index = 0; p = &qua_gain_code_ptr[0]; for (i = 0; i < NB_QUA_CODE; i++) { g_code = *p++; /* this is g_fac (Q11) */ p++; /* skip log2(g_fac) */ p++; /* skip 20*log10(g_fac) */ g_code = mult(g_code, gcode0, pOverflow); /* only continue if gc[i] < 2.0*gc which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */ if (g_code >= gain_code) { break; } L_tmp = L_mult(g_code, g_code, pOverflow); L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow); tmp = sub(g_code, gain_cod_unq, pOverflow); L_tmp = L_mult(tmp, tmp, pOverflow); L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow); /* t2, t3, t4 */ L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow); L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow); L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow); L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow); /* d2 */ tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow); L_tmp = L_mult(tmp, tmp, pOverflow); /* dist */ L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow); /* store table index if distance measure for this index is lower than the minimum seen so far */ if (L_tmp < dist_min) { dist_min = L_tmp; index = i; } } /*------------------------------------------------------------------* * read quantized gains and new values for MA predictor memories * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *------------------------------------------------------------------*/ /* Read the quantized gains */ p = &qua_gain_code_ptr[(index<<2) - index]; g_code = *p++; *qua_ener_MR122 = *p++; *qua_ener = *p; /*------------------------------------------------------------------* * calculate final fixed codebook gain: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * gc = gc0 * g * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0, pOverflow); L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow); *gain_cod = (Word16)(L_tmp >> 16); return index; }
static void MR795_gain_code_quant3( Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ Word16 g_pitch_cand[], /* i : Pitch gain candidates (3), Q14 */ Word16 g_pitch_cind[], /* i : Pitch gain cand. indices (3), Q0 */ Word16 frac_coeff[], /* i : coefficients (5), Q15 */ Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ /* coefficients from calc_filt_ener()*/ Word16 *gain_pit, /* o : Pitch gain, Q14 */ Word16 *gain_pit_ind, /* o : Pitch gain index, Q0 */ Word16 *gain_cod, /* o : Code gain, Q1 */ Word16 *gain_cod_ind, /* o : Code gain index, Q0 */ Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ /* (for MR122 MA predictor update) */ Word16 *qua_ener, /* o : quantized energy error, Q10 */ /* (for other MA predictor update) */ const Word16* qua_gain_code_ptr, /* i : ptr to read-only table */ Flag *pOverflow /* o : overflow indicator */ ) { const Word16 *p; Word16 i; Word16 j; Word16 cod_ind; Word16 pit_ind; Word16 e_max; Word16 exp_code; Word16 g_pitch; Word16 g2_pitch; Word16 g_code; Word16 g2_code_h; Word16 g2_code_l; Word16 g_pit_cod_h; Word16 g_pit_cod_l; Word16 coeff[5]; Word16 coeff_lo[5]; Word16 exp_max[5]; Word32 L_tmp; Word32 L_tmp0; Word32 dist_min; /* * The error energy (sum) to be minimized consists of five terms, t[0..4]. * * t[0] = gp^2 * <y1 y1> * t[1] = -2*gp * <xn y1> * t[2] = gc^2 * <y2 y2> * t[3] = -2*gc * <xn y2> * t[4] = 2*gp*gc * <y1 y2> * */ /* determine the scaling exponent for g_code: ec = ec0 - 10 */ exp_code = exp_gcode0 - 10; /* calculate exp_max[i] = s[i]-1 */ exp_max[0] = exp_coeff[0] - 13; exp_max[1] = exp_coeff[1] - 14; exp_max[2] = exp_coeff[2] + shl(exp_code, 1, pOverflow) + 15; exp_max[3] = exp_coeff[3] + exp_code; exp_max[4] = exp_coeff[4] + (exp_code + 1); /*-------------------------------------------------------------------* * Find maximum exponent: * * ~~~~~~~~~~~~~~~~~~~~~~ * * * * For the sum operation, all terms must have the same scaling; * * that scaling should be low enough to prevent overflow. There- * * fore, the maximum scale is determined and all coefficients are * * re-scaled: * * * * e_max = max(exp_max[i]) + 1; * * e = exp_max[i]-e_max; e <= 0! * * c[i] = c[i]*2^e * *-------------------------------------------------------------------*/ e_max = exp_max[0]; for (i = 1; i < 5; i++) /* implemented flattened */ { if (exp_max[i] > e_max) { e_max = exp_max[i]; } } e_max = add_16(e_max, 1, pOverflow); /* To avoid overflow */ for (i = 0; i < 5; i++) { j = e_max - exp_max[i]; L_tmp = ((Word32)frac_coeff[i] << 16); L_tmp = L_shr(L_tmp, j, pOverflow); L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); } /*-------------------------------------------------------------------* * Codebook search: * * ~~~~~~~~~~~~~~~~ * * * * For each of the candiates LTP gains in g_pitch_cand[], the terms * * t[0..4] are calculated from the values in the table (and the * * pitch gain candidate) and summed up; the result is the mean * * squared error for the LPT/CB gain pair. The index for the mini- * * mum MSE is stored and finally used to retrieve the quantized CB * * gain * *-------------------------------------------------------------------*/ /* start with "infinite" MSE */ dist_min = MAX_32; cod_ind = 0; pit_ind = 0; /* loop through LTP gain candidates */ for (j = 0; j < 3; j++) { /* pre-calculate terms only dependent on pitch gain */ g_pitch = g_pitch_cand[j]; g2_pitch = mult(g_pitch, g_pitch, pOverflow); L_tmp0 = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow); L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch, pOverflow); p = &qua_gain_code_ptr[0]; for (i = 0; i < NB_QUA_CODE; i++) { g_code = *p++; /* this is g_fac Q11 */ p++; /* skip log2(g_fac) */ p++; /* skip 20*log10(g_fac) */ g_code = mult(g_code, gcode0, pOverflow); L_tmp = L_mult(g_code, g_code, pOverflow); L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow); L_tmp = L_mult(g_code, g_pitch, pOverflow); L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow); L_tmp = Mac_32(L_tmp0, coeff[2], coeff_lo[2], g2_code_h, g2_code_l, pOverflow); L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], g_code, pOverflow); L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], g_pit_cod_h, g_pit_cod_l, pOverflow); /* store table index if MSE for this index is lower than the minimum MSE seen so far; also store the pitch gain for this (so far) lowest MSE */ if (L_tmp < dist_min) { dist_min = L_tmp; cod_ind = i; pit_ind = j; } } } /*------------------------------------------------------------------* * read quantized gains and new values for MA predictor memories * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *------------------------------------------------------------------*/ /* Read the quantized gains */ p = &qua_gain_code_ptr[(cod_ind<<2) - cod_ind]; g_code = *p++; *qua_ener_MR122 = *p++; *qua_ener = *p; /*------------------------------------------------------------------* * calculate final fixed codebook gain: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * gc = gc0 * g * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0, pOverflow); L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow); *gain_cod = (Word16)(L_tmp >> 16); *gain_cod_ind = cod_ind; *gain_pit = g_pitch_cand[pit_ind]; *gain_pit_ind = g_pitch_cind[pit_ind]; }
Word16 Qua_gain( /* o : index of quantization. */ enum Mode mode, /* i : AMR mode */ Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ Word16 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */ Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */ /* (frac_coeff and exp_coeff computed in */ /* calc_filt_energies()) */ Word16 gp_limit, /* i : pitch gain limit */ Word16 *gain_pit, /* o : Pitch gain, Q14 */ Word16 *gain_cod, /* o : Code gain, Q1 */ Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ /* (for MR122 MA predictor update) */ Word16 *qua_ener, /* o : quantized energy error, Q10 */ /* (for other MA predictor update) */ CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of tables ptrs */ Flag *pOverflow /* o : overflow indicator */ ) { const Word16 *p; Word16 i; Word16 j; Word16 index = 0; Word16 gcode0; Word16 e_max; Word16 temp; Word16 exp_code; Word16 g_pitch; Word16 g2_pitch; Word16 g_code; Word16 g2_code; Word16 g_pit_cod; Word16 coeff[5]; Word16 coeff_lo[5]; Word16 exp_max[5]; Word32 L_tmp; Word32 L_tmp2; Word32 dist_min; const Word16 *table_gain; Word16 table_len; if (mode == MR102 || mode == MR74 || mode == MR67) { table_len = VQ_SIZE_HIGHRATES; table_gain = common_amr_tbls->table_gain_highrates_ptr; } else { table_len = VQ_SIZE_LOWRATES; table_gain = common_amr_tbls->table_gain_lowrates_ptr; } /*-------------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * * * * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * *-------------------------------------------------------------------*/ gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); /*-------------------------------------------------------------------* * Scaling considerations: * * ~~~~~~~~~~~~~~~~~~~~~~~ * *-------------------------------------------------------------------*/ /* * The error energy (sum) to be minimized consists of five terms, t[0..4]. * * t[0] = gp^2 * <y1 y1> * t[1] = -2*gp * <xn y1> * t[2] = gc^2 * <y2 y2> * t[3] = -2*gc * <xn y2> * t[4] = 2*gp*gc * <y1 y2> * */ /* determine the scaling exponent for g_code: ec = ec0 - 11 */ exp_code = exp_gcode0 - 11; /* calculate exp_max[i] = s[i]-1 */ exp_max[0] = exp_coeff[0] - 13; exp_max[1] = exp_coeff[1] - 14; temp = shl(exp_code, 1, pOverflow); temp += 15; exp_max[2] = add_16(exp_coeff[2], temp, pOverflow); exp_max[3] = add_16(exp_coeff[3], exp_code, pOverflow); temp = exp_code + 1; exp_max[4] = add_16(exp_coeff[4], temp, pOverflow); /*-------------------------------------------------------------------* * Find maximum exponent: * * ~~~~~~~~~~~~~~~~~~~~~~ * * * * For the sum operation, all terms must have the same scaling; * * that scaling should be low enough to prevent overflow. There- * * fore, the maximum scale is determined and all coefficients are * * re-scaled: * * * * e_max = max(exp_max[i]) + 1; * * e = exp_max[i]-e_max; e <= 0! * * c[i] = c[i]*2^e * *-------------------------------------------------------------------*/ e_max = exp_max[0]; for (i = 1; i < 5; i++) { if (exp_max[i] > e_max) { e_max = exp_max[i]; } } e_max++; for (i = 0; i < 5; i++) { j = e_max - exp_max[i]; L_tmp = ((Word32)frac_coeff[i] << 16); L_tmp = L_shr(L_tmp, j, pOverflow); L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); } /*-------------------------------------------------------------------* * Codebook search: * * ~~~~~~~~~~~~~~~~ * * * * For each pair (g_pitch, g_fac) in the table calculate the * * terms t[0..4] and sum them up; the result is the mean squared * * error for the quantized gains from the table. The index for the * * minimum MSE is stored and finally used to retrieve the quantized * * gains * *-------------------------------------------------------------------*/ /* start with "infinite" MSE */ dist_min = MAX_32; p = &table_gain[0]; for (i = 0; i < table_len; i++) { g_pitch = *p++; g_code = *p++; /* this is g_fac */ p++; /* skip log2(g_fac) */ p++; /* skip 20*log10(g_fac) */ if (g_pitch <= gp_limit) { g_code = mult(g_code, gcode0, pOverflow); g2_pitch = mult(g_pitch, g_pitch, pOverflow); g2_code = mult(g_code, g_code, pOverflow); g_pit_cod = mult(g_code, g_pitch, pOverflow); L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow); L_tmp2 = Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow); L_tmp = L_add(L_tmp, L_tmp2, pOverflow); L_tmp2 = Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow); L_tmp = L_add(L_tmp, L_tmp2, pOverflow); L_tmp2 = Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow); L_tmp = L_add(L_tmp, L_tmp2, pOverflow); L_tmp2 = Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow); L_tmp = L_add(L_tmp, L_tmp2, pOverflow); /* store table index if MSE for this index is lower than the minimum MSE seen so far */ if (L_tmp < dist_min) { dist_min = L_tmp; index = i; } } } /*------------------------------------------------------------------* * read quantized gains and new values for MA predictor memories * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *------------------------------------------------------------------*/ /* Read the quantized gains */ p = &table_gain[shl(index, 2, pOverflow)]; *gain_pit = *p++; g_code = *p++; *qua_ener_MR122 = *p++; *qua_ener = *p; /*------------------------------------------------------------------* * calculate final fixed codebook gain: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * gc = gc0 * g * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0, pOverflow); temp = 10 - exp_gcode0; L_tmp = L_shr(L_tmp, temp, pOverflow); *gain_cod = (Word16)(L_tmp >> 16); return index; }
Word16 code_2i40_9bits( Word16 subNr, /* i : subframe number */ Word16 x[], /* i : target vector */ Word16 h[], /* i : impulse response of weighted synthesis */ /* filter h[-L_subfr..-1] must be set to 0. */ Word16 T0, /* i : Pitch lag */ Word16 pitch_sharp, /* i : Last quantized pitch gain */ Word16 code[], /* o : Innovative codebook */ Word16 y[], /* o : filtered fixed codebook excitation */ Word16 * sign, /* o : Signs of 2 pulses */ const Word16* startPos_ptr, /* ptr to read-only table */ Flag * pOverflow /* o : Flag set when overflow occurs */ ) { Word16 codvec[NB_PULSE]; Word16 dn[L_CODE]; Word16 dn2[L_CODE]; Word16 dn_sign[L_CODE]; Word16 rr[L_CODE][L_CODE]; register Word16 i; Word16 index; Word16 sharp; Word16 temp; Word32 L_temp; L_temp = ((Word32) pitch_sharp) << 1; /* Check for overflow condition */ if (L_temp != (Word32)((Word16) L_temp)) { *(pOverflow) = 1; sharp = (pitch_sharp > 0) ? MAX_16 : MIN_16; } else { sharp = (Word16) L_temp; } if (T0 < L_CODE) { for (i = T0; i < L_CODE; i++) { temp = mult( *(h + i - T0), sharp, pOverflow); *(h + i) = add_16( *(h + i), temp, pOverflow); } } cor_h_x( h, x, dn, 1, pOverflow); /* dn2[] not used in this codebook search */ set_sign( dn, dn_sign, dn2, 8); cor_h( h, dn_sign, rr, pOverflow); search_2i40( subNr, dn, rr, startPos_ptr, codvec, pOverflow); index = build_code( subNr, codvec, dn_sign, code, h, y, sign, pOverflow); /*-----------------------------------------------------------------* * Compute innovation vector gain. * * Include fixed-gain pitch contribution into code[]. * *-----------------------------------------------------------------*/ if (T0 < L_CODE) { for (i = T0; i < L_CODE; i++) { temp = mult( *(code + i - T0), sharp, pOverflow); *(code + i) = add_16( *(code + i), temp, pOverflow); } } return(index); }