//============================================================================ //函数功能:找到语音因子 //函数参数:"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); }
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; }