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); }
void phase_dispersion( int16 gain_code, /* (i) Q0 : gain of code */ int16 gain_pit, /* (i) Q14 : gain of pitch */ int16 code[], /* (i/o) : code vector */ int16 mode, /* (i) : level, 0=hi, 1=lo, 2=off */ int16 disp_mem[], /* (i/o) : static memory (size = 8) */ int16 ScratchMem[] ) { int16 i, j, state; int16 *prev_gain_pit, *prev_gain_code, *prev_state; int16 *code2 = ScratchMem; prev_state = disp_mem; prev_gain_code = disp_mem + 1; prev_gain_pit = disp_mem + 2; pv_memset((void *)code2, 0, (2*L_SUBFR)*sizeof(*code2)); if (gain_pit < pitch_0_6) { state = 0; } else if (gain_pit < pitch_0_9) { state = 1; } else { state = 2; } for (i = 5; i > 0; i--) { prev_gain_pit[i] = prev_gain_pit[i - 1]; } prev_gain_pit[0] = gain_pit; if (sub_int16(gain_code, *prev_gain_code) > shl_int16(*prev_gain_code, 1)) { /* onset */ if (state < 2) { state++; } } else { j = 0; for (i = 0; i < 6; i++) { if (prev_gain_pit[i] < pitch_0_6) { j++; } } if (j > 2) { state = 0; } if (state > *prev_state + 1) { state--; } } *prev_gain_code = gain_code; *prev_state = state; /* circular convolution */ state += mode; /* level of dispersion */ if (state == 0) { for (i = 0; i < L_SUBFR; i++) { if (code[i] != 0) { for (j = 0; j < L_SUBFR; j++) { code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_low[j])); } } } } else if (state == 1) { for (i = 0; i < L_SUBFR; i++) { if (code[i] != 0) { for (j = 0; j < L_SUBFR; j++) { code2[i + j] = add_int16(code2[i + j], mult_int16_r(code[i], ph_imp_mid[j])); } } } } if (state < 2) { for (i = 0; i < L_SUBFR; i++) { code[i] = add_int16(code2[i], code2[i + L_SUBFR]); } } return; }