void interpolate_isp( int16 isp_old[], /* input : isps from past frame */ int16 isp_new[], /* input : isps from present frame */ const int16 frac[], /* input : fraction for 3 first subfr (Q15) */ int16 Az[] /* output: LP coefficients in 4 subframes */ ) { int16 i, k, fac_old, fac_new; int16 isp[M]; int32 L_tmp; for (k = 0; k < 3; k++) { fac_new = frac[k]; fac_old = add_int16(sub_int16(32767, fac_new), 1); /* 1.0 - fac_new */ for (i = 0; i < M; i++) { L_tmp = mul_16by16_to_int32(isp_old[i], fac_old); L_tmp = mac_16by16_to_int32(L_tmp, isp_new[i], fac_new); isp[i] = amr_wb_round(L_tmp); } Isp_Az(isp, Az, M, 0); Az += MP1; } /* 4th subframe: isp_new (frac=1.0) */ Isp_Az(isp_new, Az, M, 0); return; }
//============================================================================ //函数功能:找到语音因子 //函数参数:"exc[]"表示因子,作为输入参数;"Q_exc"表示激励,表示输入参数;"gain_pit" // 表示增益音高,作为输入参数;"code[]"表示固定码本激励,作为输入参数; // "gain_code"表示编码增益,作为输入参数;"L_subfr"表示子帧长度 //============================================================================ int16 voice_factor( /* (o) Q15 : factor (-1=unvoiced to 1=voiced) */ int16 exc[], /* (i) Q_exc : pitch excitation */ int16 Q_exc, /* (i) : exc format */ int16 gain_pit, /* (i) Q14 : gain of pitch */ int16 code[], /* (i) Q9 : Fixed codebook excitation */ int16 gain_code, /* (i) Q0 : gain of code */ int16 L_subfr /* (i) : subframe length */ ) { int16 i, tmp, exp, ener1, exp1, ener2, exp2; int32 L_tmp; ener1 = extract_h(Dot_product12(exc, exc, L_subfr, &exp1)); exp1 = sub_int16(exp1, Q_exc << 1); L_tmp = mul_16by16_to_int32(gain_pit, gain_pit); exp = normalize_amr_wb(L_tmp); tmp = (int16)((L_tmp << exp) >> 16); ener1 = mult_int16(ener1, tmp); exp1 -= (exp + 10); /* 10 -> gain_pit Q14 to Q9 */ ener2 = extract_h(Dot_product12(code, code, L_subfr, &exp2)); exp = norm_s(gain_code); tmp = shl_int16(gain_code, exp); tmp = mult_int16(tmp, tmp); ener2 = mult_int16(ener2, tmp); exp2 -= (exp << 1); i = exp1 - exp2; if (i >= 0) { ener1 >>= 1; ener2 >>= (i + 1); }
{ for (i = 0; i < M; i++) { for (j = (L_MEANBUF - 1); j > 0; j--) { isf_buf[j * M + i] = isf_buf[(j - 1) * M + i]; } isf_buf[i] = isf_q[i]; } } } else { /* bad frame */ for (i = 0; i < M; i++) { L_tmp = mul_16by16_to_int32(mean_isf[i], 8192); for (j = 0; j < L_MEANBUF; j++) { L_tmp = mac_16by16_to_int32(L_tmp, isf_buf[j * M + i], 8192); } ref_isf[i] = amr_wb_round(L_tmp); } /* use the past ISFs slightly shifted towards their mean */ for (i = 0; i < ORDER; i++) { isf_q[i] = add_int16(mult_int16(ALPHA, isfold[i]), mult_int16(ONE_ALPHA, ref_isf[i])); } /* estimate past quantized residual to be used in next frame */
//============================================================================ //函数功能:设置存储器 //函数参数:"index"表示指标量化,作为输入参数;"nbits"表示位数,作为输入参数;" // code[]"表示创新载体,作为输入参数;"L_subfr"表示子帧长度,作为输入参 // 数;"gain_pit"表示基音增益,作为输出参数;"gain_cod"表示编码增益,作 // 为输出参数;"bfi"表示坏帧指示,作为输入参数;"prev_bfi"表示先前BF指 // 示器,作为输入参数;"state"表示BFH的状态,作为输入参数;"unusable_frame" // 表示UF指示器,作为输入参数;"vad_hist"表示非语音帧的数目,作为输入参 // 数;"mem"表示静态存储器,既作为输入参数又作为输出参数 //============================================================================ void dec_gain2_amr_wb( int16 index, /* (i) : index of quantization. */ int16 nbits, /* (i) : number of bits (6 or 7) */ int16 code[], /* (i) Q9 : Innovative vector. */ int16 L_subfr, /* (i) : Subframe lenght. */ int16 * gain_pit, /* (o) Q14 : Pitch gain. */ int32 * gain_cod, /* (o) Q16 : Code gain. */ int16 bfi, /* (i) : bad frame indicator */ int16 prev_bfi, /* (i) : Previous BF indicator */ int16 state, /* (i) : State of BFH */ int16 unusable_frame, /* (i) : UF indicator */ int16 vad_hist, /* (i) : number of non-speech frames */ int16 * mem /* (i/o) : static memory (4 words) */ ) { const int16 *p; int16 *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc; int16 *pbuf2; int16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov; int16 tmp1, g_code; int16 tmp2; int32 L_tmp; past_qua_en = mem; past_gain_pit = mem + 4; past_gain_code = mem + 5; prev_gc = mem + 6; pbuf = mem + 7; gbuf = mem + 12; pbuf2 = mem + 17; /* * Find energy of code and compute: * * L_tmp = 1.0 / sqrt(energy of code/ L_subfr) */ L_tmp = Dot_product12(code, code, L_subfr, &exp); exp -= 24; /* exp: -18 (code in Q9), -6 (/L_subfr) */ one_ov_sqrt_norm(&L_tmp, &exp); gcode_inov = extract_h(shl_int32(L_tmp, exp - 3)); /* g_code_inov in Q12 */ /* * Case of erasure. */ if (bfi != 0) { tmp = median5(&pbuf[2]); *past_gain_pit = tmp; if (*past_gain_pit > 15565) { *past_gain_pit = 15565; /* 0.95 in Q14 */ } if (unusable_frame != 0) { *gain_pit = mult_int16(pdown_unusable[state], *past_gain_pit); } else { *gain_pit = mult_int16(pdown_usable[state], *past_gain_pit); } tmp = median5(&gbuf[2]); if (vad_hist > 2) { *past_gain_code = tmp; } else { if (unusable_frame != 0) { *past_gain_code = mult_int16(cdown_unusable[state], tmp); } else { *past_gain_code = mult_int16(cdown_usable[state], tmp); } } /* update table of past quantized energies */ //更新过去的量子化的能量表 tmp = past_qua_en[3]; tmp1 = past_qua_en[2]; L_tmp = tmp; L_tmp += tmp1; past_qua_en[3] = tmp; tmp = past_qua_en[1]; tmp1 = past_qua_en[0]; L_tmp += tmp; L_tmp += tmp1; past_qua_en[2] = tmp; qua_ener = (int16)(L_tmp >> 3); past_qua_en[1] = tmp1; qua_ener -= 3072; /* -3 in Q10 */ if (qua_ener < -14336) { qua_ener = -14336; /* -14 in Q10 */ } past_qua_en[0] = qua_ener; for (i = 1; i < 5; i++) { gbuf[i - 1] = gbuf[i]; pbuf[i - 1] = pbuf[i]; } gbuf[4] = *past_gain_code; pbuf[4] = *past_gain_pit; /* adjust gain according to energy of code */ /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */ //调整增益根据能量代码 *gain_cod = mul_16by16_to_int32(*past_gain_code, gcode_inov); return; }
void agc2_amr_wb( int16 * sig_in, /* (i) : postfilter input signal */ int16 * sig_out, /* (i/o) : postfilter output signal */ int16 l_trm /* (i) : subframe size */ ) { int16 i, exp; int16 gain_in, gain_out, g0; int32 s; int16 temp; /* calculate gain_out with exponent */ temp = sig_out[0] >> 2; s = fxp_mul_16by16(temp, temp) << 1; for (i = 1; i < l_trm; i++) { temp = sig_out[i] >> 2; s = mac_16by16_to_int32(s, temp, temp); } if (s == 0) { return; } exp = normalize_amr_wb(s) - 1; gain_out = amr_wb_round(s << exp); /* calculate gain_in with exponent */ temp = sig_in[0] >> 2; s = mul_16by16_to_int32(temp, temp); for (i = 1; i < l_trm; i++) { temp = sig_in[i] >> 2; s = mac_16by16_to_int32(s, temp, temp); } if (s == 0) { g0 = 0; } else { i = normalize_amr_wb(s); gain_in = amr_wb_round(s << i); exp -= i; /* * g0 = sqrt(gain_in/gain_out) */ s = div_16by16(gain_out, gain_in); s = shl_int32(s, 7); /* s = gain_out / gain_in */ s = shr_int32(s, exp); /* add exponent */ s = one_ov_sqrt(s); g0 = amr_wb_round(shl_int32(s, 9)); } /* sig_out(n) = gain(n) sig_out(n) */ for (i = 0; i < l_trm; i++) { sig_out[i] = extract_h(shl_int32(fxp_mul_16by16(sig_out[i], g0), 3)); } return; }