void Pre_Process( PrpStatus *handle, Word16 signal[], /* input/output signal */ Word16 lg) /* length of signal */ { Word16 i, x2; Word32 L_tmp; for(i=0; i<lg; i++) { x2 = handle->x1; handle->x1 = handle->x0; handle->x0 = signal[i]; /* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */ /* + a[1]*y[i-1] + a[2] * y[i-2]; */ L_tmp = Mpy_32_16(handle->y1_hi, handle->y1_lo, a140[1]); L_tmp = L_add(L_tmp, Mpy_32_16(handle->y2_hi, handle->y2_lo, a140[2])); L_tmp = L_mac(L_tmp, handle->x0, b140[0]); L_tmp = L_mac(L_tmp, handle->x1, b140[1]); L_tmp = L_mac(L_tmp, x2, b140[2]); L_tmp = L_shl(L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */ signal[i] = round(L_tmp); handle->y2_hi = handle->y1_hi; handle->y2_lo = handle->y1_lo; L_Extract(L_tmp, &(handle->y1_hi), &(handle->y1_lo)); } return; }
void Post_Process( int16_t signal[], /* input/output signal */ int16_t lg) /* length of signal */ { int16_t i, x2; int32_t L_tmp; for(i=0; i<lg; i++) { x2 = x1; x1 = x0; x0 = signal[i]; /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */ /* + a[1]*y[i-1] + a[2] * y[i-2]; */ L_tmp = Mpy_32_16(y1_hi, y1_lo, a100[1]); L_tmp = L_add(L_tmp, Mpy_32_16(y2_hi, y2_lo, a100[2])); L_tmp = L_mac(L_tmp, x0, b100[0]); L_tmp = L_mac(L_tmp, x1, b100[1]); L_tmp = L_mac(L_tmp, x2, b100[2]); L_tmp = L_shl(L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */ /* Multiplication by two of output speech with saturation. */ signal[i] = _round(L_shl(L_tmp, 1)); y2_hi = y1_hi; y2_lo = y1_lo; L_Extract(L_tmp, &y1_hi, &y1_lo); } return; }
void Deemph2_( Word16 x[], /* (i/o) : input signal overwritten by the output */ Word16 mu, /* (i) Q15 : deemphasis factor */ Word16 L, /* (i) : vector size */ Word16 * mem /* (i/o) : memory (y[-1]) */ ) { Word16 i; Word32 L_tmp; /* saturation can occur in L_mac() */ L_tmp = L_mult(x[0], 16384); L_tmp = L_mac(L_tmp, *mem, mu); x[0] = round16(L_tmp); for (i = 1; i < L; i++) { L_tmp = L_mult(x[i], 16384); L_tmp = L_mac(L_tmp, x[i - 1], mu); x[i] = round16(L_tmp); } *mem = x[L - 1]; return; }
/*---------------------------------------------------------------------------* * Procedure Interpol_3() * * ~~~~~~~~~~~~~~~~~~~~~~ * * For interpolating the normalized correlation with 1/3 resolution. * *--------------------------------------------------------------------------*/ Word16 Interpol_3( /* (o) : interpolated value */ Word16 *x, /* (i) : input vector */ Word16 frac /* (i) : fraction */ ) { Word16 i, k; Word16 *x1, *x2, *c1, *c2; Word32 s; if(frac < 0) { frac = add(frac, UP_SAMP); x--; } x1 = &x[0]; x2 = &x[1]; c1 = &inter_3[frac]; c2 = &inter_3[sub(UP_SAMP,frac)]; s = 0; for(i=0, k=0; i< L_INTER4; i++, k+=UP_SAMP) { s = L_mac(s, x1[-i], c1[k]); s = L_mac(s, x2[i], c2[k]); } return round(s); }
void maxeloc(INT16 *maxloc, INT32 *maxener, INT16 *signal, INT16 dp, INT16 length, INT16 ewl) { INT32 ener; register int i; int tail, front; ener = 0; front = add(dp, ewl); tail = sub(dp, ewl); for (i = tail; i <= front; i++) ener = L_mac(ener, signal[i], signal[i]); *maxloc = 0; *maxener = ener; for (i = 1; i < length; i++) { front++; ener = L_msu(ener, signal[tail], signal[tail]); ener = L_mac(ener, signal[front], signal[front]); tail++; if (*maxener < ener) { *maxloc = i; *maxener = ener; } } *maxloc = add(*maxloc,dp); *maxener = L_shr(*maxener, 1); }
Word16 sqrts(Word16 x) { Word16 xb, y, exp, idx, sub_frac, sub_tab; Word32 a0; if(x <= 0){ y = 0; } else{ exp = norm_s(x); /* use 65-entry table */ xb = shl(x, exp); // normalization of x idx = shr(xb, 9); // for 65 entry table a0 = L_deposit_h(tabsqrt[idx]); // Q31 table look-up value sub_frac = shl((Word16)(xb & 0x01FF), 6); // Q15 sub-fraction sub_tab = sub(tabsqrt[idx+1], tabsqrt[idx]); // Q15 table interval for interpolation a0 = L_mac(a0, sub_frac, sub_tab); // Q31 linear interpolation between table entries if(exp & 0x0001){ exp = shr(add(exp, 1), 1); // normalization of sqrt() a0 = L_shr(a0, exp); y = intround(a0); // Q15 a0 = L_mac(a0, 13573, y); // Q31 incorporate the missing "/sqrt(2)" } else{ exp = shr(exp, 1); // normalization of sqrt() a0 = L_shr(a0, exp); // Q31 } y = intround(a0); // Q15 } return y; }
void Pre_Process( Word16 signal[], /* input/output signal */ Word16 lg) /* length of signal */ { Word16 i, x2; Word32 L_tmp; for(i=0; i<lg; i++) { x2 = x1; x1 = x0; x0 = signal[i]; /* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */ /* + a[1]*y[i-1] + a[2] * y[i-2]; */ L_tmp = Mpy_32_16(y1_hi, y1_lo, a140[1]); L_tmp = L_add(L_tmp, Mpy_32_16(y2_hi, y2_lo, a140[2])); L_tmp = L_mac(L_tmp, x0, b140[0]); L_tmp = L_mac(L_tmp, x1, b140[1]); L_tmp = L_mac(L_tmp, x2, b140[2]); L_tmp = L_shl(L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */ signal[i] = round(L_tmp); y2_hi = y1_hi; y2_lo = y1_lo; L_Extract(L_tmp, &y1_hi, &y1_lo); } return; }
void Post_Process( PopStatus *handle, Word16 signal[], /* input/output signal */ Word16 lg) /* length of signal */ { Word16 i, x2; Word32 L_tmp; for(i=0; i<lg; i++) { x2 = handle->x1; handle->x1 = handle->x0; handle->x0 = signal[i]; /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */ /* + a[1]*y[i-1] + a[2] * y[i-2]; */ L_tmp = Mpy_32_16(handle->y1_hi, handle->y1_lo, a100[1]); L_tmp = L_add(L_tmp, Mpy_32_16(handle->y2_hi, handle->y2_lo, a100[2])); L_tmp = L_mac(L_tmp, handle->x0, b100[0]); L_tmp = L_mac(L_tmp, handle->x1, b100[1]); L_tmp = L_mac(L_tmp, x2, b100[2]); L_tmp = L_shl(L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */ /* Multiplication by two of output speech with saturation. */ signal[i] = round(L_shl(L_tmp, 1)); handle->y2_hi = handle->y1_hi; handle->y2_lo = handle->y1_lo; L_Extract(L_tmp, &(handle->y1_hi), &(handle->y1_lo)); } return; }
//========================================================================== //函数功能:过滤要求的信号,为32位信号将信号一分为二 //函数参数:"x[]"表示输入信号的输出覆盖,既是输入参数又是输出参数;"mu"表示释 // 放因子,作为输入参数;"L"表示向量的大小,作为输入参数;"mem"表示存 // 储器的记忆 //========================================================================== void Deemph( Word16 x[], /* (i/o) : input signal overwritten by the output */ Word16 mu, /* (i) Q15 : deemphasis factor */ Word16 L, /* (i) : vector size */ Word16 * mem /* (i/o) : memory (y[-1]) */ ) { Word32 i; Word32 L_tmp; L_tmp = L_deposit_h(x[0]); L_tmp = L_mac(L_tmp, *mem, mu); x[0] = vo_round(L_tmp); for (i = 1; i < L; i++) { L_tmp = L_deposit_h(x[i]); L_tmp = L_mac(L_tmp, x[i - 1], mu); x[i] = voround(L_tmp); } *mem = x[L - 1]; return; }
static void Calc_RCoeff(Word16 *Coeff, Word16 *RCoeff, Word16 *sh_RCoeff) { Word16 i, j; Word16 sh1; Word32 L_acc; /* RCoeff[0] = SUM(j=0->M) Coeff[j] ** 2 */ L_acc = 0L; for(j=0; j <= M; j++) { L_acc = L_mac(L_acc, Coeff[j], Coeff[j]); } /* Compute exponent RCoeff */ sh1 = norm_l(L_acc); L_acc = L_shl(L_acc, sh1); RCoeff[0] = round(L_acc); /* RCoeff[i] = SUM(j=0->M-i) Coeff[j] * Coeff[j+i] */ for(i=1; i<=M; i++) { L_acc = 0L; for(j=0; j<=M-i; j++) { L_acc = L_mac(L_acc, Coeff[j], Coeff[j+i]); } L_acc = L_shl(L_acc, sh1); RCoeff[i] = round(L_acc); } *sh_RCoeff = sh1; return; }
void Pre_Process (CodState *coder, Word16 signal[], /* input/output signal */ Word16 lg) { /* length of signal */ Word16 i, x2; Word32 L_tmp; for (i = 0; i < lg; i++) { x2 = coder->x1; coder->x1 = coder->x0; coder->x0 = signal[i]; /* y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b140[2]*x[i-2]/2 */ /* + a[1]*y[i-1] + a[2] * y[i-2]; */ L_tmp = Mpy_32_16 (coder->y1_hi, coder->y1_lo, a140[1]); L_tmp = L_add (L_tmp, Mpy_32_16 (coder->y2_hi, coder->y2_lo, a140[2])); L_tmp = L_mac (L_tmp, coder->x0, b140[0]); L_tmp = L_mac (L_tmp, coder->x1, b140[1]); L_tmp = L_mac (L_tmp, x2, b140[2]); L_tmp = L_shl (L_tmp, 3); /* Q28 --> Q31 (Q12 --> Q15) */ signal[i] = wround (L_tmp); coder->y2_hi = coder->y1_hi; coder->y2_lo = coder->y1_lo; L_Extract (L_tmp, &coder->y1_hi, &coder->y1_lo); } return; }
void Deemph_32_( Word16 x_hi[], /* (i) : input signal (bit31..16) */ Word16 x_lo[], /* (i) : input signal (bit15..4) */ Word16 y[], /* (o) : output signal (x16) */ Word16 mu, /* (i) Q15 : deemphasis factor */ Word16 L, /* (i) : vector size */ Word16 * mem /* (i/o) : memory (y[-1]) */ ) { Word16 i; Word32 L_tmp; /* L_tmp = hi<<16 + lo<<4 */ L_tmp = (Word32)x_hi[0] << 16; L_tmp = L_tmp + ((Word32)x_lo[0] << 4); L_tmp = L_shl(L_tmp, 4); L_tmp = L_mac(L_tmp, *mem, mu); /* saturation can occur here */ y[0] = round16(L_tmp); for (i = 1; i < L; i++) { L_tmp = (Word32)x_hi[i] << 16; L_tmp = L_tmp + ((Word32)x_lo[i] << 4); L_tmp = L_shl(L_tmp, 4); L_tmp = L_mac(L_tmp, y[i - 1], mu); /* saturation can occur here */ y[i] = round16(L_tmp); } *mem = y[L - 1]; return; }
/*-----------------------------------------------------* * Function Autocorr() * * * * Compute autocorrelations of signal with windowing * * * *-----------------------------------------------------*/ void Autocorr( Word16 x[], /* (i) : Input signal */ Word16 m, /* (i) : LPC order */ Word16 r_h[], /* (o) : Autocorrelations (msb) */ Word16 r_l[] /* (o) : Autocorrelations (lsb) */ ) { Word16 i, j, norm; Word16 y[L_WINDOW]; Word32 sum; extern Flag Overflow; /* Windowing of signal */ for(i=0; i<L_WINDOW; i++) { y[i] = mult_r(x[i], hamwindow[i]); } /* Compute r[0] and test for overflow */ do { Overflow = 0; sum = 1; /* Avoid case of all zeros */ for(i=0; i<L_WINDOW; i++) sum = L_mac(sum, y[i], y[i]); /* If overflow divide y[] by 4 */ if(Overflow != 0) { for(i=0; i<L_WINDOW; i++) { y[i] = shr(y[i], 2); } } }while (Overflow != 0); /* Normalization of r[0] */ norm = norm_l(sum); sum = L_shl(sum, norm); L_Extract(sum, &r_h[0], &r_l[0]); /* Put in DPF format (see oper_32b) */ /* r[1] to r[m] */ for (i = 1; i <= m; i++) { sum = 0; for(j=0; j<L_WINDOW-i; j++) sum = L_mac(sum, y[j], y[j+i]); sum = L_shl(sum, norm); L_Extract(sum, &r_h[i], &r_l[i]); } return; }
static Word16 Lag_max( /* output: lag found */ Word16 signal[], /* input : signal used to compute the open loop pitch */ Word16 L_frame, /* input : length of frame to compute pitch */ Word16 lag_max, /* input : maximum lag */ Word16 lag_min, /* input : minimum lag */ Word16 *cor_max) /* output: normalized correlation of selected lag */ { Word16 i, j; Word16 *p, *p1; Word32 max, t0, L_temp; Word16 max_h, max_l, ener_h, ener_l; Word16 p_max; max = MIN_32; /* initialization used only to suppress Microsoft Visual C++ warnings */ p_max = lag_max; for (i = lag_max; i >= lag_min; i--) { p = signal; p1 = &signal[-i]; t0 = 0; for (j=0; j<L_frame; j++, p++, p1++) t0 = L_mac(t0, *p, *p1); L_temp = L_sub(t0,max); if (L_temp >= 0L) { max = t0; p_max = i; } } /* compute energy */ t0 = 0; p = &signal[-p_max]; for(i=0; i<L_frame; i++, p++) t0 = L_mac(t0, *p, *p); /* 1/sqrt(energy), result in Q30 */ t0 = Inv_sqrt(t0); /* max = max/sqrt(energy) */ /* This result will always be on 16 bits !! */ L_Extract(max, &max_h, &max_l); L_Extract(t0, &ener_h, &ener_l); t0 = Mpy_32(max_h, max_l, ener_h, ener_l); *cor_max = extract_l(t0); return(p_max); }
void Corr_xy2( Word16 xn[], /* (i) Q0 :Target vector. */ Word16 y1[], /* (i) Q0 :Adaptive codebook. */ Word16 y2[], /* (i) Q12 :Filtered innovative vector. */ Word16 g_coeff[], /* (o) Q[exp]:Correlations between xn,y1,y2 */ Word16 exp_g_coeff[] /* (o) :Q-format of g_coeff[] */ ) { Word16 i,exp; Word16 exp_y2y2,exp_xny2,exp_y1y2; Word16 y2y2, xny2, y1y2; Word32 L_acc; Word16 scaled_y2[L_SUBFR]; /* Q9 */ /*------------------------------------------------------------------* * Scale down y2[] from Q12 to Q9 to avoid overflow * *------------------------------------------------------------------*/ for(i=0; i<L_SUBFR; i++) { scaled_y2[i] = shr(y2[i], 3); } /* Compute scalar product <y2[],y2[]> */ L_acc = 1; /* Avoid case of all zeros */ for(i=0; i<L_SUBFR; i++) L_acc = L_mac(L_acc, scaled_y2[i], scaled_y2[i]); /* L_acc:Q19 */ exp = norm_l(L_acc); y2y2 = round( L_shl(L_acc, exp) ); exp_y2y2 = add(exp, 19-16); /* Q[19+exp-16] */ g_coeff[2] = y2y2; exp_g_coeff[2] = exp_y2y2; /* Compute scalar product <xn[],y2[]> */ L_acc = 1; /* Avoid case of all zeros */ for(i=0; i<L_SUBFR; i++) L_acc = L_mac(L_acc, xn[i], scaled_y2[i]); /* L_acc:Q10 */ exp = norm_l(L_acc); xny2 = round( L_shl(L_acc, exp) ); exp_xny2 = add(exp, 10-16); /* Q[10+exp-16] */ g_coeff[3] = negate(xny2); exp_g_coeff[3] = sub(exp_xny2,1); /* -2<xn,y2> */ /* Compute scalar product <y1[],y2[]> */ L_acc = 1; /* Avoid case of all zeros */ for(i=0; i<L_SUBFR; i++) L_acc = L_mac(L_acc, y1[i], scaled_y2[i]); /* L_acc:Q10 */ exp = norm_l(L_acc); y1y2 = round( L_shl(L_acc, exp) ); exp_y1y2 = add(exp, 10-16); /* Q[10+exp-16] */ g_coeff[4] = y1y2; exp_g_coeff[4] = sub(exp_y1y2,1); ; /* 2<y1,y2> */ return; }
/*-------------------------------------------------------------------* * Function set_sign() * * ~~~~~~~~~~~~~~~~~~~~ * * Set the sign of each pulse position. * *-------------------------------------------------------------------*/ static void set_sign( Word16 fac_cn, /* (i) Q15: residual weight for sign determination */ Word16 cn[], /* (i) Q0 : residual after long term prediction */ Word16 dn[], /* (i) Q0 : correlation between target and h[] */ Word16 sign[], /* (o) Q15: sign vector (sign of each position) */ Word16 inv_sign[], /* (o) Q15: inverse of sign[] */ Word16 pos_max[], /* (o) : pos of max of correlation */ Word32 corr[] /* (o) : correlation of each track */ ) { Word16 i, k, pos, k_cn, k_dn, val; Word32 s, max; /* calculate energy for normalization of cn[] and dn[] */ s = 0; for (i=0; i<L_SUBFR; i++) s = L_mac(s, cn[i], cn[i]); if (s < 512) s = 512; s = Inv_sqrt(s); k_cn = extract_h(L_shl(s, 5)); /* k_cn = 11..23170 */ k_cn = mult(k_cn, fac_cn); s = 0; for (i=0; i<L_SUBFR; i++) s = L_mac(s, dn[i], dn[i]); if (s < 512) s = 512; s = Inv_sqrt(s); k_dn = extract_h(L_shl(s, 5)); /* k_dn = 11..23170 */ /* set sign according to en[] = k_cn*cn[] + k_dn*dn[] */ /* find position of maximum of correlation in each track */ for (k=0; k<NB_TRACK; k++) { max = -1; for (i=k; i<L_SUBFR; i+=STEP) { val = dn[i]; s = L_mac(L_mult(k_cn, cn[i]), k_dn, val); if (s >= 0) { sign[i] = 32767L; /* sign = +1 (Q15) */ inv_sign[i] = -32768L; } else { sign[i] = -32768L; /* sign = -1 (Q15) */ inv_sign[i] = 32767L; val = negate(val); } dn[i] = val; /* modify dn[] according to the fixed sign */ s = L_abs(s); if (s > max) { max = s; pos = i; } } pos_max[k] = pos; corr[k] = max; } return; }
Word32 Mpy_32(Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2) { Word32 L_32; L_32 = L_mult(hi1, hi2); L_32 = L_mac(L_32, mult(hi1, lo2) , 1); L_32 = L_mac(L_32, mult(lo1, hi2) , 1); return( L_32 ); }
static Word16 Vq_subvec (/* o : quantization index, Q0 */ Word16 *lsf_r1, /* i : 1st LSF residual vector, Q15 */ Word16 *lsf_r2, /* i : 2nd LSF residual vector, Q15 */ const Word16 *dico, /* i : quantization codebook, Q15 */ Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ Word16 dico_size /* i : size of quantization codebook, Q0 */ ) { Word16 index = 0; /* initialization only needed to keep gcc silent */ Word16 i, temp; const Word16 *p_dico; Word32 dist_min, dist; dist_min = MAX_32; move32 (); p_dico = dico; move16 (); for (i = 0; i < dico_size; i++) { temp = sub (lsf_r1[0], *p_dico++); temp = mult (wf1[0], temp); dist = L_mult (temp, temp); temp = sub (lsf_r1[1], *p_dico++); temp = mult (wf1[1], temp); dist = L_mac (dist, temp, temp); temp = sub (lsf_r2[0], *p_dico++); temp = mult (wf2[0], temp); dist = L_mac (dist, temp, temp); temp = sub (lsf_r2[1], *p_dico++); temp = mult (wf2[1], temp); dist = L_mac (dist, temp, temp); test (); if (L_sub (dist, dist_min) < (Word32) 0) { dist_min = dist; move32 (); index = i; move16 (); } } /* Reading the selected vector */ p_dico = &dico[shl (index, 2)]; move16 (); lsf_r1[0] = *p_dico++; move16 (); lsf_r1[1] = *p_dico++; move16 (); lsf_r2[0] = *p_dico++; move16 (); lsf_r2[1] = *p_dico++; move16 (); return index; }
void Post_Process( Word16 signal[], /* input/output signal */ Word16 lg) /* length of signal */ { Word16 i, x2; Word32 L_tmp; Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1; y2_hi = pg729dec->ppost_pro->y2_hi; y2_lo = pg729dec->ppost_pro->y2_lo; y1_hi = pg729dec->ppost_pro->y1_hi; y1_lo = pg729dec->ppost_pro->y1_lo; x0 = pg729dec->ppost_pro->x0; x1 = pg729dec->ppost_pro->x1; for(i=0; i<lg; i++) { x2 = x1; x1 = x0; x0 = signal[i]; /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */ /* + a[1]*y[i-1] + a[2] * y[i-2]; */ L_tmp = Mpy_32_16(y1_hi, y1_lo, a100[1]); L_tmp = L_add(L_tmp, Mpy_32_16(y2_hi, y2_lo, a100[2])); L_tmp = L_mac(L_tmp, x0, b100[0]); L_tmp = L_mac(L_tmp, x1, b100[1]); L_tmp = L_mac(L_tmp, x2, b100[2]); L_tmp = L_shl(L_tmp, 2); /* Q29 --> Q31 (Q13 --> Q15) */ /* Multiplication by two of output speech with saturation. */ signal[i] = round(L_shl(L_tmp, 1)); y2_hi = y1_hi; y2_lo = y1_lo; L_Extract(L_tmp, &y1_hi, &y1_lo); } pg729dec->ppost_pro->y2_hi = y2_hi; pg729dec->ppost_pro->y2_lo = y2_lo; pg729dec->ppost_pro->y1_hi = y1_hi; pg729dec->ppost_pro->y1_lo = y1_lo; pg729dec->ppost_pro->x0 = x0; pg729dec->ppost_pro->x1 = x1; return; }
void rmlt_coefs_to_samples(int16_t coefs[], int16_t old_samples[], int16_t out_samples[], int dct_length, int16_t mag_shift) { int i; int half_dct_length; int last; int16_t new_samples[MAX_DCT_LENGTH]; const int16_t *win; int32_t sum; half_dct_length = dct_length >> 1; /* Perform a Type IV (inverse) DCT on the coefficients */ dct_type_iv_s(coefs, new_samples, dct_length); if (mag_shift > 0) { for (i = 0; i < dct_length; i++) new_samples[i] = shr(new_samples[i], mag_shift); } else if (mag_shift < 0) { mag_shift = negate(mag_shift); for (i = 0; i < dct_length; i++) new_samples[i] = shl(new_samples[i], mag_shift); } win = (dct_length == DCT_LENGTH) ? rmlt_to_samples_window : max_rmlt_to_samples_window; last = half_dct_length - 1; for (i = 0; i < half_dct_length; i++) { /* Get the first half of the windowed samples */ sum = L_mult(win[i], new_samples[last - i]); sum = L_mac(sum, win[dct_length - i - 1], old_samples[i]); out_samples[i] = xround(L_shl(sum, 2)); /* Get the second half of the windowed samples */ sum = L_mult(win[half_dct_length + i], new_samples[i]); sum = L_mac(sum, negate(win[last - i]), old_samples[last - i]); out_samples[half_dct_length + i] = xround(L_shl(sum, 2)); } /* Save the second half of the new samples for next time, when they will be the old samples. */ vec_copyi16(old_samples, &new_samples[half_dct_length], half_dct_length); }
/*-------------------------------------------------------------------* * Function cor_h_vec() * * ~~~~~~~~~~~~~~~~~~~~~ * * Compute correlations of h[] with vec[] for the specified track. * *-------------------------------------------------------------------* *-------------------------------------------------------------------*/ static void cor_h_vec( Word16 h[], /* (i) scaled impulse response */ Word16 vec[], /* (i) vector to correlate with h[] */ Word16 track, /* (i) track to use */ Word16 sign[], /* (i) sign vector */ Word16 rrixix[][NB_POS], /* (i) correlation of h[x] with h[x] */ Word16 cor[] /* (o) result of correlation (NB_POS elements) */ ) { Word16 i, j, pos; Word16 *p0, *p1, *p2; Word32 s; p0 = rrixix[track]; pos = track; for (i=0; i<NB_POS; i++, pos+=STEP) { s = 0; p1 = h; p2 = &vec[pos]; for (j=pos; j<L_SUBFR; j++) { s = L_mac(s, *p1, *p2); p1++; p2++; } cor[i] = add(mult(round(s), sign[pos]), *p0++); } return; }
void Gp_clip_test_isf( Word16 isf[], /* (i) : isf values (in frequency domain) */ Word16 mem[] /* (i/o) : memory of gain of pitch clipping algorithm */ ) { Word16 dist, dist_min; Word32 i; dist_min = vo_sub(isf[1], isf[0]); for (i = 2; i < M - 1; i++) { dist = vo_sub(isf[i], isf[i - 1]); if(dist < dist_min) { dist_min = dist; } } dist = extract_h(L_mac(vo_L_mult(26214, mem[0]), 6554, dist_min)); if (dist > DIST_ISF_MAX) { dist = DIST_ISF_MAX; } mem[0] = dist; return; }
Word32 L_Comp(Word16 hi, Word16 lo) { Word32 L_32; L_32 = L_deposit_h(hi); return( L_mac(L_32, lo, 1)); /* = hi<<16 + lo<<1 */ }
void Pred_lt4( Word16 exc[], /* in/out: excitation buffer */ Word16 T0, /* input : integer pitch lag */ Word16 frac, /* input : fraction of lag */ Word16 L_subfr /* input : subframe size */ ) { Word16 i, j, k, *x; Word32 L_sum; x = &exc[-T0]; // frac = -frac; /* frac=0,1,2,3 */ if (frac >= 0) { frac = frac - UP_SAMP; x--; } x = x - L_INTERPOL2 + 1; for (j = 0; j < L_subfr; j++) { L_sum = 0L; for (i = 0, k = UP_SAMP-1+frac; i < 2*L_INTERPOL2; i++, k += UP_SAMP) { L_sum = L_mac(L_sum, x[i], inter4_2[k]); } L_sum = L_shl(L_sum, 1); exc[j] = round16(L_sum); x++; } return; }
void Lsp_pre_select( Word16 rbuf[], /* (i) Q13 : target vetor */ Word16 lspcb1[][M], /* (i) Q13 : first stage LSP codebook */ Word16 *cand /* (o) : selected code */ ) { Word16 i, j; Word16 tmp; /* Q13 */ Word32 L_dmin; /* Q26 */ Word32 L_tmp; /* Q26 */ Word32 L_temp; /* avoid the worst case. (all over flow) */ *cand = 0; L_dmin = MAX_32; for ( i = 0 ; i < NC0 ; i++ ) { L_tmp = 0; for ( j = 0 ; j < M ; j++ ) { tmp = sub(rbuf[j], lspcb1[i][j]); L_tmp = L_mac( L_tmp, tmp, tmp ); } L_temp = L_sub(L_tmp,L_dmin); if ( L_temp< 0L) { L_dmin = L_tmp; *cand = i; } } return; }
void Lsp_get_tdist( Word16 wegt[], /* (i) norm: weight coef. */ Word16 buf[], /* (i) Q13 : candidate LSP vector */ Word32 *L_tdist, /* (o) Q27 : distortion */ Word16 rbuf[], /* (i) Q13 : target vector */ Word16 fg_sum[] /* (i) Q15 : present MA prediction coef. */ ) { Word16 j; Word16 tmp, tmp2; /* Q13 */ Word32 L_acc; /* Q25 */ *L_tdist = 0; for ( j = 0 ; j < M ; j++ ) { /* tmp = (buf - rbuf)*fg_sum */ tmp = sub( buf[j], rbuf[j] ); tmp = mult( tmp, fg_sum[j] ); /* *L_tdist += wegt * tmp * tmp */ L_acc = L_mult( wegt[j], tmp ); tmp2 = extract_h( L_shl( L_acc, 4 ) ); *L_tdist = L_mac( *L_tdist, tmp2, tmp ); } return; }
void Log2( Word32 x, /* (i) input */ Word16 *int_comp, /* Q0 integer part */ Word16 *frac_comp /* Q15 fractional part */ ) { Word16 exp, idx_man, sub_man, sub_tab; Word32 a0; if(x <= 0){ *int_comp = 0; *frac_comp = 0; } else{ exp = norm_l(x); // normalization a0 = L_shl(x, exp); // Q30 mantissa, i.e. 1.xxx Q30 /* use table look-up of man in [1.0, 2.0[ Q30 */ a0 = L_shr(L_sub(a0, (Word32)0x40000000), 8); // Q16 index into table - note zero'ing of leading 1 idx_man = extract_h(a0); // Q0 index into table sub_man = extract_l(L_shr((a0 & 0xFFFF), 1)); // Q15 fractional sub_man a0 = L_deposit_h(tablog[idx_man]); // Q31 sub_tab = sub(tablog[idx_man+1], tablog[idx_man]); // Q15 a0 = L_mac(a0, sub_man, sub_tab); // Q31 *frac_comp = intround(a0); // Q15 *int_comp = sub(30, exp); // Q0 } return; }
static void cor_h_x_e( Word16 h[], /* (i) Q12 : impulse response of weighted synthesis filter */ Word16 x[], /* (i) Q0 : correlation between target and h[] */ Word16 dn[] /* (o) Q0 : correlation between target and h[] */ ) { Word16 i, j, k; Word32 s, y32[L_SUBFR], max, tot, L_tmp; /* first keep the result on 32 bits and find absolute maximum */ tot = 5; for (k=0; k<NB_TRACK; k++) { max = 0; for (i=k; i<L_SUBFR; i+=STEP) { s = 0; for (j=i; j<L_SUBFR; j++) s = L_mac(s, x[j], h[j-i]); y32[i] = s; s = L_abs(s); L_tmp = L_sub(s, max); if (L_tmp > (Word32)0) max = s; } tot = L_add(tot, L_shr(max, 1)); /* tot += (2.0 x max) / 4.0 */ } /* Find the number of right shifts to do on y32[] so that */ /* 2.0 x sumation of all max of dn[] in each track not saturate. */ j = sub(norm_l(tot), 2); /* multiply tot by 4 */ for (i=0; i<L_SUBFR; i++) { dn[i] = round(L_shl(y32[i], j)); } return; }
/*---------------------------------------------------------------------------- * filt_plt - ltp postfilter *---------------------------------------------------------------------------- */ static void filt_plt( Word16 *s_in, /* input : input signal with past*/ Word16 *s_ltp, /* input : filtered signal with gain 1 */ Word16 *s_out, /* output: output signal */ Word16 gain_plt /* input : filter gain */ ) { /* Local variables */ int n; Word32 L_acc; Word16 gain_plt_1; gain_plt_1 = sub(32767, gain_plt); gain_plt_1 = add(gain_plt_1, 1); /* 2**15 (1 - g) */ for(n=0; n<L_SUBFR; n++) { /* s_out(n) = gain_plt x s_in(n) + gain_plt_1 x s_ltp(n) */ L_acc = L_mult(gain_plt, s_in[n]); L_acc = L_mac(L_acc, gain_plt_1, s_ltp[n]); /* no overflow */ s_out[n] = round(L_acc); } return; }
Word32 Mpy_32_16(Word16 hi, Word16 lo, Word16 n) { Word32 L_32; L_32 = L_mult(hi, n); L_32 = L_mac(L_32, mult(lo, n) , 1); return( L_32 ); }