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; }
void WebRtcG729fix_Log2( int32_t L_x, /* (i) Q0 : input value */ int16_t *exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ int16_t *fraction /* (o) Q15: Fractional part of Log2. (range: 0<=val<1) */ ) { int16_t exp, i, a, tmp; int32_t L_y; if( L_x <= (int32_t)0 ) { *exponent = 0; *fraction = 0; return; } exp = WebRtcSpl_NormW32(L_x); L_x = L_shl(L_x, exp ); /* L_x is normalized */ *exponent = WebRtcSpl_SubSatW16(30, exp); L_x = L_shr(L_x, 9); i = extract_h(L_x); /* Extract b25-b31 */ L_x = L_shr(L_x, 1); a = extract_l(L_x); /* Extract b10-b24 of fraction */ a = a & (int16_t)0x7fff; i = WebRtcSpl_SubSatW16(i, 32); L_y = L_deposit_h(WebRtcG729fix_tablog[i]); /* tablog[i] << 16 */ tmp = WebRtcSpl_SubSatW16(WebRtcG729fix_tablog[i], WebRtcG729fix_tablog[i+1]); /* tablog[i] - tablog[i+1] */ L_y = L_msu(L_y, tmp, a); /* L_y -= tmp*a*2 */ *fraction = extract_h( L_y); }
int32_t WebRtcG729fix_Inv_sqrt( /* (o) Q30 : output value (range: 0<=val<1) */ int32_t L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ ) { int16_t exp, i, a, tmp; int32_t L_y; if( L_x <= (int32_t)0) return ( (int32_t)0x3fffffffL); exp = WebRtcSpl_NormW32(L_x); L_x = L_shl(L_x, exp ); /* L_x is normalize */ exp = WebRtcSpl_SubSatW16(30, exp); if( (exp & 1) == 0 ) /* If exponent even -> shift right */ L_x = L_shr(L_x, 1); exp = shr(exp, 1); exp = WebRtcSpl_AddSatW16(exp, 1); L_x = L_shr(L_x, 9); i = extract_h(L_x); /* Extract b25-b31 */ L_x = L_shr(L_x, 1); a = extract_l(L_x); /* Extract b10-b24 */ a = a & (int16_t)0x7fff; i = WebRtcSpl_SubSatW16(i, 16); L_y = L_deposit_h(WebRtcG729fix_tabsqr[i]); /* tabsqr[i] << 16 */ tmp = WebRtcSpl_SubSatW16(WebRtcG729fix_tabsqr[i], WebRtcG729fix_tabsqr[i+1]); /* tabsqr[i] - tabsqr[i+1]) */ L_y = L_msu(L_y, tmp, a); /* L_y -= tmp*a*2 */ L_y = L_shr(L_y, exp); /* denormalization */ return(L_y); }
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; }
Word32 Inv_sqrt( /* (o) Q30 : output value (range: 0<=val<1) */ Word32 L_x /* (i) Q0 : input value (range: 0<=val<=7fffffff) */ ) { Word16 exp, i, a, tmp; Word32 L_y; if( L_x <= (Word32)0) return ( (Word32)0x3fffffffL); exp = norm_l(L_x); L_x = L_shl(L_x, exp ); /* L_x is normalize */ exp = sub(30, exp); if( (exp & 1) == 0 ) /* If exponent even -> shift right */ L_x = L_shr(L_x, 1); exp = shr(exp, 1); exp = add(exp, 1); L_x = L_shr(L_x, 9); i = extract_h(L_x); /* Extract b25-b31 */ L_x = L_shr(L_x, 1); a = extract_l(L_x); /* Extract b10-b24 */ a = a & (Word16)0x7fff; i = sub(i, 16); L_y = L_deposit_h(tabsqr[i]); /* tabsqr[i] << 16 */ tmp = sub(tabsqr[i], tabsqr[i+1]); /* tabsqr[i] - tabsqr[i+1]) */ L_y = L_msu(L_y, tmp, a); /* L_y -= tmp*a*2 */ L_y = L_shr(L_y, exp); /* denormalization */ return(L_y); }
/*---------------------------------------------------------------------------- * select_ltp : selects best of (gain1, gain2) * with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1 * and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2 *---------------------------------------------------------------------------- */ static Word16 select_ltp( /* output : 1 = 1st gain, 2 = 2nd gain */ Word16 num1, /* input : numerator of gain1 */ Word16 den1, /* input : denominator of gain1 */ Word16 sh_num1, /* input : just. factor for num1 */ Word16 sh_den1, /* input : just. factor for den1 */ Word16 num2, /* input : numerator of gain2 */ Word16 den2, /* input : denominator of gain2 */ Word16 sh_num2, /* input : just. factor for num2 */ Word16 sh_den2) /* input : just. factor for den2 */ { Word32 L_temp1, L_temp2; Word16 temp1, temp2; Word16 hi, lo; Word32 L_temp; if(den2 == 0) { return(1); } /* compares criteria = num**2/den */ L_temp1 = L_mult(num1, num1); L_Extract(L_temp1, &hi, &lo); L_temp1 = Mpy_32_16(hi, lo, den2); L_temp2 = L_mult(num2, num2); L_Extract(L_temp2, &hi, &lo); L_temp2 = Mpy_32_16(hi, lo, den1); /* temp1 = sh_den2 + 2 * sh_num1 */ temp1 = shl(sh_num1, 1); temp1 = add(temp1, sh_den2); /* temp2 = sh_den1 + 2 * sh_num2; */ temp2 = shl(sh_num2, 1); temp2 = add(temp2, sh_den1); if(sub(temp2 ,temp1)>0) { temp2 = sub(temp2, temp1); L_temp1 = L_shr(L_temp1, temp2); /* temp2 > 0 */ } else { if(sub(temp1 ,temp2) >0) { temp1 = sub(temp1, temp2); L_temp2 = L_shr(L_temp2, temp1); /* temp1 > 0 */ } } L_temp = L_sub(L_temp2,L_temp1); if(L_temp>0L) { return(2); } else { return(1); } }
void Cor_h_X( Word16 h[], /* (i) Q12 :Impulse response of filters */ Word16 X[], /* (i) :Target vector */ Word16 D[] /* (o) :Correlations between h[] and D[] */ /* Normalized to 13 bits */ ) { Word16 i, j; Word32 s, max, L_temp; Word32 y32[L_SUBFR]; /* first keep the result on 32 bits and find absolute maximum */ max = 0; for (i = 0; i < L_SUBFR; i++) { 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_temp =L_sub(s,max); if(L_temp>0L) { max = s; } } /* Find the number of right shifts to do on y32[] */ /* so that maximum is on 13 bits */ j = norm_l(max); if( sub(j,16) > 0) { j = 16; } j = sub(18, j); if(j>=0) { for(i=0; i<L_SUBFR; i++) { D[i] = extract_l( L_shr(y32[i], j) ); } } else { Word16 pj = abs_s(j); for(i=0; i<L_SUBFR; i++) { D[i] = extract_l( L_shr(y32[i], pj) ); } } return; }
/* * The decimation-in-time complex FFT is implemented below. * The input complex numbers are presented as real part followed by * imaginary part for each sample. The counters are therefore * incremented by two to access the complex valued samples. */ void r_fft(Word16 * farray_ptr, Flag *pOverflow) { Word16 ftmp1_real; Word16 ftmp1_imag; Word16 ftmp2_real; Word16 ftmp2_imag; Word32 Lftmp1_real; Word32 Lftmp1_imag; Word16 i; Word16 j; Word32 Ltmp1; /* Perform the complex FFT */ c_fft(farray_ptr, pOverflow); /* First, handle the DC and foldover frequencies */ ftmp1_real = *farray_ptr; ftmp2_real = *(farray_ptr + 1); *farray_ptr = add(ftmp1_real, ftmp2_real, pOverflow); *(farray_ptr + 1) = sub(ftmp1_real, ftmp2_real, pOverflow); /* Now, handle the remaining positive frequencies */ for (i = 2, j = SIZE - i; i <= SIZE_BY_TWO; i = i + 2, j = SIZE - i) { ftmp1_real = add(*(farray_ptr + i), *(farray_ptr + j), pOverflow); ftmp1_imag = sub(*(farray_ptr + i + 1), *(farray_ptr + j + 1), pOverflow); ftmp2_real = add(*(farray_ptr + i + 1), *(farray_ptr + j + 1), pOverflow); ftmp2_imag = sub(*(farray_ptr + j), *(farray_ptr + i), pOverflow); Lftmp1_real = L_deposit_h(ftmp1_real); Lftmp1_imag = L_deposit_h(ftmp1_imag); Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[i], pOverflow); Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[i + 1], pOverflow); *(farray_ptr + i) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); Ltmp1 = L_mac(Lftmp1_imag, ftmp2_imag, phs_tbl[i], pOverflow); Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[i + 1], pOverflow); *(farray_ptr + i + 1) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, phs_tbl[j], pOverflow); Ltmp1 = L_mac(Ltmp1, ftmp2_imag, phs_tbl[j + 1], pOverflow); *(farray_ptr + j) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); Ltmp1 = L_negate(Lftmp1_imag); Ltmp1 = L_msu(Ltmp1, ftmp2_imag, phs_tbl[j], pOverflow); Ltmp1 = L_mac(Ltmp1, ftmp2_real, phs_tbl[j + 1], pOverflow); *(farray_ptr + j + 1) = pv_round(L_shr(Ltmp1, 1, pOverflow), pOverflow); } } /* end r_fft () */
Word32 sqrt_l_exp( /* o : output value, Q31 */ Word32 L_x, /* i : input value, Q31 */ Word16 *pExp, /* o : right shift to be applied to result, Q1 */ Flag *pOverflow /* i : pointer to overflow flag */ ) { Word16 e; Word16 i; Word16 a; Word16 tmp; Word32 L_y; /* y = sqrt(x) x = f * 2^-e, 0.5 <= f < 1 (normalization) y = sqrt(f) * 2^(-e/2) a) e = 2k --> y = sqrt(f) * 2^-k (k = e div 2, 0.707 <= sqrt(f) < 1) b) e = 2k+1 --> y = sqrt(f/2) * 2^-k (k = e div 2, 0.5 <= sqrt(f/2) < 0.707) */ if (L_x <= (Word32) 0) { *pExp = 0; return (Word32) 0; } e = norm_l(L_x) & 0xFFFE; /* get next lower EVEN norm. exp */ L_x = L_shl(L_x, e, pOverflow); /* L_x is normalized to [0.25..1) */ *pExp = e; /* return 2*exponent (or Q1) */ L_x = L_shr(L_x, 9, pOverflow); i = (Word16)(L_x >> 16); /* Extract b25-b31, 16 <= i <= 63 because of normalization */ L_x = L_shr(L_x, 1, pOverflow); a = (Word16)(L_x); /* Extract b10-b24 */ a &= (Word16) 0x7fff; i = sub(i, 16, pOverflow); /* 0 <= i <= 47 */ L_y = L_deposit_h(sqrt_l_tbl[i]); /* sqrt_l_tbl[i] << 16 */ /* sqrt_l_tbl[i] - sqrt_l_tbl[i+1]) */ tmp = sub(sqrt_l_tbl[i], sqrt_l_tbl[i + 1], pOverflow); L_y = L_msu(L_y, tmp, a, pOverflow); /* L_y -= tmp*a*2 */ /* L_y = L_shr (L_y, *exp); */ /* denormalization done by caller */ return (L_y); }
/*---------------------------------------------------------------------------- * 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; }
int16_t WebRtcG729fix_Random(int16_t *seed) { /* seed = seed*31821 + 13849; */ *seed = extract_l(WebRtcSpl_AddSatW32(L_shr(L_mult(*seed, 31821), 1), 13849L)); return(*seed); }
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); }
void WebRtcG729fix_Lsp_lsf2( int16_t lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ int16_t lsf[], /* (o) Q13 : lsf[m] (range: 0.0<=val<PI) */ int16_t m /* (i) : LPC order */ ) { int16_t i, ind; int16_t offset; /* in Q15 */ int16_t freq; /* normalized frequency in Q16 */ int32_t L_tmp; ind = 63; /* begin at end of table2 -1 */ for(i= m-(int16_t)1; i >= 0; i--) { /* find value in table2 that is just greater than lsp[i] */ while( WebRtcSpl_SubSatW16(WebRtcG729fix_table2[ind], lsp[i]) < 0 ) { ind = WebRtcSpl_SubSatW16(ind,1); if ( ind <= 0 ) break; } offset = WebRtcSpl_SubSatW16(lsp[i], WebRtcG729fix_table2[ind]); /* acos(lsp[i])= ind*512 + (slope_acos[ind]*offset >> 11) */ L_tmp = L_mult( WebRtcG729fix_slope_acos[ind], offset ); /* L_tmp in Q28 */ freq = WebRtcSpl_AddSatW16(shl(ind, 9), extract_l(L_shr(L_tmp, 12))); lsf[i] = mult(freq, 25736); /* 25736: 2.0*PI in Q12 */ } }
void WebRtcG729fix_Lsf_lsp2( int16_t lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=val<PI) */ int16_t lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */ int16_t m /* (i) : LPC order */ ) { int16_t i, ind; int16_t offset; /* in Q8 */ int16_t freq; /* normalized frequency in Q15 */ int32_t L_tmp; for(i=0; i<m; i++) { /* freq = abs_s(freq);*/ freq = mult(lsf[i], 20861); /* 20861: 1.0/(2.0*PI) in Q17 */ ind = shr(freq, 8); /* ind = b8-b15 of freq */ offset = freq & (int16_t)0x00ff; /* offset = b0-b7 of freq */ if (ind > 63){ ind = 63; /* 0 <= ind <= 63 */ } /* lsp[i] = table2[ind]+ (slope_cos[ind]*offset >> 12) */ L_tmp = L_mult(WebRtcG729fix_slope_cos[ind], offset); /* L_tmp in Q28 */ lsp[i] = WebRtcSpl_AddSatW16(WebRtcG729fix_table2[ind], extract_l(L_shr(L_tmp, 13))); } }
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; }
void SynthesisFilter( short *output, short *input, short *coef, short *memory, short order, short length ) { register short i, j; long acc; /* iir filter for each subframe */ for (i = 0; i < length; i++) { acc = L_deposit_h(*input++); acc = L_shr(acc, 3); for (j = order - 1; j > 0; j--) { /* acc = L_sub(acc, L_mult(memory[j], coef[j])); */ acc = L_msu(acc, memory[j], coef[j]); memory[j] = memory[j - 1]; } /* acc = L_sub(acc, L_mult(memory[0], coef[0])); */ acc = L_msu(acc, memory[0], coef[0]); acc = L_shl(acc, 3); *output++ = round(acc); memory[0] = round(acc); } }
/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ void d_gain_code( gc_predState *pred_state, /* i/o : MA predictor state */ enum Mode mode, /* i : AMR mode (MR795 or MR122) */ Word16 index, /* i : received quantization index */ Word16 code[], /* i : innovation codevector */ Word16 *gain_code, /* o : decoded innovation gain */ Flag *pOverflow ) { Word16 gcode0, exp, frac; const Word16 *p; Word16 qua_ener_MR122, qua_ener; Word16 exp_inn_en; Word16 frac_inn_en; Word32 L_tmp; Word16 tbl_tmp; Word16 temp; /*-------------- Decode codebook gain ---------------*/ /*-------------------------------------------------------------------* * predict codebook gain * * ~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow2(int(d)+frac(d)) * * = 2^exp + 2^frac * * * *-------------------------------------------------------------------*/ gc_pred(pred_state, mode, code, &exp, &frac, &exp_inn_en, &frac_inn_en, pOverflow); tbl_tmp = add(add(index, index, pOverflow), index, pOverflow); p = &qua_gain_code[tbl_tmp]; /* Different scalings between MR122 and the other modes */ temp = sub((Word16)mode, (Word16)MR122, pOverflow); if (temp == 0) { gcode0 = (Word16)(Pow2(exp, frac, pOverflow)); /* predicted gain */ gcode0 = shl(gcode0, 4, pOverflow); *gain_code = shl(mult(gcode0, *p++, pOverflow), 1, pOverflow); } else { gcode0 = (Word16)(Pow2(14, frac, pOverflow)); L_tmp = L_mult(*p++, gcode0, pOverflow); L_tmp = L_shr(L_tmp, sub(9, exp, pOverflow), pOverflow); *gain_code = extract_h(L_tmp); /* Q1 */ } /*-------------------------------------------------------------------* * update table of past quantized energies * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *-------------------------------------------------------------------*/ qua_ener_MR122 = *p++; qua_ener = *p++; gc_pred_update(pred_state, qua_ener_MR122, qua_ener); return; }
void Lsf_lsp2( Word16 lsf[], /* (i) Q13 : lsf[m] (range: 0.0<=val<PI) */ Word16 lsp[], /* (o) Q15 : lsp[m] (range: -1<=val<1) */ Word16 m /* (i) : LPC order */ ) { Word16 i, ind; Word16 offset; /* in Q8 */ Word16 freq; /* normalized frequency in Q15 */ Word32 L_tmp; for(i=0; i<m; i++) { /* freq = abs_s(freq);*/ freq = mult(lsf[i], 20861); /* 20861: 1.0/(2.0*PI) in Q17 */ ind = shr(freq, 8); /* ind = b8-b15 of freq */ offset = freq & (Word16)0x00ff; /* offset = b0-b7 of freq */ if ( sub(ind, 63)>0 ){ ind = 63; /* 0 <= ind <= 63 */ } /* lsp[i] = table2[ind]+ (slope_cos[ind]*offset >> 12) */ L_tmp = L_mult(slope_cos[ind], offset); /* L_tmp in Q28 */ lsp[i] = add(table2[ind], extract_l(L_shr(L_tmp, 13))); } return; }
Word16 Test_Err(Word16 Lag1, Word16 Lag2,ENC_HANDLE *handle) { int i, i1, i2; Word16 zone1, zone2; Word32 Acc, Err_max; Word16 iTest; i2 = Lag2 + ClPitchOrd/2; zone2 = mult( (Word16) i2, (Word16) 1092); i1 = - SubFrLen + 1 + Lag1 - ClPitchOrd/2; if(i1 <= 0) i1 = 1; zone1 = mult( (Word16) i1, (Word16) 1092); Err_max = -1L; for(i=zone2; i>=zone1; i--) { Acc = L_sub(handle->CodStat.Err[i], Err_max); if(Acc > 0L) { Err_max = handle->CodStat.Err[i]; } } Acc = L_sub(Err_max, ThreshErr); if((Acc > 0L) || (handle->CodStat.SinDet < 0 ) ) { iTest = 0; } else { Acc = L_negate(Acc); Acc = L_shr(Acc, DEC); iTest = extract_l(Acc); } return(iTest); }
void Lsp_lsf2( Word16 lsp[], /* (i) Q15 : lsp[m] (range: -1<=val<1) */ Word16 lsf[], /* (o) Q13 : lsf[m] (range: 0.0<=val<PI) */ Word16 m /* (i) : LPC order */ ) { Word16 i, ind; Word16 offset; /* in Q15 */ Word16 freq; /* normalized frequency in Q16 */ Word32 L_tmp; ind = 63; /* begin at end of table2 -1 */ for(i= m-(Word16)1; i >= 0; i--) { /* find value in table2 that is just greater than lsp[i] */ while( sub(table2[ind], lsp[i]) < 0 ) { ind = sub(ind,1); if ( ind <= 0 ) break; } offset = sub(lsp[i], table2[ind]); /* acos(lsp[i])= ind*512 + (slope_acos[ind]*offset >> 11) */ L_tmp = L_mult( slope_acos[ind], offset ); /* L_tmp in Q28 */ freq = add(shl(ind, 9), extract_l(L_shr(L_tmp, 12))); lsf[i] = mult(freq, 25736); /* 25736: 2.0*PI in Q12 */ } return; }
void energy_computation ( Word16 r_h[], Word16 scal_acf, Word16 rvad[], Word16 scal_rvad, Pfloat * acf0, Pfloat * pvad ) { Word16 i, temp, norm_prod; Word32 L_temp; /* r[0] is always greater than zero (no need to test for r[0] == 0) */ /* Computation of acf0 (exponent and mantissa) */ acf0->e = sub (32, scal_acf); acf0->m = r_h[0] & 0x7ff8; /* Computation of pvad (exponent and mantissa) */ pvad->e = add (acf0->e, 14); pvad->e = sub (pvad->e, scal_rvad); L_temp = 0L; for (i = 1; i <= 8; i++) { temp = shr (r_h[i], 3); L_temp = L_mac (L_temp, temp, rvad[i]); } temp = shr (r_h[0], 3); L_temp = L_add (L_temp, L_shr (L_mult (temp, rvad[0]), 1)); if (L_temp <= 0L) { L_temp = 1L; } norm_prod = norm_l (L_temp); pvad->e = sub (pvad->e, norm_prod); if(norm_prod<=0) pvad->m = extract_h (L_shr (L_temp, -norm_prod)); else pvad->m = extract_h (L_shl (L_temp, norm_prod)); return; }
Word16 Random(Word16 *seed) { /* seed = seed*31821 + 13849; */ *seed = extract_l(L_add(L_shr(L_mult(*seed, 31821), 1), 13849L)); return(*seed); }
short ran0(short *seed0) { long Ltemp; Ltemp = 0.0; Ltemp = L_mac(27698, 25173, *seed0); Ltemp = L_shr(Ltemp, 1); Ltemp = Ltemp & 0x0000ffffL; *seed0 = extract_l(Ltemp); return (extract_h(L_shl(Ltemp,15))); }
static Word16 compress10 ( Word16 pos_indxA, /* i : signs of 4 pulses (signs only) */ Word16 pos_indxB, /* i : position index of 8 pulses (pos only) */ Word16 pos_indxC) /* i : position and sign of 8 pulses (compressed) */ { Word16 indx, ia,ib,ic; ia = shr(pos_indxA, 1); ib = extract_l(L_shr(L_mult(shr(pos_indxB, 1), 5), 1)); ic = extract_l(L_shr(L_mult(shr(pos_indxC, 1), 25), 1)); indx = shl(add(ia, add(ib, ic)), 3); ia = pos_indxA & 1; logic16 (); ib = shl((pos_indxB & 1), 1); logic16 (); ic = shl((pos_indxC & 1), 2); logic16 (); indx = add(indx , add(ia, add(ib, ic))); return indx; }
Word32 fnLog2(Word32 L_Input) { static Word16 swC0 = -0x2b2a, swC1 = 0x7fc5, swC2 = -0x54d0; Word16 siShiftCnt, swInSqrd, swIn; Word32 LwIn; /*_________________________________________________________________________ | | | Executable Code | |_________________________________________________________________________| */ /* normalize input and store shifts required */ /* ----------------------------------------- */ siShiftCnt = norm_l(L_Input); LwIn = L_shl(L_Input, siShiftCnt); siShiftCnt = add(siShiftCnt, 1); siShiftCnt = negate(siShiftCnt); /* calculate x*x*c0 */ /* ---------------- */ swIn = extract_h(LwIn); swInSqrd = mult_r(swIn, swIn); LwIn = L_mult(swInSqrd, swC0); /* add x*c1 */ /* --------- */ LwIn = L_mac(LwIn, swIn, swC1); /* add c2 */ /* ------ */ LwIn = L_add(LwIn, L_deposit_h(swC2)); /* apply *(4/32) */ /* ------------- */ LwIn = L_shr(LwIn, 3); LwIn = LwIn & 0x03ffffff; siShiftCnt = shl(siShiftCnt, 10); LwIn = L_add(LwIn, L_deposit_h(siShiftCnt)); /* return log2 */ /* ----------- */ return (LwIn); }
/* ******************************************************************************** * 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); }
void GetExc800bps_dec(short *output, short length, short best, short flag, short n, short fer_flag) { short i, j; short sum; long Ltemp; short temp; static short Seed = 1234; static short Sum[NoOfSubFrames]; static short PrevBest = 0; #define P333 10923 /* (1/3) */ if (!flag && !n) Seed = 1234; if (n == 0) { /* De-quantize */ if (fer_flag == 0) { for (j = 0; j < 3; j++) Sum[j] = Powqtbl[best * 3 + j]; PrevBest = best; } else { for (j = 0, Ltemp = 0; j < 3; j++) Ltemp = L_mac(Ltemp, Powqtbl[PrevBest * 3 + j], P333); for (j = 0; j < 3; j++) Sum[j] = round(Ltemp); } } /* Convert to linear domain */ sum = Sum[n]; /* NOTE: Logqtbl[] and pow() function has been replaced with Powqtbl[] */ for (i = 0; i < length; i++) { temp = ran_g(&Seed); Ltemp = L_mult(sum, temp); Ltemp = L_shr(Ltemp, 5); output[i] = round(Ltemp); } }
void acf_averaging ( Word16 r_h[], Word16 r_l[], Word16 scal_acf, Word32 L_av0[], Word32 L_av1[] ) { Word32 L_temp; Word16 scale; Word16 i; scale = add (9, scal_acf); for (i = 0; i <= 8; i++) { if(scale<0) L_temp = L_shl (L_Comp (r_h[i], r_l[i]), -scale); else L_temp = L_shr (L_Comp (r_h[i], r_l[i]), scale); L_av0[i] = L_add (L_sacf[i], L_temp); L_av0[i] = L_add (L_sacf[i + 9], L_av0[i]); L_av0[i] = L_add (L_sacf[i + 18], L_av0[i]); L_sacf[pt_sacf + i] = L_temp; L_av1[i] = L_sav0[pt_sav0 + i]; L_sav0[pt_sav0 + i] = L_av0[i]; } /* Update the array pointers */ if (sub (pt_sacf, 18) == 0) { pt_sacf = 0; } else { pt_sacf = add (pt_sacf, 9); } if (sub (pt_sav0, 27) == 0) { pt_sav0 = 0; } else { pt_sav0 = add (pt_sav0, 9); } return; }
/*************************************************************************** Function: adjust_abs_region_power_index Syntax: adjust_abs_region_power_index(Word16 *absolute_region_power_index, Word16 *mlt_coefs, Word16 number_of_regions) inputs: *mlt_coefs *absolute_region_power_index number_of_regions outputs: *absolute_region_power_index Description: Adjusts the absolute power index WMOPS: 7kHz | 24kbit | 32kbit -------|--------------|---------------- AVG | 0.03 | 0.03 -------|--------------|---------------- MAX | 0.12 | 0.12 -------|--------------|---------------- 14kHz | 24kbit | 32kbit | 48kbit -------|--------------|----------------|---------------- AVG | 0.03 | 0.03 | 0.03 -------|--------------|----------------|---------------- MAX | 0.14 | 0.14 | 0.14 -------|--------------|----------------|---------------- ***************************************************************************/ void adjust_abs_region_power_index(Word16 *absolute_region_power_index,Word16 *mlt_coefs,Word16 number_of_regions) { Word16 n,i; Word16 region; Word16 *raw_mlt_ptr; Word32 acca; Word16 temp; for (region=0; region<number_of_regions; region++) { n = sub(absolute_region_power_index[region],39); n = shr(n,1); test(); if (n > 0) { temp = extract_l(L_mult0(region,REGION_SIZE)); raw_mlt_ptr = &mlt_coefs[temp]; for (i=0; i<REGION_SIZE; i++) { acca = L_shl(*raw_mlt_ptr,16); acca = L_add(acca,32768L); acca = L_shr(acca,n); acca = L_shr(acca,16); *raw_mlt_ptr++ = extract_l(acca); } temp = shl(n,1); temp = sub(absolute_region_power_index[region],temp); absolute_region_power_index[region] = temp; move16(); } } }
void Log2( Word32 L_x, /* (i) Q0 : input value */ Word16 *exponent, /* (o) Q0 : Integer part of Log2. (range: 0<=val<=30) */ Word16 *fraction /* (o) Q15: Fractional part of Log2. (range: 0<=val<1) */ ) { Word16 exp, i, a, tmp; Word32 L_y; if( L_x <= (Word32)0 ) { *exponent = 0; *fraction = 0; return; } exp = norm_l(L_x); L_x = L_shl(L_x, exp ); /* L_x is normalized */ *exponent = sub(30, exp); L_x = L_shr(L_x, 9); i = extract_h(L_x); /* Extract b25-b31 */ L_x = L_shr(L_x, 1); a = extract_l(L_x); /* Extract b10-b24 of fraction */ a = a & (Word16)0x7fff; i = sub(i, 32); L_y = L_deposit_h(tablog[i]); /* tablog[i] << 16 */ tmp = sub(tablog[i], tablog[i+1]); /* tablog[i] - tablog[i+1] */ L_y = L_msu(L_y, tmp, a); /* L_y -= tmp*a*2 */ *fraction = extract_h( L_y); return; }