diff options
Diffstat (limited to 'media/libstagefright/codecs/amrwbenc/src/levinson.c')
-rw-r--r-- | media/libstagefright/codecs/amrwbenc/src/levinson.c | 286 |
1 files changed, 143 insertions, 143 deletions
diff --git a/media/libstagefright/codecs/amrwbenc/src/levinson.c b/media/libstagefright/codecs/amrwbenc/src/levinson.c index 4b2f8ed..9d5a3bd 100644 --- a/media/libstagefright/codecs/amrwbenc/src/levinson.c +++ b/media/libstagefright/codecs/amrwbenc/src/levinson.c @@ -21,7 +21,7 @@ * * ************************************************************************/ /*---------------------------------------------------------------------------* - * LEVINSON.C * + * LEVINSON.C * *---------------------------------------------------------------------------* * * * LEVINSON-DURBIN algorithm in double precision * @@ -96,154 +96,154 @@ #define NC (M/2) void Init_Levinson( - Word16 * mem /* output :static memory (18 words) */ - ) + Word16 * mem /* output :static memory (18 words) */ + ) { - Set_zero(mem, 18); /* old_A[0..M-1] = 0, old_rc[0..1] = 0 */ - return; + Set_zero(mem, 18); /* old_A[0..M-1] = 0, old_rc[0..1] = 0 */ + return; } void Levinson( - Word16 Rh[], /* (i) : Rh[M+1] Vector of autocorrelations (msb) */ - Word16 Rl[], /* (i) : Rl[M+1] Vector of autocorrelations (lsb) */ - Word16 A[], /* (o) Q12 : A[M] LPC coefficients (m = 16) */ - Word16 rc[], /* (o) Q15 : rc[M] Reflection coefficients. */ - Word16 * mem /* (i/o) :static memory (18 words) */ - ) + Word16 Rh[], /* (i) : Rh[M+1] Vector of autocorrelations (msb) */ + Word16 Rl[], /* (i) : Rl[M+1] Vector of autocorrelations (lsb) */ + Word16 A[], /* (o) Q12 : A[M] LPC coefficients (m = 16) */ + Word16 rc[], /* (o) Q15 : rc[M] Reflection coefficients. */ + Word16 * mem /* (i/o) :static memory (18 words) */ + ) { - Word32 i, j; - Word16 hi, lo; - Word16 Kh, Kl; /* reflection coefficient; hi and lo */ - Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */ - Word16 Ah[M + 1], Al[M + 1]; /* LPC coef. in double prec. */ - Word16 Anh[M + 1], Anl[M + 1]; /* LPC coef.for next iteration in double prec. */ - Word32 t0, t1, t2; /* temporary variable */ - Word16 *old_A, *old_rc; - - /* Last A(z) for case of unstable filter */ - old_A = mem; - old_rc = mem + M; - - /* K = A[1] = -R[1] / R[0] */ - - t1 = ((Rh[1] << 16) + (Rl[1] << 1)); /* R[1] in Q31 */ - t2 = L_abs(t1); /* abs R[1] */ - t0 = Div_32(t2, Rh[0], Rl[0]); /* R[1]/R[0] in Q31 */ - if (t1 > 0) - t0 = -t0; /* -R[1]/R[0] */ - - Kh = t0 >> 16; - Kl = (t0 & 0xffff)>>1; - rc[0] = Kh; - t0 = (t0 >> 4); /* A[1] in Q27 */ - - Ah[1] = t0 >> 16; - Al[1] = (t0 & 0xffff)>>1; - - /* Alpha = R[0] * (1-K**2) */ - t0 = Mpy_32(Kh, Kl, Kh, Kl); /* K*K in Q31 */ - t0 = L_abs(t0); /* Some case <0 !! */ - t0 = vo_L_sub((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ - - hi = t0 >> 16; - lo = (t0 & 0xffff)>>1; - - t0 = Mpy_32(Rh[0], Rl[0], hi, lo); /* Alpha in Q31 */ - - /* Normalize Alpha */ - alp_exp = norm_l(t0); - t0 = (t0 << alp_exp); - - alp_h = t0 >> 16; - alp_l = (t0 & 0xffff)>>1; - /*--------------------------------------* - * ITERATIONS I=2 to M * - *--------------------------------------*/ - for (i = 2; i <= M; i++) - { - /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */ - t0 = 0; - for (j = 1; j < i; j++) - t0 = vo_L_add(t0, Mpy_32(Rh[j], Rl[j], Ah[i - j], Al[i - j])); - - t0 = t0 << 4; /* result in Q27 -> convert to Q31 */ - /* No overflow possible */ - t1 = ((Rh[i] << 16) + (Rl[i] << 1)); - t0 = vo_L_add(t0, t1); /* add R[i] in Q31 */ - - /* K = -t0 / Alpha */ - t1 = L_abs(t0); - t2 = Div_32(t1, alp_h, alp_l); /* abs(t0)/Alpha */ - if (t0 > 0) - t2 = -t2; /* K =-t0/Alpha */ - t2 = (t2 << alp_exp); /* denormalize; compare to Alpha */ - - Kh = t2 >> 16; - Kl = (t2 & 0xffff)>>1; - - rc[i - 1] = Kh; - /* Test for unstable filter. If unstable keep old A(z) */ - if (abs_s(Kh) > 32750) - { - A[0] = 4096; /* Ai[0] not stored (always 1.0) */ - for (j = 0; j < M; j++) - { - A[j + 1] = old_A[j]; - } - rc[0] = old_rc[0]; /* only two rc coefficients are needed */ - rc[1] = old_rc[1]; - return; - } - /*------------------------------------------* - * Compute new LPC coeff. -> An[i] * - * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * - * An[i]= K * - *------------------------------------------*/ - for (j = 1; j < i; j++) - { - t0 = Mpy_32(Kh, Kl, Ah[i - j], Al[i - j]); - t0 = vo_L_add(t0, ((Ah[j] << 16) + (Al[j] << 1))); - Anh[j] = t0 >> 16; - Anl[j] = (t0 & 0xffff)>>1; - } - t2 = (t2 >> 4); /* t2 = K in Q31 ->convert to Q27 */ - - VO_L_Extract(t2, &Anh[i], &Anl[i]); /* An[i] in Q27 */ - - /* Alpha = Alpha * (1-K**2) */ - t0 = Mpy_32(Kh, Kl, Kh, Kl); /* K*K in Q31 */ - t0 = L_abs(t0); /* Some case <0 !! */ - t0 = vo_L_sub((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ - hi = t0 >> 16; - lo = (t0 & 0xffff)>>1; - t0 = Mpy_32(alp_h, alp_l, hi, lo); /* Alpha in Q31 */ - - /* Normalize Alpha */ - j = norm_l(t0); - t0 = (t0 << j); - alp_h = t0 >> 16; - alp_l = (t0 & 0xffff)>>1; - alp_exp += j; /* Add normalization to alp_exp */ - - /* A[j] = An[j] */ - for (j = 1; j <= i; j++) - { - Ah[j] = Anh[j]; - Al[j] = Anl[j]; - } - } - /* Truncate A[i] in Q27 to Q12 with rounding */ - A[0] = 4096; - for (i = 1; i <= M; i++) - { - t0 = (Ah[i] << 16) + (Al[i] << 1); - old_A[i - 1] = A[i] = vo_round((t0 << 1)); - } - old_rc[0] = rc[0]; - old_rc[1] = rc[1]; - - return; + Word32 i, j; + Word16 hi, lo; + Word16 Kh, Kl; /* reflection coefficient; hi and lo */ + Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */ + Word16 Ah[M + 1], Al[M + 1]; /* LPC coef. in double prec. */ + Word16 Anh[M + 1], Anl[M + 1]; /* LPC coef.for next iteration in double prec. */ + Word32 t0, t1, t2; /* temporary variable */ + Word16 *old_A, *old_rc; + + /* Last A(z) for case of unstable filter */ + old_A = mem; + old_rc = mem + M; + + /* K = A[1] = -R[1] / R[0] */ + + t1 = ((Rh[1] << 16) + (Rl[1] << 1)); /* R[1] in Q31 */ + t2 = L_abs(t1); /* abs R[1] */ + t0 = Div_32(t2, Rh[0], Rl[0]); /* R[1]/R[0] in Q31 */ + if (t1 > 0) + t0 = -t0; /* -R[1]/R[0] */ + + Kh = t0 >> 16; + Kl = (t0 & 0xffff)>>1; + rc[0] = Kh; + t0 = (t0 >> 4); /* A[1] in Q27 */ + + Ah[1] = t0 >> 16; + Al[1] = (t0 & 0xffff)>>1; + + /* Alpha = R[0] * (1-K**2) */ + t0 = Mpy_32(Kh, Kl, Kh, Kl); /* K*K in Q31 */ + t0 = L_abs(t0); /* Some case <0 !! */ + t0 = vo_L_sub((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ + + hi = t0 >> 16; + lo = (t0 & 0xffff)>>1; + + t0 = Mpy_32(Rh[0], Rl[0], hi, lo); /* Alpha in Q31 */ + + /* Normalize Alpha */ + alp_exp = norm_l(t0); + t0 = (t0 << alp_exp); + + alp_h = t0 >> 16; + alp_l = (t0 & 0xffff)>>1; + /*--------------------------------------* + * ITERATIONS I=2 to M * + *--------------------------------------*/ + for (i = 2; i <= M; i++) + { + /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */ + t0 = 0; + for (j = 1; j < i; j++) + t0 = vo_L_add(t0, Mpy_32(Rh[j], Rl[j], Ah[i - j], Al[i - j])); + + t0 = t0 << 4; /* result in Q27 -> convert to Q31 */ + /* No overflow possible */ + t1 = ((Rh[i] << 16) + (Rl[i] << 1)); + t0 = vo_L_add(t0, t1); /* add R[i] in Q31 */ + + /* K = -t0 / Alpha */ + t1 = L_abs(t0); + t2 = Div_32(t1, alp_h, alp_l); /* abs(t0)/Alpha */ + if (t0 > 0) + t2 = -t2; /* K =-t0/Alpha */ + t2 = (t2 << alp_exp); /* denormalize; compare to Alpha */ + + Kh = t2 >> 16; + Kl = (t2 & 0xffff)>>1; + + rc[i - 1] = Kh; + /* Test for unstable filter. If unstable keep old A(z) */ + if (abs_s(Kh) > 32750) + { + A[0] = 4096; /* Ai[0] not stored (always 1.0) */ + for (j = 0; j < M; j++) + { + A[j + 1] = old_A[j]; + } + rc[0] = old_rc[0]; /* only two rc coefficients are needed */ + rc[1] = old_rc[1]; + return; + } + /*------------------------------------------* + * Compute new LPC coeff. -> An[i] * + * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * + * An[i]= K * + *------------------------------------------*/ + for (j = 1; j < i; j++) + { + t0 = Mpy_32(Kh, Kl, Ah[i - j], Al[i - j]); + t0 = vo_L_add(t0, ((Ah[j] << 16) + (Al[j] << 1))); + Anh[j] = t0 >> 16; + Anl[j] = (t0 & 0xffff)>>1; + } + t2 = (t2 >> 4); /* t2 = K in Q31 ->convert to Q27 */ + + VO_L_Extract(t2, &Anh[i], &Anl[i]); /* An[i] in Q27 */ + + /* Alpha = Alpha * (1-K**2) */ + t0 = Mpy_32(Kh, Kl, Kh, Kl); /* K*K in Q31 */ + t0 = L_abs(t0); /* Some case <0 !! */ + t0 = vo_L_sub((Word32) 0x7fffffffL, t0); /* 1 - K*K in Q31 */ + hi = t0 >> 16; + lo = (t0 & 0xffff)>>1; + t0 = Mpy_32(alp_h, alp_l, hi, lo); /* Alpha in Q31 */ + + /* Normalize Alpha */ + j = norm_l(t0); + t0 = (t0 << j); + alp_h = t0 >> 16; + alp_l = (t0 & 0xffff)>>1; + alp_exp += j; /* Add normalization to alp_exp */ + + /* A[j] = An[j] */ + for (j = 1; j <= i; j++) + { + Ah[j] = Anh[j]; + Al[j] = Anl[j]; + } + } + /* Truncate A[i] in Q27 to Q12 with rounding */ + A[0] = 4096; + for (i = 1; i <= M; i++) + { + t0 = (Ah[i] << 16) + (Al[i] << 1); + old_A[i - 1] = A[i] = vo_round((t0 << 1)); + } + old_rc[0] = rc[0]; + old_rc[1] = rc[1]; + + return; } |