Word32 quant_2p_2N1( /* (o) return (2*N)+1 bits */ Word16 pos1, /* (i) position of the pulse 1 */ Word16 pos2, /* (i) position of the pulse 2 */ Word16 N) /* (i) number of bits for position */ { Word16 mask, tmp; Word32 index; mask = (1 << N) - 1; /* mask = ((1<<N)-1); */ /*-------------------------------------------------------* * Quantization of 2 pulses with 2*N+1 bits: * // 2×n + 1位2脉冲量化 *-------------------------------------------------------*/ if (((pos2 ^ pos1) & NB_POS) == 0) { /* sign of 1st pulse == sign of 2th pulse */ // 标志第一脉冲= =第二签名脉冲 if(pos1 <= pos2) /* ((pos1 - pos2) <= 0) */ { /* index = ((pos1 & mask) << N) + (pos2 & mask); */ index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask)))); } else { /* ((pos2 & mask) << N) + (pos1 & mask); */ index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask)))); } if ((pos1 & NB_POS) != 0) { tmp = (N << 1); index = vo_L_add(index, (1L << tmp)); /* index += 1 << (2*N); */ } } else { /* sign of 1st pulse != sign of 2th pulse */ // 第一脉冲信号!=第二脉冲信号 if (vo_sub((Word16) (pos1 & mask), (Word16) (pos2 & mask)) <= 0) { /* index = ((pos2 & mask) << N) + (pos1 & mask); */ index = L_deposit_l(add1((((Word16) (pos2 & mask)) << N), ((Word16) (pos1 & mask)))); if ((pos2 & NB_POS) != 0) { tmp = (N << 1); /* index += 1 << (2*N); */ index = vo_L_add(index, (1L << tmp)); } } else { /* index = ((pos1 & mask) << N) + (pos2 & mask); */ index = L_deposit_l(add1((((Word16) (pos1 & mask)) << N), ((Word16) (pos2 & mask)))); if ((pos1 & NB_POS) != 0) { tmp = (N << 1); index = vo_L_add(index, (1 << tmp)); /* index += 1 << (2*N); */ } } } return (index); }
/*-------------------------------------------------------------------* * Function Qua_Sidgain * * ~~~~~~~~~~~ * *-------------------------------------------------------------------*/ void Qua_Sidgain( Word16 *ener, /* (i) array of energies */ Word16 *sh_ener, /* (i) corresponding scaling factors */ Word16 nb_ener, /* (i) number of energies or */ Word16 *enerq, /* (o) decoded energies in dB */ Word16 *idx /* (o) SID gain quantization index */ ) { Word16 i; Word32 L_x; Word16 sh1, temp; Word16 hi, lo; Word32 L_acc; if(nb_ener == 0) { /* Quantize energy saved for frame erasure case */ /* L_x = average_ener */ L_acc = L_deposit_l(*ener); L_acc = L_shl(L_acc, *sh_ener); /* >> if *sh_ener < 0 */ L_Extract(L_acc, &hi, &lo); L_x = Mpy_32_16(hi, lo, fact[0]); sh1 = 0; } else { /* * Compute weighted average of energies * ener[i] = enerR[i] x 2**sh_ener[i] * L_x = k[nb_ener] x SUM(i=0->nb_ener-1) enerR[i] * with k[nb_ener] = fact_ener / nb_ener x L_FRAME x nbAcf */ sh1 = sh_ener[0]; for(i=1; i<nb_ener; i++) { if(sh_ener[i] < sh1) sh1 = sh_ener[i]; } sh1 = add(sh1, (16-marg[nb_ener])); L_x = 0L; for(i=0; i<nb_ener; i++) { temp = sub(sh1, sh_ener[i]); L_acc = L_deposit_l(ener[i]); L_acc = L_shl(L_acc, temp); L_x = L_add(L_x, L_acc); } L_Extract(L_x, &hi, &lo); L_x = Mpy_32_16(hi, lo, fact[i]); } *idx = Quant_Energy(L_x, sh1, enerq); return; }
Word32 quant_1p_N1( /* (o) return N+1 bits */ Word16 pos, /* (i) position of the pulse */ Word16 N) /* (i) number of bits for position */ { Word16 mask; Word32 index; mask = (1 << N) - 1; /* mask = ((1<<N)-1); */ /*-------------------------------------------------------* * Quantization of 1 pulse with N+1 bits: * *-------------------------------------------------------*/ index = L_deposit_l((Word16) (pos & mask)); if ((pos & NB_POS) != 0) { index = vo_L_add(index, L_deposit_l(1 << N)); /* index += 1 << N; */ } return (index); }
static Word16 Cmp_filt(Word16 *RCoeff, Word16 sh_RCoeff, Word16 *acf, Word16 alpha, Word16 FracThresh) { Word32 L_temp0, L_temp1; Word16 temp1, temp2, sh[2], ind; Word16 i; Word16 diff, flag; extern Flag Overflow; sh[0] = 0; sh[1] = 0; ind = 1; flag = 0; do { Overflow = 0; temp1 = shr(RCoeff[0], sh[0]); temp2 = shr(acf[0], sh[1]); L_temp0 = L_shr(L_mult(temp1, temp2),1); for(i=1; i <= M; i++) { temp1 = shr(RCoeff[i], sh[0]); temp2 = shr(acf[i], sh[1]); L_temp0 = L_mac(L_temp0, temp1, temp2); } if(Overflow != 0) { sh[(int)ind] = add(sh[(int)ind], 1); ind = sub(1, ind); } else flag = 1; } while (flag == 0); temp1 = mult_r(alpha, FracThresh); L_temp1 = L_add(L_deposit_l(temp1), L_deposit_l(alpha)); temp1 = add(sh_RCoeff, 9); /* 9 = Lpc_justif. * 2 - 16 + 1 */ temp2 = add(sh[0], sh[1]); temp1 = sub(temp1, temp2); L_temp1 = L_shl(L_temp1, temp1); L_temp0 = L_sub(L_temp0, L_temp1); if(L_temp0 > 0L) diff = 1; else diff = 0; return(diff); }
void Lsp_stability( Word16 buf[] /* (i/o) Q13 : quantized LSP parameters */ ) { Word16 j; Word16 tmp; Word32 L_diff; Word32 L_acc, L_accb; for(j=0; j<M-1; j++) { L_acc = L_deposit_l( buf[j+1] ); L_accb = L_deposit_l( buf[j] ); L_diff = L_sub( L_acc, L_accb ); if( L_diff < 0L ) { /* exchange buf[j]<->buf[j+1] */ tmp = buf[j+1]; buf[j+1] = buf[j]; buf[j] = tmp; } } if( sub(buf[0], L_LIMIT) <0 ) { buf[0] = L_LIMIT; printf("lsp_stability warning Low \n"); } for(j=0; j<M-1; j++) { L_acc = L_deposit_l( buf[j+1] ); L_accb = L_deposit_l( buf[j] ); L_diff = L_sub( L_acc, L_accb ); if( L_sub(L_diff, GAP3)<0L ) { buf[j+1] = add( buf[j], GAP3 ); } } if( sub(buf[M-1],M_LIMIT)>0 ) { buf[M-1] = M_LIMIT; printf("lsp_stability warning High \n"); } return; }
void step_up ( Word16 np, Word16 vpar[], Word16 aav1[] ) { Word32 L_coef[9], L_work[9]; Word16 temp; Word16 i, m; /*** Initialization of the step-up recursion ***/ L_coef[0] = 0x20000000L; L_coef[1] = L_shl (L_deposit_l (vpar[0]), 14); /*** Loop on the LPC analysis order: ***/ for (m = 2; m <= np; m++) { for (i = 1; i < m; i++) { temp = extract_h (L_coef[m - i]); L_work[i] = L_mac (L_coef[i], vpar[m - 1], temp); } for (i = 1; i < m; i++) { L_coef[i] = L_work[i]; } L_coef[m] = L_shl (L_deposit_l (vpar[m - 1]), 14); } /*** Keep the aav1[0..np] in 15 bits ***/ for (i = 0; i <= np; i++) { aav1[i] = extract_h (L_shr (L_coef[i], 3)); } return; }
Word32 quant_3p_3N1( /* (o) return (3*N)+1 bits */ Word16 pos1, /* (i) position of the pulse 1 */ Word16 pos2, /* (i) position of the pulse 2 */ Word16 pos3, /* (i) position of the pulse 3 */ Word16 N) /* (i) number of bits for position */ { Word16 nb_pos; Word32 index; nb_pos =(1 <<(N - 1)); /* nb_pos = (1<<(N-1)); */ /*-------------------------------------------------------* * Quantization of 3 pulses with 3*N+1 bits: * // 3脉冲3×n + 1比特量化 *-------------------------------------------------------*/ if (((pos1 ^ pos2) & nb_pos) == 0) { index = quant_2p_2N1(pos1, pos2, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos2, (N-1)); */ /* index += (pos1 & nb_pos) << N; */ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N)); /* index += quant_1p_N1(pos3, N) << (2*N); */ index = vo_L_add(index, (quant_1p_N1(pos3, N)<<(N << 1))); } else if (((pos1 ^ pos3) & nb_pos) == 0) { index = quant_2p_2N1(pos1, pos3, sub(N, 1)); /* index = quant_2p_2N1(pos1, pos3, (N-1)); */ index = vo_L_add(index, (L_deposit_l((Word16) (pos1 & nb_pos)) << N)); /* index += (pos1 & nb_pos) << N; */ index = vo_L_add(index, (quant_1p_N1(pos2, N) << (N << 1))); /* index += quant_1p_N1(pos2, N) << * (2*N); */ } else { index = quant_2p_2N1(pos2, pos3, (N - 1)); /* index = quant_2p_2N1(pos2, pos3, (N-1)); */ /* index += (pos2 & nb_pos) << N; */ index = vo_L_add(index, (L_deposit_l((Word16) (pos2 & nb_pos)) << N)); /* index += quant_1p_N1(pos1, N) << (2*N); */ index = vo_L_add(index, (quant_1p_N1(pos1, N) << (N << 1))); } return (index); }
/* ******************************************************************************** * PRIVATE PROGRAM CODE ******************************************************************************** */ void MR475_quant_store_results( gc_predState *pred_st, /* i/o: gain predictor state struct */ const Word16 *p, /* i : pointer to selected quantizer table entry */ Word16 gcode0, /* i : predicted CB gain, Q(14 - exp_gcode0) */ Word16 exp_gcode0, /* i : exponent of predicted CB gain, Q0 */ Word16 *gain_pit, /* o : Pitch gain, Q14 */ Word16 *gain_cod /* o : Code gain, Q1 */ ) { Word16 g_code, exp, frac, tmp; Word32 L_tmp; Word16 qua_ener_MR122; /* o : quantized energy error, MR122 version Q10 */ Word16 qua_ener; /* o : quantized energy error, Q10 */ /* Read the quantized gains */ *gain_pit = *p++; g_code = *p++; /*------------------------------------------------------------------* * calculate final fixed codebook gain: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * gc = gc0 * g * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0); L_tmp = L_shr(L_tmp, sub(10, exp_gcode0)); *gain_cod = extract_h(L_tmp); /*------------------------------------------------------------------* * calculate predictor update values and update gain predictor: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * qua_ener = log2(g) * * qua_ener_MR122 = 20*log10(g) * *------------------------------------------------------------------*/ Log2 (L_deposit_l (g_code), &exp, &frac); /* Log2(x Q12) = log2(x) + 12 */ exp = sub(exp, 12); tmp = shr_r (frac, 5); qua_ener_MR122 = add (tmp, shl (exp, 10)); L_tmp = Mpy_32_16(exp, frac, 24660); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */ gc_pred_update(pred_st, qua_ener_MR122, qua_ener); }
/*---------------------------------------------------------------------------- * filt_mu - tilt filtering with : (1 + mu z-1) * (1/1-|mu|) * computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1]) *---------------------------------------------------------------------------- */ static void filt_mu( Word16 *sig_in, /* input : input signal (beginning at sample -1) */ Word16 *sig_out, /* output: output signal */ Word16 parcor0 /* input : parcor0 (mu = parcor0 * gamma3) */ ) { int n; Word16 mu, mu2, ga, temp; Word32 L_acc, L_temp, L_fact; Word16 fact, sh_fact1; Word16 *ptrs; if(parcor0 > 0) { mu = mult_r(parcor0, GAMMA3_PLUS); /* GAMMA3_PLUS < 0.5 */ sh_fact1 = 15; /* sh_fact + 1 */ fact = (Word16)0x4000; /* 2**sh_fact */ L_fact = (Word32)0x00004000L; } else { mu = mult_r(parcor0, GAMMA3_MINUS); /* GAMMA3_MINUS < 0.9375 */ sh_fact1 = 12; /* sh_fact + 1 */ fact = (Word16)0x0800; /* 2**sh_fact */ L_fact = (Word32)0x00000800L; } temp = sub(1, abs_s(mu)); mu2 = add(32767, temp); /* 2**15 (1 - |mu|) */ ga = div_s(fact, mu2); /* 2**sh_fact / (1 - |mu|) */ ptrs = sig_in; /* points on sig_in(-1) */ mu = shr(mu, 1); /* to avoid overflows */ for(n=0; n<L_SUBFR; n++) { temp = *ptrs++; L_temp = L_deposit_l(*ptrs); L_acc = L_shl(L_temp, 15); /* sig_in(n) * 2**15 */ L_temp = L_mac(L_acc, mu, temp); L_temp = L_add(L_temp, 0x00004000L); temp = extract_l(L_shr(L_temp,15)); /* ga x temp x 2 with rounding */ L_temp = L_add(L_mult(temp, ga),L_fact); L_temp = L_shr(L_temp, sh_fact1); /* mult. temp x ga */ sig_out[n] = sature(L_temp); } return; }
static Word16 Gauss(Word16 *seed) { /**** Xi = uniform v.a. in [-32768, 32767] ****/ /**** Z = SUM(i=1->12) Xi / 2 x 32768 is N(0,1) ****/ /**** output : Z x 512 < 2^12 ****/ Word16 i; Word16 temp; Word32 L_acc; L_acc = 0L; for(i=0; i<12; i++) { L_acc = L_add(L_acc, L_deposit_l(Random(seed))); } L_acc = L_shr(L_acc, 7); temp = extract_l(L_acc); return(temp); }
static int16_t Gauss(int16_t *seed) { /**** Xi = uniform v.a. in [-32768, 32767] ****/ /**** Z = SUM(i=1->12) Xi / 2 x 32768 is N(0,1) ****/ /**** output : Z x 512 < 2^12 ****/ int16_t i; int16_t temp; int32_t L_acc; L_acc = 0L; for (i = 0; i < 12; i++) { L_acc = WebRtcSpl_AddSatW32(L_acc, L_deposit_l(WebRtcG729fix_Random(seed))); } L_acc = L_shr(L_acc, 7); temp = extract_l(L_acc); return(temp); }
/*---------------------------------------------------------------------------* * Function Gain_update_erasure * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * update table of past quantized energies (frame erasure) * *---------------------------------------------------------------------------* * av_pred_en = 0.0; * * for (i = 0; i < 4; i++) * * av_pred_en += past_qua_en[i]; * * av_pred_en = av_pred_en*0.25 - 4.0; * * if (av_pred_en < -14.0) av_pred_en = -14.0; * *---------------------------------------------------------------------------*/ void Gain_update_erasure( Word16 past_qua_en[] /* (i) Q10 :Past quantized energies */ ) { Word16 i, av_pred_en; Word32 L_tmp; L_tmp = 0; /* Q10 */ for(i=0; i<4; i++) L_tmp = L_add( L_tmp, L_deposit_l( past_qua_en[i] ) ); av_pred_en = extract_l( L_shr( L_tmp, 2 ) ); av_pred_en = sub( av_pred_en, 4096 ); /* Q10 */ if( sub(av_pred_en, -14336) < 0 ){ av_pred_en = -14336; /* 14336:14[Q10] */ } for(i=3; i>0; i--){ past_qua_en[i] = past_qua_en[i-1]; } past_qua_en[0] = av_pred_en; }
/*---------------------------------------------------------------------------- * calc_st_filt - computes impulse response of A(gamma2) / A(gamma1) * controls gain : computation of energy impulse response as * SUMn (abs (h[n])) and computes parcor0 *---------------------------------------------------------------------------- */ static void calc_st_filte( Word16 *apond2, /* input : coefficients of numerator */ Word16 *apond1, /* input : coefficients of denominator */ Word16 *parcor0, /* output: 1st parcor calcul. on composed filter */ Word16 *sig_ltp_ptr, /* in/out: input of 1/A(gamma1) : scaled by 1/g0 */ Word16 long_h_st, /* input : impulse response length */ Word16 m_pst /* input : LPC order */ ) { Word16 h[LONG_H_ST_E]; Word32 L_temp, L_g0; Word16 g0, temp; Word16 i; /* compute i.r. of composed filter apond2 / apond1 */ Syn_filte(m_pst, apond1, apond2, h, long_h_st, mem_zero, 0); /* compute 1st parcor */ calc_rc0_he(h, parcor0, long_h_st); /* compute g0 */ L_g0 = 0L; for(i=0; i<long_h_st; i++) { L_temp = L_deposit_l(abs_s(h[i])); L_g0 = L_add(L_g0, L_temp); } g0 = extract_h(L_shl(L_g0, 14)); /* Scale signal input of 1/A(gamma1) */ if(sub(g0, 1024)>0) { temp = div_s(1024, g0); /* temp = 2**15 / gain0 */ for(i=0; i<L_SUBFR; i++) { sig_ltp_ptr[i] = mult_r(sig_ltp_ptr[i], temp); } } return; }
static void Calc_sum_acf(Word16 *acf, Word16 *sh_acf, Word16 *sum, Word16 *sh_sum, Word16 nb) { Word16 *ptr1; Word32 L_temp, L_tab[MP1]; Word16 sh0, temp; Word16 i, j; /* Compute sum = sum of nb acfs */ /* Find sh_acf minimum */ sh0 = sh_acf[0]; for(i=1; i<nb; i++) { if(sub(sh_acf[i], sh0) < 0) sh0 = sh_acf[i]; } sh0 = add(sh0, 14); /* 2 bits of margin */ for(j=0; j<MP1; j++) { L_tab[j] = 0L; } ptr1 = acf; for(i=0; i<nb; i++) { temp = sub(sh0, sh_acf[i]); for(j=0; j<MP1; j++) { L_temp = L_deposit_l(*ptr1++); L_temp = L_shl(L_temp, temp); /* shift right if temp<0 */ L_tab[j] = L_add(L_tab[j], L_temp); } } temp = norm_l(L_tab[0]); for(i=0; i<=M; i++) { sum[i] = extract_h(L_shl(L_tab[i], temp)); } temp = sub(temp, 16); *sh_sum = add(sh0, temp); return; }
/*---------------------------------------------------------------------------* * Function Dec_gain * * ~~~~~~~~~~~~~~~~~~ * * Decode the pitch and codebook gains * * * *---------------------------------------------------------------------------* * input arguments: * * * * index :Quantization index * * code[] :Innovative code vector * * L_subfr :Subframe size * * bfi :Bad frame indicator * * * * output arguments: * * * * gain_pit :Quantized pitch gain * * gain_cod :Quantized codebook gain * * * *---------------------------------------------------------------------------*/ void Dec_gain( Word16 index, /* (i) :Index of quantization. */ Word16 code[], /* (i) Q13 :Innovative vector. */ Word16 L_subfr, /* (i) :Subframe length. */ Word16 bfi, /* (i) :Bad frame indicator */ Word16 *gain_pit, /* (o) Q14 :Pitch gain. */ Word16 *gain_cod /* (o) Q1 :Code gain. */ ) { Word16 index1, index2, tmp; Word16 gcode0, exp_gcode0; Word32 L_gbk12, L_acc, L_accb; void Gain_predict( Word16 past_qua_en[], Word16 code[], Word16 L_subfr, Word16 *gcode0, Word16 *exp_gcode0 ); void Gain_update( Word16 past_qua_en[], Word32 L_gbk12 ); void Gain_update_erasure( Word16 past_qua_en[] ); /* Gain predictor, Past quantized energies = -14.0 in Q10 */ static Word16 past_qua_en[4] = { -14336, -14336, -14336, -14336 }; /*-------------- Case of erasure. ---------------*/ if(bfi != 0){ *gain_pit = mult( *gain_pit, 29491 ); /* *0.9 in Q15 */ if (sub( *gain_pit, 29491) > 0) *gain_pit = 29491; *gain_cod = mult( *gain_cod, 32111 ); /* *0.98 in Q15 */ /*----------------------------------------------* * update table of past quantized energies * * (frame erasure) * *----------------------------------------------*/ Gain_update_erasure(past_qua_en); return; } /*-------------- Decode pitch gain ---------------*/ index1 = imap1[ shr(index,NCODE2_B) ] ; index2 = imap2[ index & (NCODE2-1) ] ; *gain_pit = add( gbk1[index1][0], gbk2[index2][0] ); /*-------------- Decode codebook gain ---------------*/ /*---------------------------------------------------* *- energy due to innovation -* *- predicted energy -* *- predicted codebook gain => gcode0[exp_gcode0] -* *---------------------------------------------------*/ Gain_predict( past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 ); /*-----------------------------------------------------------------* * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * *-----------------------------------------------------------------*/ L_acc = L_deposit_l( gbk1[index1][1] ); L_accb = L_deposit_l( gbk2[index2][1] ); L_gbk12 = L_add( L_acc, L_accb ); /* Q13 */ tmp = extract_l( L_shr( L_gbk12,1 ) ); /* Q12 */ L_acc = L_mult(tmp, gcode0); /* Q[exp_gcode0+12+1] */ L_acc = L_shl(L_acc, add( negate(exp_gcode0),(-12-1+1+16) )); *gain_cod = extract_h( L_acc ); /* Q1 */ /*----------------------------------------------* * update table of past quantized energies * *----------------------------------------------*/ Gain_update( past_qua_en, L_gbk12 ); return; }
void agc( Word16 *sig_in, /* (i) : postfilter input signal */ Word16 *sig_out, /* (i/o) : postfilter output signal */ Word16 l_trm /* (i) : subframe size */ ) { #if 0 static Word16 past_gain=4096; /* past_gain = 1.0 (Q12) */ #endif Word16 i, exp; Word16 gain_in, gain_out, g0, gain; /* Q12 */ Word32 s; Word16 signal[L_SUBFR]; /* calculate gain_out with exponent */ for(i=0; i<l_trm; i++) signal[i] = shr(sig_out[i], 2); s = 0; for(i=0; i<l_trm; i++) s = L_mac(s, signal[i], signal[i]); if (s == 0) { pg729dec->ppost_filt->past_gain = 0; return; } exp = sub(norm_l(s), 1); if(exp>0) gain_out = round(L_shl(s, exp)); else gain_out = round(L_shr(s, abs_s(exp))); /* calculate gain_in with exponent */ for(i=0; i<l_trm; i++) signal[i] = shr(sig_in[i], 2); s = 0; for(i=0; i<l_trm; i++) s = L_mac(s, signal[i], signal[i]); if (s == 0) { g0 = 0; } else { i = norm_l(s); if(i>=0) gain_in = round(L_shl(s, i)); else gain_in = round(L_shr(s, abs_s(i))); exp = sub(exp, i); /*---------------------------------------------------* * g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out); * *---------------------------------------------------*/ s = L_deposit_l(div_s(gain_out,gain_in)); /* Q15 */ s = L_shl(s, 7); /* s(Q22) = gain_out / gain_in */ if(exp>0) s = L_shr(s, exp); /* Q22, add exponent */ else s = L_shl(s, abs_s(exp)); /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */ s = Inv_sqrt(s); /* Q19 */ i = round(L_shl(s,9)); /* Q12 */ /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */ g0 = mult(i, AGC_FAC1); /* Q12 */ } /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */ /* sig_out(n) = gain(n) sig_out(n) */ gain = pg729dec->ppost_filt->past_gain; for(i=0; i<l_trm; i++) { gain = mult(gain, AGC_FAC); gain = add(gain, g0); sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], gain), 3)); } pg729dec->ppost_filt->past_gain = gain; return; }
/* ** ** Function: Qua_SidGain() ** ** Description: Quantization of Sid gain ** Pseudo-log quantizer in 3 segments ** 1st segment : length = 16, resolution = 2 ** 2nd segment : length = 16, resolution = 4 ** 3rd segment : length = 32, resolution = 8 ** quantizes a sum of energies ** ** Links to text: ** ** Arguments: ** ** Word16 *Ener table of the energies ** Word16 *shEner corresponding scaling factors ** Word16 nq if nq >= 1 : quantization of nq energies ** for SID gain calculation in function Cod_Cng() ** if nq = 0 : in function Comp_Info(), ** quantization of saved estimated excitation energy ** ** Outputs: None ** ** ** Return value: index of quantized energy ** */ Word16 Qua_SidGain(Word16 *Ener, Word16 *shEner, Word16 nq) { Word16 temp, iseg, iseg_p1; Word16 j, j2, k, exp; Word32 L_x, L_y; Word16 sh1; Word32 L_acc; int i; if(nq == 0) { /* Quantize energy saved for frame erasure case */ /* L_x = 2 x average_ener */ temp = shl(*shEner, 1); temp = sub(16, temp); L_acc = L_deposit_l(*Ener); L_acc = L_shl(L_acc, temp); /* may overflow, and >> if temp < 0 */ L_x = L_mls(L_acc, fact[0]); } else { /* * Compute weighted average of energies * Ener[i] = enerR[i] x 2**(shEner[i]-14) * L_x = k[nq] x SUM(i=0->nq-1) enerR[i] * with k[nq] = 2 x fact_mul x fact_mul / nq x Frame */ sh1 = shEner[0]; for(i=1; i<nq; i++) { if(shEner[i] < sh1) sh1 = shEner[i]; } for(i=0, L_x=0L; i<nq; i++) { temp = sub(shEner[i], sh1); temp = shr(Ener[i], temp); temp = mult_r(fact[nq], temp); L_x = L_add(L_x, L_deposit_l(temp)); } temp = sub(15, sh1); L_x = L_shl(L_x, temp); } /* Quantize L_x */ if(L_x >= L_bseg[2]) return(63); /* Compute segment number iseg */ if(L_x >= L_bseg[1]) { iseg = 2; exp = 4; } else { exp = 3; if(L_x >= L_bseg[0]) iseg = 1; else iseg = 0; } iseg_p1 = add(iseg,1); j = shl(1, exp); k = shr(j,1); /* Binary search in segment iseg */ for(i=0; i<exp; i++) { temp = add(base[iseg], shl(j, iseg_p1)); // L_y = L_mult(temp, temp); L_MULT(temp, temp, L_y); if(L_x >= L_y) j = add(j, k); else j = sub(j, k); k = shr(k, 1); } temp = add(base[iseg], shl(j, iseg_p1)); L_y = L_mult(temp, temp); L_y = L_sub(L_y, L_x); if(L_y <= 0L) { j2 = add(j, 1); temp = add(base[iseg], shl(j2, iseg_p1)); L_acc = L_mult(temp, temp); L_acc = L_sub(L_x, L_acc); if(L_y > L_acc) temp = add(shl(iseg,4), j); else temp = add(shl(iseg,4), j2); } else { j2 = sub(j, 1); temp = add(base[iseg], shl(j2, iseg_p1)); L_acc = L_mult(temp, temp); L_acc = L_sub(L_x, L_acc); if(L_y < L_acc) temp = add(shl(iseg,4), j); else temp = add(shl(iseg,4), j2); } return(temp); }
/*************************************************************************** Function: vector_huffman Syntax: Word16 vector_huffman(Word16 category, Word16 power_index, Word16 *raw_mlt_ptr, UWord32 *word_ptr) inputs: Word16 category Word16 power_index Word16 *raw_mlt_ptr outputs: number_of_region_bits *word_ptr Description: Huffman encoding for each region based on category and power_index WMOPS: 7kHz | 24kbit | 32kbit -------|--------------|---------------- AVG | 0.03 | 0.03 -------|--------------|---------------- MAX | 0.04 | 0.04 -------|--------------|---------------- 14kHz | 24kbit | 32kbit | 48kbit -------|--------------|----------------|---------------- AVG | 0.03 | 0.03 | 0.03 -------|--------------|----------------|---------------- MAX | 0.04 | 0.04 | 0.04 -------|--------------|----------------|---------------- ***************************************************************************/ Word16 vector_huffman(Word16 category, Word16 power_index, Word16 *raw_mlt_ptr, UWord32 *word_ptr) { Word16 inv_of_step_size_times_std_dev; Word16 j,n; Word16 k; Word16 number_of_region_bits; Word16 number_of_non_zero; Word16 vec_dim; Word16 num_vecs; Word16 kmax, kmax_plus_one; Word16 index,signs_index; Word16 *bitcount_table_ptr; UWord16 *code_table_ptr; Word32 code_bits; Word16 number_of_code_bits; UWord32 current_word; Word16 current_word_bits_free; Word32 acca; Word32 accb; Word16 temp; Word16 mytemp; /* new variable in Release 1.2 */ Word16 myacca; /* new variable in Release 1.2 */ /* initialize variables */ vec_dim = vector_dimension[category]; move16(); num_vecs = number_of_vectors[category]; move16(); kmax = max_bin[category]; move16(); kmax_plus_one = add(kmax,1); move16(); current_word = 0L; move16(); current_word_bits_free = 32; move16(); number_of_region_bits = 0; move16(); /* set up table pointers */ bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category]; code_table_ptr = (UWord16 *) table_of_code_tables[category]; /* compute inverse of step size * standard deviation */ acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]); acca = L_shr_nocheck(acca,1); acca = L_add(acca,4096); acca = L_shr_nocheck(acca,13); /* * The next two lines are new to Release 1.2 */ mytemp = (Word16)(acca & 0x3); acca = L_shr_nocheck(acca,2); inv_of_step_size_times_std_dev = extract_l(acca); for (n=0; n<num_vecs; n++) { index = 0; move16(); signs_index = 0; move16(); number_of_non_zero = 0; move16(); for (j=0; j<vec_dim; j++) { k = abs_s(*raw_mlt_ptr); acca = L_mult(k,inv_of_step_size_times_std_dev); acca = L_shr_nocheck(acca,1); /* * The next four lines are new to Release 1.2 */ myacca = (Word16)L_mult(k,mytemp); myacca = (Word16)L_shr_nocheck(myacca,1); myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]); myacca = (Word16)L_shr_nocheck(myacca,2); acca = L_add(acca,int_dead_zone[category]); /* * The next two lines are new to Release 1.2 */ acca = L_add(acca,myacca); acca = L_shr_nocheck(acca,13); k = extract_l(acca); test(); if (k != 0) { number_of_non_zero = add(number_of_non_zero,1); signs_index = shl_nocheck(signs_index,1); test(); if (*raw_mlt_ptr > 0) { signs_index = add(signs_index,1); } temp = sub(k,kmax); test(); if (temp > 0) { k = kmax; move16(); } } acca = L_shr_nocheck(L_mult(index,(kmax_plus_one)),1); index = extract_l(acca); index = add(index,k); raw_mlt_ptr++; } code_bits = *(code_table_ptr+index); number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero); number_of_region_bits = add(number_of_region_bits,number_of_code_bits); acca = code_bits << number_of_non_zero; accb = L_deposit_l(signs_index); acca = L_add(acca,accb); code_bits = acca; move32(); /* msb of codebits is transmitted first. */ j = sub(current_word_bits_free,number_of_code_bits); test(); if (j >= 0) { test(); acca = code_bits << j; current_word = L_add(current_word,acca); current_word_bits_free = j; move16(); } else { j = negate(j); acca = L_shr_nocheck(code_bits,j); current_word = L_add(current_word,acca); *word_ptr++ = current_word; move16(); current_word_bits_free = sub(32,j); test(); current_word = code_bits << current_word_bits_free; } } *word_ptr++ = current_word; move16(); return (number_of_region_bits); }
/************************************************************************* * * FUNCTION: Dec_gain() * * PURPOSE: Decode the pitch and codebook gains * ************************************************************************/ void Dec_gain( gc_predState *pred_state, /* i/o: MA predictor state */ enum Mode mode, /* i : AMR mode */ Word16 index, /* i : index of quantization. */ Word16 code[], /* i : Innovative vector. */ Word16 evenSubfr, /* i : Flag for even subframes */ Word16 * gain_pit, /* o : Pitch gain. */ Word16 * gain_cod /* o : Code gain. */ ) { const Word16 *p; Word16 frac, gcode0, exp, qua_ener, qua_ener_MR122; Word16 g_code; Word32 L_tmp; /* Read the quantized gains (table depends on mode) */ index = shl (index, 2); test(); test(); test(); if ( sub (mode, MR102) == 0 || sub (mode, MR74) == 0 || sub (mode, MR67) == 0) { p = &table_gain_highrates[index]; move16 (); *gain_pit = *p++; move16 (); g_code = *p++; move16 (); qua_ener_MR122 = *p++; move16 (); qua_ener = *p; move16 (); } else { test(); if (sub (mode, MR475) == 0) { index = add (index, shl(sub(1, evenSubfr), 1)); p = &table_gain_MR475[index]; move16 (); *gain_pit = *p++; move16 (); g_code = *p++; move16 (); /*---------------------------------------------------------* * calculate predictor update values (not stored in 4.75 * * quantizer table to save space): * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * qua_ener = log2(g) * * qua_ener_MR122 = 20*log10(g) * *---------------------------------------------------------*/ /* Log2(x Q12) = log2(x) + 12 */ Log2 (L_deposit_l (g_code), &exp, &frac); exp = sub(exp, 12); qua_ener_MR122 = add (shr_r (frac, 5), shl (exp, 10)); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ L_tmp = Mpy_32_16(exp, frac, 24660); qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */ } else { p = &table_gain_lowrates[index]; move16 (); *gain_pit = *p++; move16 (); g_code = *p++; move16 (); qua_ener_MR122 = *p++; move16 (); qua_ener = *p; move16 (); } } /*-------------------------------------------------------------------* * predict codebook gain * * ~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow2(int(d)+frac(d)) * * = 2^exp + 2^frac * * * * gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp) * *-------------------------------------------------------------------*/ gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL); gcode0 = extract_l(Pow2(14, frac)); /*------------------------------------------------------------------* * read quantized gains, update table of past quantized energies * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant * * = Log2(g_fac) * * = qua_ener * * constant = 20*Log10(2) * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0); L_tmp = L_shr(L_tmp, sub(10, exp)); *gain_cod = extract_h(L_tmp); /* update table of past quantized energies */ gc_pred_update(pred_state, qua_ener_MR122, qua_ener); return; }
Word32 quant_4p_4N( /* (o) return 4*N bits */ Word16 pos[], /* (i) position of the pulse 1..4 */ Word16 N) /* (i) number of bits for position */ { Word16 nb_pos, mask, n_1, tmp; Word16 posA[4], posB[4]; Word32 i, j, k, index; n_1 = (Word16) (N - 1); nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */ mask = vo_sub((1 << N), 1); /* mask = ((1<<N)-1); */ i = 0; j = 0; for (k = 0; k < 4; k++) { if ((pos[k] & nb_pos) == 0) { posA[i++] = pos[k]; } else { posB[j++] = pos[k]; } } switch (i) { case 0: tmp = vo_sub((N << 2), 3); /* index = 1 << ((4*N)-3); */ index = (1L << tmp); /* index += quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1); */ index = vo_L_add(index, quant_4p_4N1(posB[0], posB[1], posB[2], posB[3], n_1)); break; case 1: /* index = quant_1p_N1(posA[0], n_1) << ((3*n_1)+1); */ tmp = add1((Word16)((vo_L_mult(3, n_1) >> 1)), 1); index = L_shl(quant_1p_N1(posA[0], n_1), tmp); /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */ index = vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1)); break; case 2: tmp = ((n_1 << 1) + 1); /* index = quant_2p_2N1(posA[0], posA[1], n_1) << ((2*n_1)+1); */ index = L_shl(quant_2p_2N1(posA[0], posA[1], n_1), tmp); /* index += quant_2p_2N1(posB[0], posB[1], n_1); */ index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], n_1)); break; case 3: /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << N; */ index = L_shl(quant_3p_3N1(posA[0], posA[1], posA[2], n_1), N); index = vo_L_add(index, quant_1p_N1(posB[0], n_1)); /* index += quant_1p_N1(posB[0], n_1); */ break; case 4: index = quant_4p_4N1(posA[0], posA[1], posA[2], posA[3], n_1); break; default: index = 0; fprintf(stderr, "Error in function quant_4p_4N\n"); } tmp = ((N << 2) - 2); /* index += (i & 3) << ((4*N)-2); */ index = vo_L_add(index, L_shl((L_deposit_l(i) & (3L)), tmp)); return (index); }
void GetExc800bps( /* 1 */ short *output, /* 2 */ short *best, /* 3 */ short scale, /* 4 */ short *input, /* 5 */ short length, /* 6 */ short flag, /* 7 */ short n) { short k, j; short D; long tmp; long ltmp; short stmp; short *ptr; long sum, lscale; short ssum, sscale; static short Seed = 1234; static short Sum[NoOfSubFrames]; short shft_scale; short shft_sum; short stemp1; if (!flag) Seed = 1234; /* * sum is an integer value, not a fractional value. */ /* Get energy of next sub frame */ for (k = 0, sum = 0; k < length; k++) { sum = L_add(sum, L_deposit_l(abs_s(input[k]))); } sum = L_shl(sum, 1); /* correct for scaling */ if (sum < SubFrameSize) { sum = fnLog10(L_deposit_h(scale)); sum = L_negate(L_add(L_shl(sum, 3), 484942745)); /* add (log8)/4 = 484842745 (VALUE ADJUSTED TO BETTER MATCH FLOAT MODEL) */ } else { lscale = L_mult(SubFrameSize, scale); shft_scale = norm_l(lscale); sscale = round(L_shl(lscale, shft_scale)); shft_sum = norm_l(sum) - 1; ssum = round(L_shl(sum, shft_sum)); /* * The following divide/L_shl produced sum scaled down by 64. * sum can have a max value of 40.xx in the sample data. */ /* sum = L_shl(L_divide(sum, lscale), (shft_scale + 7 - shft_sum)); */ sum = L_deposit_h(shl(divide_s(ssum, sscale), (shft_scale - shft_sum))); /* sum = fnLog10(sum); */ sum = L_add(fnLog10(sum), 141412467); /* add log (2^7) scaled down by 32 */ sum = L_add(L_shl(sum, 3), 969485490); /* add (log8)/2 = 969685490 (VALUE ADJUSTED TO BETTER MATCH FLOAT MODEL) */ } /* * Sum scaled down by 4. */ Sum[n] = round(sum); /* Quantize if last frame */ if (n == NoOfSubFrames - 1) { /* Quantize to 8 bits */ for (k = 0, sum = 2147483647, ptr = Logqtbl; k < 256; k++) { for (j = 0, tmp = 0; j < 3; j++) { /* * Sum and Logqtbl both scaled down by 4. * Change Logqtbl to short if Lw not required. */ D = sub(Sum[j], (*ptr++)); tmp = L_mac(tmp, D, D); } if (tmp < sum) { ltmp = sum; sum = tmp; *best = k; } } for (j = 0; j < 3; j++) { Sum[j] = Powqtbl[*best * 3 + j]; } /* Get excitation */ j = FrameSize - ACBMemSize; for (k = 0; k < FrameSize - 1; k++) { if (k >= j) { stmp = e_ran_g(&Seed); stemp1 = k / (length - 1); output[k - j] = round(L_shr(L_mult(stmp, Sum[stemp1]), 5)); } } stmp = e_ran_g(&Seed); output[k - j] = round(L_shr(L_mult(stmp, Sum[2]), 5)); /* last excitation */ } }
/* ************************************************************************** * * Function : agc * Purpose : Scales the postfilter output on a subframe basis * ************************************************************************** */ int agc ( agcState *st, /* i/o : agc state */ Word16 *sig_in, /* i : postfilter input signal (l_trm) */ Word16 *sig_out, /* i/o : postfilter output signal (l_trm) */ Word16 agc_fac, /* i : AGC factor */ Word16 l_trm /* i : subframe size */ ) { Word16 i, exp; Word16 gain_in, gain_out, g0, gain; Word32 s; /* calculate gain_out with exponent */ s = energy_new(sig_out, l_trm); /* function result */ if (s == 0) { st->past_gain = 0; return 0; } exp = sub (norm_l (s), 1); gain_out = round (L_shl (s, exp)); /* calculate gain_in with exponent */ s = energy_new(sig_in, l_trm); /* function result */ if (s == 0) { g0 = 0; } else { i = norm_l (s); gain_in = round (L_shl (s, i)); exp = sub (exp, i); /*---------------------------------------------------* * g0 = (1-agc_fac) * sqrt(gain_in/gain_out); * *---------------------------------------------------*/ s = L_deposit_l (div_s (gain_out, gain_in)); s = L_shl (s, 7); /* s = gain_out / gain_in */ s = L_shr (s, exp); /* add exponent */ s = Inv_sqrt (s); /* function result */ i = round (L_shl (s, 9)); /* g0 = i * (1-agc_fac) */ g0 = mult (i, sub (32767, agc_fac)); } /* compute gain[n] = agc_fac * gain[n-1] + (1-agc_fac) * sqrt(gain_in/gain_out) */ /* sig_out[n] = gain[n] * sig_out[n] */ gain = st->past_gain; for (i = 0; i < l_trm; i++) { gain = mult (gain, agc_fac); gain = add (gain, g0); sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3)); } st->past_gain = gain; return 0; }
/*************************************************************************** Function: bits_to_words Syntax: bits_to_words(UWord32 *region_mlt_bits, Word16 *region_mlt_bit_counts, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *out_words, Word16 categorization_control, Word16 number_of_regions, Word16 num_categorization_control_bits, Word16 number_of_bits_per_frame) Description: Stuffs the bits into words for output WMOPS: 7kHz | 24kbit | 32kbit -------|--------------|---------------- AVG | 0.09 | 0.12 -------|--------------|---------------- MAX | 0.10 | 0.13 -------|--------------|---------------- 14kHz | 24kbit | 32kbit | 48kbit -------|--------------|----------------|---------------- AVG | 0.12 | 0.15 | 0.19 -------|--------------|----------------|---------------- MAX | 0.14 | 0.17 | 0.21 -------|--------------|----------------|---------------- ***************************************************************************/ void bits_to_words(UWord32 *region_mlt_bits, Word16 *region_mlt_bit_counts, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *out_words, Word16 categorization_control, Word16 number_of_regions, Word16 num_categorization_control_bits, Word16 number_of_bits_per_frame) { Word16 out_word_index = 0; Word16 j; Word16 region; Word16 out_word; Word16 region_bit_count; Word16 current_word_bits_left; UWord16 slice; Word16 out_word_bits_free = 16; UWord32 *in_word_ptr; UWord32 current_word; Word32 acca = 0; Word32 accb; Word16 temp; /* First set up the categorization control bits to look like one more set of region power bits. */ out_word = 0; move16(); drp_num_bits[number_of_regions] = num_categorization_control_bits; move16(); drp_code_bits[number_of_regions] = (UWord16)categorization_control; move16(); /* These code bits are right justified. */ for (region=0; region <= number_of_regions; region++) { current_word_bits_left = drp_num_bits[region]; move16(); current_word = (UWord32)drp_code_bits[region]; move16(); j = sub(current_word_bits_left,out_word_bits_free); test(); if (j >= 0) { temp = extract_l(L_shr_nocheck(current_word,j)); out_word = add(out_word,temp); out_words[out_word_index++] = out_word; move16(); out_word_bits_free = 16; move16(); out_word_bits_free = sub(out_word_bits_free,j); acca = (current_word << out_word_bits_free); out_word = extract_l(acca); } else { j = negate(j); acca = (current_word << j); accb = L_deposit_l(out_word); acca = L_add(accb,acca); out_word = extract_l(acca); out_word_bits_free = sub(out_word_bits_free,current_word_bits_left); } } /* These code bits are left justified. */ for (region=0;region<number_of_regions; region++) { accb = L_deposit_l(out_word_index); accb = L_shl_nocheck(accb,4); accb = L_sub(accb,number_of_bits_per_frame); test(); if(accb < 0) { temp = shl_nocheck(region,2); in_word_ptr = ®ion_mlt_bits[temp]; region_bit_count = region_mlt_bit_counts[region]; move16(); temp = sub(32,region_bit_count); test(); if(temp > 0) current_word_bits_left = region_bit_count; else current_word_bits_left = 32; current_word = *in_word_ptr++; acca = L_deposit_l(out_word_index); acca = L_shl_nocheck(acca,4); acca = L_sub(acca,number_of_bits_per_frame); /* from while loop */ test(); test(); logic16(); while ((region_bit_count > 0) && (acca < 0)) { /* from while loop */ test(); test(); logic16(); temp = sub(current_word_bits_left,out_word_bits_free); test(); if (temp >= 0) { temp = sub(32,out_word_bits_free); accb = LU_shr(current_word,temp); slice = (UWord16)extract_l(accb); out_word = add(out_word,slice); test(); current_word <<= out_word_bits_free; current_word_bits_left = sub(current_word_bits_left,out_word_bits_free); out_words[out_word_index++] = extract_l(out_word); move16(); out_word = 0; move16(); out_word_bits_free = 16; move16(); } else { temp = sub(32,current_word_bits_left); accb = LU_shr(current_word,temp); slice = (UWord16)extract_l(accb); temp = sub(out_word_bits_free,current_word_bits_left); test(); accb = slice << temp; acca = L_deposit_l(out_word); acca = L_add(acca,accb); out_word = extract_l(acca); out_word_bits_free = sub(out_word_bits_free,current_word_bits_left); current_word_bits_left = 0; move16(); } test(); if (current_word_bits_left == 0) { current_word = *in_word_ptr++; region_bit_count = sub(region_bit_count,32); /* current_word_bits_left = MIN(32,region_bit_count); */ temp = sub(32,region_bit_count); test(); if(temp > 0) current_word_bits_left = region_bit_count; else current_word_bits_left = 32; } acca = L_deposit_l(out_word_index); acca = L_shl_nocheck(acca,4); acca = L_sub(acca,number_of_bits_per_frame); } accb = L_deposit_l(out_word_index); accb = L_shl_nocheck(accb,4); accb = L_sub(accb,number_of_bits_per_frame); } } /* Fill out with 1's. */ test(); while (acca < 0) { test(); current_word = 0x0000ffff; move32(); temp = sub(16,out_word_bits_free); acca = LU_shr(current_word,temp); slice = (UWord16)extract_l(acca); out_word = add(out_word,slice); out_words[out_word_index++] = out_word; move16(); out_word = 0; move16(); out_word_bits_free = 16; move16(); acca = L_deposit_l(out_word_index); acca = L_shl_nocheck(acca,4); acca = L_sub(acca,number_of_bits_per_frame); } }
//============================================================================= //函数名称:Dec_gain //函数功能:解码的音调和码书增益 //============================================================================= void Dec_gain( gc_predState *pred_state, /* i/o: MA predictor state */ enum Mode mode, /* i : AMR mode */ Word16 index, /* i : index of quantization. */ Word16 code[], /* i : Innovative vector. */ Word16 evenSubfr, /* i : Flag for even subframes */ Word16 * gain_pit, /* o : Pitch gain. */ Word16 * gain_cod, /* o : Code gain. */ Flag * pOverflow ) { const Word16 *p; Word16 frac; Word16 gcode0; Word16 exp; Word16 qua_ener; Word16 qua_ener_MR122; Word16 g_code; Word32 L_tmp; Word16 temp1; Word16 temp2; /* Read the quantized gains (table depends on mode) */ //阅读量化收益(表取决于模式) index = shl(index, 2, pOverflow); if (mode == MR102 || mode == MR74 || mode == MR67) { p = &table_gain_highrates[index]; *gain_pit = *p++; g_code = *p++; qua_ener_MR122 = *p++; qua_ener = *p; } else { if (mode == MR475) { index += (1 ^ evenSubfr) << 1; /* evenSubfr is 0 or 1 */ if (index > (MR475_VQ_SIZE*4 - 2)) { index = (MR475_VQ_SIZE * 4 - 2); /* avoid possible buffer overflow */ } p = &table_gain_MR475[index]; *gain_pit = *p++; g_code = *p++; /*---------------------------------------------------------* * calculate predictor update values (not stored in 4.75 * * quantizer table to save space): * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * qua_ener = log2(g) * * qua_ener_MR122 = 20*log10(g) * *---------------------------------------------------------*/ //计算预测更新值(不存储在4.75量化表,以节省空间) /* Log2(x Q12) = log2(x) + 12 */ temp1 = (Word16) L_deposit_l(g_code); Log2(temp1, &exp, &frac, pOverflow); exp = sub(exp, 12, pOverflow); temp1 = shr_r(frac, 5, pOverflow); temp2 = shl(exp, 10, pOverflow); qua_ener_MR122 = add(temp1, temp2, pOverflow); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow); L_tmp = L_shl(L_tmp, 13, pOverflow); qua_ener = pv_round(L_tmp, pOverflow); /* Q12 * Q0 = Q13 -> Q10 */ } else { p = &table_gain_lowrates[index]; *gain_pit = *p++; g_code = *p++; qua_ener_MR122 = *p++; qua_ener = *p; } } /*-------------------------------------------------------------------* * predict codebook gain * * ~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow2(int(d)+frac(d)) * * = 2^exp + 2^frac * * * * gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp) * *-------------------------------------------------------------------*/ gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL, pOverflow); gcode0 = (Word16) Pow2(14, frac, pOverflow); /*------------------------------------------------------------------* * read quantized gains, update table of past quantized energies * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant * * = Log2(g_fac) * * = qua_ener * * constant = 20*Log10(2) * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0, pOverflow); temp1 = sub(10, exp, pOverflow); L_tmp = L_shr(L_tmp, temp1, pOverflow); *gain_cod = extract_h(L_tmp); /* update table of past quantized energies */ //过去的量化能量表更新 gc_pred_update(pred_state, qua_ener_MR122, qua_ener); return; }
void agc( int16_t *sig_in, /* (i) : postfilter input signal */ int16_t *sig_out, /* (i/o) : postfilter output signal */ int16_t l_trm /* (i) : subframe size */ ) { static int16_t past_gain=4096; /* past_gain = 1.0 (Q12) */ int16_t i, exp; int16_t gain_in, gain_out, g0, gain; /* Q12 */ int32_t s; int16_t signal[L_SUBFR]; /* calculate gain_out with exponent */ for(i=0; i<l_trm; i++) signal[i] = shr(sig_out[i], 2); s = 0; for(i=0; i<l_trm; i++) s = L_mac(s, signal[i], signal[i]); if (s == 0) { past_gain = 0; return; } exp = sub(norm_l(s), 1); gain_out = _round(L_shl(s, exp)); /* calculate gain_in with exponent */ for(i=0; i<l_trm; i++) signal[i] = shr(sig_in[i], 2); s = 0; for(i=0; i<l_trm; i++) s = L_mac(s, signal[i], signal[i]); if (s == 0) { g0 = 0; } else { i = norm_l(s); gain_in = _round(L_shl(s, i)); exp = sub(exp, i); /*---------------------------------------------------* * g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out); * *---------------------------------------------------*/ s = L_deposit_l(div_s(gain_out,gain_in)); /* Q15 */ s = L_shl(s, 7); /* s(Q22) = gain_out / gain_in */ s = L_shr(s, exp); /* Q22, add exponent */ /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */ s = Inv_sqrt(s); /* Q19 */ i = _round(L_shl(s,9)); /* Q12 */ /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */ g0 = mult(i, AGC_FAC1); /* Q12 */ } /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */ /* sig_out(n) = gain(n) sig_out(n) */ gain = past_gain; for(i=0; i<l_trm; i++) { gain = mult(gain, AGC_FAC); gain = add(gain, g0); sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], gain), 3)); } past_gain = gain; return; }
/*---------------------------------------------------------------------------* * Function Gbk_presel * * ~~~~~~~~~~~~~~~~~~~ * * - presearch for gain codebook - * *---------------------------------------------------------------------------*/ static void Gbk_presel( Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */ /* (i) [1] Q2 : unquantized code gain */ Word16 *cand1, /* (o) : index of best 1st stage vector */ Word16 *cand2, /* (o) : index of best 2nd stage vector */ Word16 gcode0 /* (i) Q4 : presearch for gain codebook */ ) { Word16 acc_h; Word16 sft_x,sft_y; Word32 L_acc,L_preg,L_cfbg,L_tmp,L_tmp_x,L_tmp_y; Word32 L_temp; /*--------------------------------------------------------------------------* x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef; *--------------------------------------------------------------------------*/ L_cfbg = L_mult( coef[0][0], best_gain[0] ); /* L_cfbg:Q20 -> !!y */ L_acc = L_shr( L_coef[1][1], 15 ); /* L_acc:Q20 */ L_acc = L_add( L_cfbg , L_acc ); acc_h = extract_h( L_acc ); /* acc_h:Q4 */ L_preg = L_mult( acc_h, gcode0 ); /* L_preg:Q9 */ L_acc = L_shl( L_deposit_l( best_gain[1] ), 7 ); /* L_acc:Q9 */ L_acc = L_sub( L_acc, L_preg ); acc_h = extract_h( L_shl( L_acc,2 ) ); /* L_acc_h:Q[-5] */ L_tmp_x = L_mult( acc_h, INV_COEF ); /* L_tmp_x:Q15 */ /*--------------------------------------------------------------------------* y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0 -coef[0][0]*best_gain[1]) * inv_coef; *--------------------------------------------------------------------------*/ L_acc = L_shr( L_coef[0][1], 10 ); /* L_acc:Q20 */ L_acc = L_sub( L_cfbg, L_acc ); /* !!x -> L_cfbg:Q20 */ acc_h = extract_h( L_acc ); /* acc_h:Q4 */ acc_h = mult( acc_h, gcode0 ); /* acc_h:Q[-7] */ L_tmp = L_mult( acc_h, coef[1][0] ); /* L_tmp:Q10 */ L_preg = L_mult( coef[0][0], best_gain[1] ); /* L_preg:Q13 */ L_acc = L_sub( L_tmp, L_shr(L_preg,3) ); /* L_acc:Q10 */ acc_h = extract_h( L_shl( L_acc,2 ) ); /* acc_h:Q[-4] */ L_tmp_y = L_mult( acc_h, INV_COEF ); /* L_tmp_y:Q16 */ sft_y = (14+4+1)-16; /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */ sft_x = (15+4+1)-15; /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */ if(gcode0>0){ /*-- pre select codebook #1 --*/ *cand1 = 0 ; do{ L_temp = L_sub( L_tmp_y, L_shr(L_mult(thr1[*cand1],gcode0),sft_y)); if(L_temp >0L ){ //(*cand1) =add(*cand1,1); *cand1 += 1; } else break ; //} while(sub((*cand1),(NCODE1-NCAN1))<0) ; } while ((*cand1) < (NCODE1-NCAN1)); /*-- pre select codebook #2 --*/ *cand2 = 0 ; do{ L_temp = L_sub( L_tmp_x , L_shr(L_mult(thr2[*cand2],gcode0),sft_x)); if( L_temp >0L) { //(*cand2) =add(*cand2,1); *cand2 += 1; } else break ; //} while(sub((*cand2),(NCODE2-NCAN2))<0) ; } while((*cand2) < (NCODE2-NCAN2)) ; } else{ /*-- pre select codebook #1 --*/ *cand1 = 0 ; do{ L_temp = L_sub(L_tmp_y ,L_shr(L_mult(thr1[*cand1],gcode0),sft_y)); if( L_temp <0L){ //(*cand1) =add(*cand1,1); *cand1 += 1; } else break ; //} while(sub((*cand1),(NCODE1-NCAN1))) ; } while (*cand1 != (NCODE1-NCAN1)) ; /*-- pre select codebook #2 --*/ *cand2 = 0 ; do{ L_temp =L_sub(L_tmp_x ,L_shr(L_mult(thr2[*cand2],gcode0),sft_x)); if( L_temp <0L){ //(*cand2) =add(*cand2,1); *cand2 += 1; } else break ; //} while(sub( (*cand2),(NCODE2-NCAN2))) ; } while(*cand2 != (NCODE2-NCAN2)) ; } return ; }
/*---------------------------------------------------------------------------* * Function Qua_gain * * ~~~~~~~~~~~~~~~~~~ * * Inputs: * * code[] :Innovative codebook. * * g_coeff[] :Correlations compute for pitch. * * L_subfr :Subframe length. * * * * Outputs: * * gain_pit :Quantized pitch gain. * * gain_cod :Quantized code gain. * * * * Return: * * Index of quantization. * * * *--------------------------------------------------------------------------*/ Word16 Qua_gain( Word16 code[], /* (i) Q13 :Innovative vector. */ Word16 g_coeff[], /* (i) :Correlations <xn y1> -2<y1 y1> */ /* <y2,y2>, -2<xn,y2>, 2<y1,y2> */ Word16 exp_coeff[], /* (i) :Q-Format g_coeff[] */ Word16 L_subfr, /* (i) :Subframe length. */ Word16 *gain_pit, /* (o) Q14 :Pitch gain. */ Word16 *gain_cod, /* (o) Q1 :Code gain. */ Word16 tameflag /* (i) : set to 1 if taming is needed */ ) { Word16 i, j, index1, index2; Word16 cand1, cand2; Word16 exp, gcode0, exp_gcode0, gcode0_org, e_min ; Word16 nume, denom, inv_denom; Word16 exp1,exp2,exp_nume,exp_denom,exp_inv_denom,sft,tmp; Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod; Word16 coeff[5], coeff_lsf[5]; Word16 exp_min[5]; Word32 L_gbk12; Word32 L_tmp, L_dist_min, L_tmp1, L_tmp2, L_acc, L_accb; Word16 best_gain[2]; /* Gain predictor, Past quantized energies = -14.0 in Q10 */ static Word16 past_qua_en[4] = { -14336, -14336, -14336, -14336 }; /*---------------------------------------------------* *- energy due to innovation -* *- predicted energy -* *- predicted codebook gain => gcode0[exp_gcode0] -* *---------------------------------------------------*/ Gain_predict( past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 ); /*-----------------------------------------------------------------* * pre-selection * *-----------------------------------------------------------------*/ /*-----------------------------------------------------------------* * calculate best gain * * * * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * * gbk_presel(best_gain,&cand1,&cand2,gcode0) ; * * * *-----------------------------------------------------------------*/ /*-----------------------------------------------------------------* * tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; * *-----------------------------------------------------------------*/ L_tmp1 = L_mult( g_coeff[0], g_coeff[2] ); exp1 = add( add( exp_coeff[0], exp_coeff[2] ), 1-2 ); L_tmp2 = L_mult( g_coeff[4], g_coeff[4] ); exp2 = add( add( exp_coeff[4], exp_coeff[4] ), 1 ); //if( sub(exp1, exp2)>0 ){ if( exp1 > exp2 ){ L_tmp = L_sub( L_shr( L_tmp1, sub(exp1,exp2) ), L_tmp2 ); exp = exp2; } else{ L_tmp = L_sub( L_tmp1, L_shr( L_tmp2, sub(exp2,exp1) ) ); exp = exp1; } sft = norm_l( L_tmp ); denom = extract_h( L_shl(L_tmp, sft) ); exp_denom = sub( add( exp, sft ), 16 ); inv_denom = div_s(16384,denom); inv_denom = negate( inv_denom ); exp_inv_denom = sub( 14+15, exp_denom ); /*-----------------------------------------------------------------* * best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; * *-----------------------------------------------------------------*/ L_tmp1 = L_mult( g_coeff[2], g_coeff[1] ); exp1 = add( exp_coeff[2], exp_coeff[1] ); L_tmp2 = L_mult( g_coeff[3], g_coeff[4] ); exp2 = add( add( exp_coeff[3], exp_coeff[4] ), 1 ); //if( sub(exp1, exp2)>0 ){ if (exp1 > exp2){ L_tmp = L_sub( L_shr( L_tmp1, add(sub(exp1,exp2),1 )), L_shr( L_tmp2,1 ) ); exp = sub(exp2,1); } else{ L_tmp = L_sub( L_shr( L_tmp1,1 ), L_shr( L_tmp2, add(sub(exp2,exp1),1 )) ); exp = sub(exp1,1); } sft = norm_l( L_tmp ); nume = extract_h( L_shl(L_tmp, sft) ); exp_nume = sub( add( exp, sft ), 16 ); sft = sub( add( exp_nume, exp_inv_denom ), (9+16-1) ); L_acc = L_shr( L_mult( nume,inv_denom ), sft ); best_gain[0] = extract_h( L_acc ); /*-- best_gain[0]:Q9 --*/ if (tameflag == 1){ //if(sub(best_gain[0], GPCLIP2) > 0) best_gain[0] = GPCLIP2; if(best_gain[0] > GPCLIP2) best_gain[0] = GPCLIP2; } /*-----------------------------------------------------------------* * best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; * *-----------------------------------------------------------------*/ L_tmp1 = L_mult( g_coeff[0], g_coeff[3] ); exp1 = add( exp_coeff[0], exp_coeff[3] ) ; L_tmp2 = L_mult( g_coeff[1], g_coeff[4] ); exp2 = add( add( exp_coeff[1], exp_coeff[4] ), 1 ); //if( sub(exp1, exp2)>0 ){ if( exp1 > exp2 ){ L_tmp = L_sub( L_shr( L_tmp1, add(sub(exp1,exp2),1) ), L_shr( L_tmp2,1 ) ); exp = sub(exp2,1); //exp = exp2--; } else{ L_tmp = L_sub( L_shr( L_tmp1,1 ), L_shr( L_tmp2, add(sub(exp2,exp1),1) ) ); exp = sub(exp1,1); //exp = exp1--; } sft = norm_l( L_tmp ); nume = extract_h( L_shl(L_tmp, sft) ); exp_nume = sub( add( exp, sft ), 16 ); sft = sub( add( exp_nume, exp_inv_denom ), (2+16-1) ); L_acc = L_shr( L_mult( nume,inv_denom ), sft ); best_gain[1] = extract_h( L_acc ); /*-- best_gain[1]:Q2 --*/ /*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/ //if( sub(exp_gcode0,4) >= 0 ){ if (exp_gcode0 >=4) { gcode0_org = shr( gcode0, sub(exp_gcode0,4) ); } else{ L_acc = L_deposit_l( gcode0 ); L_acc = L_shl( L_acc, sub( (4+16), exp_gcode0 ) ); gcode0_org = extract_h( L_acc ); /*-- gcode0_org:Q4 --*/ } /*----------------------------------------------* * - presearch for gain codebook - * *----------------------------------------------*/ Gbk_presel(best_gain, &cand1, &cand2, gcode0_org ); /*---------------------------------------------------------------------------* * * * Find the best quantizer. * * * * dist_min = MAX_32; * * for ( i=0 ; i<NCAN1 ; i++ ){ * * for ( j=0 ; j<NCAN2 ; j++ ){ * * g_pitch = gbk1[cand1+i][0] + gbk2[cand2+j][0]; * * g_code = gcode0 * (gbk1[cand1+i][1] + gbk2[cand2+j][1]); * * dist = g_pitch*g_pitch * coeff[0] * * + g_pitch * coeff[1] * * + g_code*g_code * coeff[2] * * + g_code * coeff[3] * * + g_pitch*g_code * coeff[4] ; * * * * if (dist < dist_min){ * * dist_min = dist; * * indice1 = cand1 + i ; * * indice2 = cand2 + j ; * * } * * } * * } * * * * g_pitch = Q13 * * g_pitch*g_pitch = Q11:(13+13+1-16) * * g_code = Q[exp_gcode0-3]:(exp_gcode0+(13-1)+1-16) * * g_code*g_code = Q[2*exp_gcode0-21]:(exp_gcode0-3+exp_gcode0-3+1-16) * * g_pitch*g_code = Q[exp_gcode0-5]:(13+exp_gcode0-3+1-16) * * * * term 0: g_pitch*g_pitch*coeff[0] ;exp_min0 = 13 +exp_coeff[0] * * term 1: g_pitch *coeff[1] ;exp_min1 = 14 +exp_coeff[1] * * term 2: g_code*g_code *coeff[2] ;exp_min2 = 2*exp_gcode0-21+exp_coeff[2] * * term 3: g_code *coeff[3] ;exp_min3 = exp_gcode0 - 3+exp_coeff[3] * * term 4: g_pitch*g_code *coeff[4] ;exp_min4 = exp_gcode0 - 4+exp_coeff[4] * * * *---------------------------------------------------------------------------*/ exp_min[0] = add( exp_coeff[0], 13 ); exp_min[1] = add( exp_coeff[1], 14 ); exp_min[2] = add( exp_coeff[2], sub( shl( exp_gcode0, 1 ), 21 ) ); exp_min[3] = add( exp_coeff[3], sub( exp_gcode0, 3 ) ); exp_min[4] = add( exp_coeff[4], sub( exp_gcode0, 4 ) ); e_min = exp_min[0]; for(i=1; i<5; i++){ //if( sub(exp_min[i], e_min) < 0 ){ if (exp_min[i] < e_min) { e_min = exp_min[i]; } } /* align coeff[] and save in special 32 bit double precision */ for(i=0; i<5; i++){ j = sub( exp_min[i], e_min ); L_tmp = (Word32)g_coeff[i] << 16; L_tmp = L_shr( L_tmp, j ); /* L_tmp:Q[exp_g_coeff[i]+16-j] */ L_Extract( L_tmp, &coeff[i], &coeff_lsf[i] ); /* DPF */ } /* Codebook search */ L_dist_min = MAX_32; /* initialization used only to suppress Microsoft Visual C++ warnings */ index1 = cand1; index2 = cand2; if(tameflag == 1){ for(i=0; i<NCAN1; i++){ for(j=0; j<NCAN2; j++){ g_pitch = add( gbk1[cand1+i][0], gbk2[cand2+j][0] ); /* Q14 */ if(g_pitch < GP0999) { L_acc = L_deposit_l( gbk1[cand1+i][1] ); L_accb = L_deposit_l( gbk2[cand2+j][1] ); /* Q13 */ L_tmp = L_add( L_acc,L_accb ); tmp = extract_l( L_shr( L_tmp,1 ) ); /* Q12 */ g_code = mult( gcode0, tmp ); /* Q[exp_gcode0+12-15] */ g2_pitch = mult(g_pitch, g_pitch); /* Q13 */ g2_code = mult(g_code, g_code); /* Q[2*exp_gcode0-6-15] */ g_pit_cod= mult(g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */ L_tmp = Mpy_32_16(coeff[0], coeff_lsf[0], g2_pitch); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch) ); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[2], coeff_lsf[2], g2_code) ); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[3], coeff_lsf[3], g_code) ); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod) ); L_tmp += Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch); L_tmp += Mpy_32_16(coeff[2], coeff_lsf[2], g2_code); L_tmp += Mpy_32_16(coeff[3], coeff_lsf[3], g_code); L_tmp += Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod); //L_temp = L_sub(L_tmp, L_dist_min); //if( L_temp < 0L ){ if( L_tmp < L_dist_min ){ L_dist_min = L_tmp; index1 = add(cand1,i); index2 = add(cand2,j); } } } } } else{ for(i=0; i<NCAN1; i++){ for(j=0; j<NCAN2; j++){ g_pitch = add( gbk1[cand1+i][0], gbk2[cand2+j][0] ); /* Q14 */ L_acc = L_deposit_l( gbk1[cand1+i][1] ); L_accb = L_deposit_l( gbk2[cand2+j][1] ); /* Q13 */ L_tmp = L_add( L_acc,L_accb ); tmp = extract_l( L_shr( L_tmp,1 ) ); /* Q12 */ g_code = mult( gcode0, tmp ); /* Q[exp_gcode0+12-15] */ g2_pitch = mult(g_pitch, g_pitch); /* Q13 */ g2_code = mult(g_code, g_code); /* Q[2*exp_gcode0-6-15] */ g_pit_cod= mult(g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */ L_tmp = Mpy_32_16(coeff[0], coeff_lsf[0], g2_pitch); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch) ); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[2], coeff_lsf[2], g2_code) ); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[3], coeff_lsf[3], g_code) ); //L_tmp = L_add(L_tmp, Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod) ); L_tmp += Mpy_32_16(coeff[1], coeff_lsf[1], g_pitch); L_tmp += Mpy_32_16(coeff[2], coeff_lsf[2], g2_code); L_tmp += Mpy_32_16(coeff[3], coeff_lsf[3], g_code); L_tmp += Mpy_32_16(coeff[4], coeff_lsf[4], g_pit_cod); if( L_tmp < L_dist_min ){ L_dist_min = L_tmp; index1 = add(cand1,i); index2 = add(cand2,j); } } } } /* Read the quantized gain */ /*-----------------------------------------------------------------* * *gain_pit = gbk1[indice1][0] + gbk2[indice2][0]; * *-----------------------------------------------------------------*/ *gain_pit = add( gbk1[index1][0], gbk2[index2][0] ); /* Q14 */ /*-----------------------------------------------------------------* * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * *-----------------------------------------------------------------*/ L_gbk12 = (Word32)gbk1[index1][1] + (Word32)gbk2[index2][1]; /* Q13 */ tmp = extract_l( L_shr( L_gbk12,1 ) ); /* Q12 */ L_acc = L_mult(tmp, gcode0); /* Q[exp_gcode0+12+1] */ L_acc = L_shl(L_acc, add( negate(exp_gcode0),(-12-1+1+16) )); *gain_cod = extract_h( L_acc ); /* Q1 */ /*----------------------------------------------* * update table of past quantized energies * *----------------------------------------------*/ Gain_update( past_qua_en, L_gbk12 ); return( add( map1[index1]*(Word16)NCODE2, map2[index2] ) ); }
Word32 quant_6p_6N_2( /* (o) return (6*N)-2 bits */ Word16 pos[], /* (i) position of the pulse 1..6 */ Word16 N) /* (i) number of bits for position */ { Word16 nb_pos, n_1; Word16 posA[6], posB[6]; Word32 i, j, k, index; /* !! N and n_1 are constants -> it doesn't need to be operated by Basic Operators */ // N和n_1是常数-它不需要基本的运营 n_1 = (Word16) (N - 1); nb_pos = (1 << n_1); /* nb_pos = (1<<n_1); */ i = 0; j = 0; for (k = 0; k < 6; k++) { if ((pos[k] & nb_pos) == 0) { posA[i++] = pos[k]; } else { posB[j++] = pos[k]; } } switch (i) { case 0: index = (1 << (Word16) (6 * N - 5)); /* index = 1 << ((6*N)-5); */ index = vo_L_add(index, (quant_5p_5N(posB, n_1) << N)); /* index += quant_5p_5N(posB, n_1) << N; */ index = vo_L_add(index, quant_1p_N1(posB[5], n_1)); /* index += quant_1p_N1(posB[5], n_1); */ break; case 1: index = (1L << (Word16) (6 * N - 5)); /* index = 1 << ((6*N)-5); */ index = vo_L_add(index, (quant_5p_5N(posB, n_1) << N)); /* index += quant_5p_5N(posB, n_1) << N; */ index = vo_L_add(index, quant_1p_N1(posA[0], n_1)); /* index += quant_1p_N1(posA[0], n_1); */ break; case 2: index = (1L << (Word16) (6 * N - 5)); /* index = 1 << ((6*N)-5); */ /* index += quant_4p_4N(posB, n_1) << ((2*n_1)+1); */ index = vo_L_add(index, (quant_4p_4N(posB, n_1) << (Word16) (2 * n_1 + 1))); index = vo_L_add(index, quant_2p_2N1(posA[0], posA[1], n_1)); /* index += quant_2p_2N1(posA[0], posA[1], n_1); */ break; case 3: index = (quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << (Word16) (3 * n_1 + 1)); /* index = quant_3p_3N1(posA[0], posA[1], posA[2], n_1) << ((3*n_1)+1); */ index =vo_L_add(index, quant_3p_3N1(posB[0], posB[1], posB[2], n_1)); /* index += quant_3p_3N1(posB[0], posB[1], posB[2], n_1); */ break; case 4: i = 2; index = (quant_4p_4N(posA, n_1) << (Word16) (2 * n_1 + 1)); /* index = quant_4p_4N(posA, n_1) << ((2*n_1)+1); */ index = vo_L_add(index, quant_2p_2N1(posB[0], posB[1], n_1)); /* index += quant_2p_2N1(posB[0], posB[1], n_1); */ break; case 5: i = 1; index = (quant_5p_5N(posA, n_1) << N); /* index = quant_5p_5N(posA, n_1) << N; */ index = vo_L_add(index, quant_1p_N1(posB[0], n_1)); /* index += quant_1p_N1(posB[0], n_1); */ break; case 6: i = 0; index = (quant_5p_5N(posA, n_1) << N); /* index = quant_5p_5N(posA, n_1) << N; */ index = vo_L_add(index, quant_1p_N1(posA[5], n_1)); /* index += quant_1p_N1(posA[5], n_1); */ break; default: index = 0; fprintf(stderr, "Error in function quant_6p_6N_2\n"); } index = vo_L_add(index, ((L_deposit_l(i) & 3L) << (Word16) (6 * N - 4))); /* index += (i & 3) << ((6*N)-4); */ return (index); }
/*---------------------------------------------------------------------------* * Function Dec_gain * * ~~~~~~~~~~~~~~~~~~ * * Decode the pitch and codebook gains * * * *---------------------------------------------------------------------------* * input arguments: * * * * index :Quantization index * * code[] :Innovative code vector * * L_subfr :Subframe size * * bfi :Bad frame indicator * * * * output arguments: * * * * gain_pit :Quantized pitch gain * * gain_cod :Quantized codebook gain * * * *---------------------------------------------------------------------------*/ void WebRtcG729fix_Dec_gain( Decod_ld8a_state *st, int16_t index, /* (i) :Index of quantization. */ int16_t code[], /* (i) Q13 :Innovative vector. */ int16_t L_subfr, /* (i) :Subframe length. */ int16_t bfi, /* (i) :Bad frame indicator */ int16_t *gain_pit, /* (o) Q14 :Pitch gain. */ int16_t *gain_cod /* (o) Q1 :Code gain. */ ) { int16_t index1, index2, tmp; int16_t gcode0, exp_gcode0; int32_t L_gbk12, L_acc, L_accb; /*-------------- Case of erasure. ---------------*/ if(bfi != 0){ *gain_pit = mult( *gain_pit, 29491 ); /* *0.9 in Q15 */ if (*gain_pit > 29491) *gain_pit = 29491; *gain_cod = mult( *gain_cod, 32111 ); /* *0.98 in Q15 */ /*----------------------------------------------* * update table of past quantized energies * * (frame erasure) * *----------------------------------------------*/ WebRtcG729fix_Gain_update_erasure(st->past_qua_en); return; } /*-------------- Decode pitch gain ---------------*/ index1 = WebRtcG729fix_imap1[ shr(index,NCODE2_B) ] ; index2 = WebRtcG729fix_imap2[ index & (NCODE2-1) ] ; *gain_pit = WebRtcSpl_AddSatW16( WebRtcG729fix_gbk1[index1][0], WebRtcG729fix_gbk2[index2][0] ); /*-------------- Decode codebook gain ---------------*/ /*---------------------------------------------------* *- energy due to innovation -* *- predicted energy -* *- predicted codebook gain => gcode0[exp_gcode0] -* *---------------------------------------------------*/ WebRtcG729fix_Gain_predict(st->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 ); /*-----------------------------------------------------------------* * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; * *-----------------------------------------------------------------*/ L_acc = L_deposit_l( WebRtcG729fix_gbk1[index1][1] ); L_accb = L_deposit_l( WebRtcG729fix_gbk2[index2][1] ); L_gbk12 = WebRtcSpl_AddSatW32( L_acc, L_accb ); /* Q13 */ tmp = extract_l( L_shr( L_gbk12,1 ) ); /* Q12 */ L_acc = L_mult(tmp, gcode0); /* Q[exp_gcode0+12+1] */ L_acc = L_shl(L_acc, WebRtcSpl_AddSatW16( negate(exp_gcode0),(-12-1+1+16) )); *gain_cod = extract_h( L_acc ); /* Q1 */ /*----------------------------------------------* * update table of past quantized energies * *----------------------------------------------*/ WebRtcG729fix_Gain_update(st->past_qua_en, L_gbk12 ); return; }
Word16 compute_region_powers(Word16 *mlt_coefs, Word16 mag_shift, Word16 *drp_num_bits, UWord16 *drp_code_bits, Word16 *absolute_region_power_index, Word16 number_of_regions) { Word16 *input_ptr; Word32 long_accumulator; Word16 itemp1; Word16 power_shift; Word16 region; Word16 j; Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS]; Word16 number_of_bits; Word32 acca; Word16 temp; Word16 temp1; Word16 temp2; input_ptr = mlt_coefs; for (region=0; region<number_of_regions; region++) { long_accumulator = L_deposit_l(0); for (j=0; j<REGION_SIZE; j++) { itemp1 = *input_ptr++; move16(); long_accumulator = L_mac0(long_accumulator,itemp1,itemp1); } power_shift = 0; move16(); acca = (long_accumulator & 0x7fff0000L); logic32(); test(); while (acca > 0) { test(); long_accumulator = L_shr_nocheck(long_accumulator,1); acca = (long_accumulator & 0x7fff0000L); logic32(); power_shift = add(power_shift,1); } acca = L_sub(long_accumulator,32767); temp = add(power_shift,15); test(); test(); logic16(); while ((acca <= 0) && (temp >= 0)) { test(); test(); logic16(); long_accumulator = L_shl_nocheck(long_accumulator,1); acca = L_sub(long_accumulator,32767); power_shift--; temp = add(power_shift,15); } long_accumulator = L_shr_nocheck(long_accumulator,1); /* 28963 corresponds to square root of 2 times REGION_SIZE(20). */ acca = L_sub(long_accumulator,28963); test(); if (acca >= 0) power_shift = add(power_shift,1); acca = L_deposit_l(mag_shift); acca = L_shl_nocheck(acca,1); acca = L_sub(power_shift,acca); acca = L_add(35,acca); acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES); absolute_region_power_index[region] = extract_l(acca); } /* Before we differentially encode the quantized region powers, adjust upward the valleys to make sure all the peaks can be accurately represented. */ temp = sub(number_of_regions,2); for (region = temp; region >= 0; region--) { temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX); temp2 = sub(absolute_region_power_index[region],temp1); test(); if (temp2 < 0) { absolute_region_power_index[region] = temp1; move16(); } } /* The MLT is currently scaled too low by the factor ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160). This is the ninth power of 1 over the square root of 2. So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9) to drp_code_bits[0]. */ /* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */ temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX); temp2 = sub(absolute_region_power_index[0],temp1); test(); if (temp2 < 0) { absolute_region_power_index[0] = temp1; move16(); } temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX); /* * The next line was corrected in Release 1.2 */ temp2 = sub(absolute_region_power_index[0], temp1); test(); if (temp2 > 0) { absolute_region_power_index[0] = temp1; move16(); } differential_region_power_index[0] = absolute_region_power_index[0]; move16(); number_of_bits = 5; move16(); drp_num_bits[0] = 5; move16(); drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX); move16(); /* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes may be mathematically impossible anyway.*/ for (region=1; region<number_of_regions; region++) { temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX); temp2 = sub(absolute_region_power_index[region],temp1); test(); if (temp2 < 0) { absolute_region_power_index[region] = temp1; move16(); } temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX); temp2 = sub(absolute_region_power_index[region],temp1); test(); if (temp2 > 0) { absolute_region_power_index[region] = temp1; move16(); } } for (region=1; region<number_of_regions; region++) { j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]); temp = sub(j,DRP_DIFF_MIN); test(); if (temp < 0) { j = DRP_DIFF_MIN; } j = sub(j,DRP_DIFF_MIN); move16(); differential_region_power_index[region] = j; move16(); temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]); temp = add(temp,DRP_DIFF_MIN); absolute_region_power_index[region] = temp; move16(); number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]); drp_num_bits[region] = differential_region_power_bits[region][j]; move16(); drp_code_bits[region] = differential_region_power_codes[region][j]; move16(); } return (number_of_bits); }