diff options
Diffstat (limited to 'media/libstagefright/codecs/amrwbenc/src/isp_az.c')
-rw-r--r-- | media/libstagefright/codecs/amrwbenc/src/isp_az.c | 494 |
1 files changed, 247 insertions, 247 deletions
diff --git a/media/libstagefright/codecs/amrwbenc/src/isp_az.c b/media/libstagefright/codecs/amrwbenc/src/isp_az.c index 7b44d12..c235c5d 100644 --- a/media/libstagefright/codecs/amrwbenc/src/isp_az.c +++ b/media/libstagefright/codecs/amrwbenc/src/isp_az.c @@ -1,247 +1,247 @@ -/*
- ** Copyright 2003-2010, VisualOn, Inc.
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-/***********************************************************************
-* File: isp_az.c *
-* *
-* Description:Compute the LPC coefficients from isp (order=M) *
-* *
-************************************************************************/
-
-#include "typedef.h"
-#include "basic_op.h"
-#include "oper_32b.h"
-#include "cnst.h"
-
-#define NC (M/2)
-#define NC16k (M16k/2)
-
-/* local function */
-
-static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n);
-static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n);
-
-void Isp_Az(
- Word16 isp[], /* (i) Q15 : Immittance spectral pairs */
- Word16 a[], /* (o) Q12 : predictor coefficients (order = M) */
- Word16 m,
- Word16 adaptive_scaling /* (i) 0 : adaptive scaling disabled */
- /* 1 : adaptive scaling enabled */
- )
-{
- Word32 i, j;
- Word16 hi, lo;
- Word32 f1[NC16k + 1], f2[NC16k];
- Word16 nc;
- Word32 t0;
- Word16 q, q_sug;
- Word32 tmax;
-
- nc = (m >> 1);
- if(nc > 8)
- {
- Get_isp_pol_16kHz(&isp[0], f1, nc);
- for (i = 0; i <= nc; i++)
- {
- f1[i] = f1[i] << 2;
- }
- } else
- Get_isp_pol(&isp[0], f1, nc);
-
- if (nc > 8)
- {
- Get_isp_pol_16kHz(&isp[1], f2, (nc - 1));
- for (i = 0; i <= nc - 1; i++)
- {
- f2[i] = f2[i] << 2;
- }
- } else
- Get_isp_pol(&isp[1], f2, (nc - 1));
-
- /*-----------------------------------------------------*
- * Multiply F2(z) by (1 - z^-2) *
- *-----------------------------------------------------*/
-
- for (i = (nc - 1); i > 1; i--)
- {
- f2[i] = vo_L_sub(f2[i], f2[i - 2]); /* f2[i] -= f2[i-2]; */
- }
-
- /*----------------------------------------------------------*
- * Scale F1(z) by (1+isp[m-1]) and F2(z) by (1-isp[m-1]) *
- *----------------------------------------------------------*/
-
- for (i = 0; i < nc; i++)
- {
- /* f1[i] *= (1.0 + isp[M-1]); */
-
- hi = f1[i] >> 16;
- lo = (f1[i] & 0xffff)>>1;
-
- t0 = Mpy_32_16(hi, lo, isp[m - 1]);
- f1[i] = vo_L_add(f1[i], t0);
-
- /* f2[i] *= (1.0 - isp[M-1]); */
-
- hi = f2[i] >> 16;
- lo = (f2[i] & 0xffff)>>1;
- t0 = Mpy_32_16(hi, lo, isp[m - 1]);
- f2[i] = vo_L_sub(f2[i], t0);
- }
-
- /*-----------------------------------------------------*
- * A(z) = (F1(z)+F2(z))/2 *
- * F1(z) is symmetric and F2(z) is antisymmetric *
- *-----------------------------------------------------*/
-
- /* a[0] = 1.0; */
- a[0] = 4096;
- tmax = 1;
- for (i = 1, j = m - 1; i < nc; i++, j--)
- {
- /* a[i] = 0.5*(f1[i] + f2[i]); */
-
- t0 = vo_L_add(f1[i], f2[i]); /* f1[i] + f2[i] */
- tmax |= L_abs(t0);
- a[i] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
-
- /* a[j] = 0.5*(f1[i] - f2[i]); */
-
- t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */
- tmax |= L_abs(t0);
- a[j] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */
- }
-
- /* rescale data if overflow has occured and reprocess the loop */
- if(adaptive_scaling == 1)
- q = 4 - norm_l(tmax); /* adaptive scaling enabled */
- else
- q = 0; /* adaptive scaling disabled */
-
- if (q > 0)
- {
- q_sug = (12 + q);
- for (i = 1, j = m - 1; i < nc; i++, j--)
- {
- /* a[i] = 0.5*(f1[i] + f2[i]); */
- t0 = vo_L_add(f1[i], f2[i]); /* f1[i] + f2[i] */
- a[i] = (Word16)(vo_L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
-
- /* a[j] = 0.5*(f1[i] - f2[i]); */
- t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */
- a[j] = (Word16)(vo_L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
- }
- a[0] = shr(a[0], q);
- }
- else
- {
- q_sug = 12;
- q = 0;
- }
- /* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */
- hi = f1[nc] >> 16;
- lo = (f1[nc] & 0xffff)>>1;
- t0 = Mpy_32_16(hi, lo, isp[m - 1]);
- t0 = vo_L_add(f1[nc], t0);
- a[nc] = (Word16)(L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */
- /* a[m] = isp[m-1]; */
-
- a[m] = vo_shr_r(isp[m - 1], (3 + q)); /* from Q15 to Q12 */
- return;
-}
-
-/*-----------------------------------------------------------*
-* procedure Get_isp_pol: *
-* ~~~~~~~~~~~ *
-* Find the polynomial F1(z) or F2(z) from the ISPs. *
-* This is performed by expanding the product polynomials: *
-* *
-* F1(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) *
-* i=0,2,4,6,8 *
-* F2(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) *
-* i=1,3,5,7 *
-* *
-* where isp_i are the ISPs in the cosine domain. *
-*-----------------------------------------------------------*
-* *
-* Parameters: *
-* isp[] : isp vector (cosine domaine) in Q15 *
-* f[] : the coefficients of F1 or F2 in Q23 *
-* n : == NC for F1(z); == NC-1 for F2(z) *
-*-----------------------------------------------------------*/
-
-static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n)
-{
- Word16 hi, lo;
- Word32 i, j, t0;
- /* All computation in Q23 */
-
- f[0] = vo_L_mult(4096, 1024); /* f[0] = 1.0; in Q23 */
- f[1] = vo_L_mult(isp[0], -256); /* f[1] = -2.0*isp[0] in Q23 */
-
- f += 2; /* Advance f pointer */
- isp += 2; /* Advance isp pointer */
- for (i = 2; i <= n; i++)
- {
- *f = f[-2];
- for (j = 1; j < i; j++, f--)
- {
- hi = f[-1]>>16;
- lo = (f[-1] & 0xffff)>>1;
-
- t0 = Mpy_32_16(hi, lo, *isp); /* t0 = f[-1] * isp */
- t0 = t0 << 1;
- *f = vo_L_sub(*f, t0); /* *f -= t0 */
- *f = vo_L_add(*f, f[-2]); /* *f += f[-2] */
- }
- *f -= (*isp << 9); /* *f -= isp<<8 */
- f += i; /* Advance f pointer */
- isp += 2; /* Advance isp pointer */
- }
- return;
-}
-
-static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n)
-{
- Word16 hi, lo;
- Word32 i, j, t0;
-
- /* All computation in Q23 */
- f[0] = L_mult(4096, 256); /* f[0] = 1.0; in Q23 */
- f[1] = L_mult(isp[0], -64); /* f[1] = -2.0*isp[0] in Q23 */
-
- f += 2; /* Advance f pointer */
- isp += 2; /* Advance isp pointer */
-
- for (i = 2; i <= n; i++)
- {
- *f = f[-2];
- for (j = 1; j < i; j++, f--)
- {
- VO_L_Extract(f[-1], &hi, &lo);
- t0 = Mpy_32_16(hi, lo, *isp); /* t0 = f[-1] * isp */
- t0 = L_shl2(t0, 1);
- *f = L_sub(*f, t0); /* *f -= t0 */
- *f = L_add(*f, f[-2]); /* *f += f[-2] */
- }
- *f = L_msu(*f, *isp, 64); /* *f -= isp<<8 */
- f += i; /* Advance f pointer */
- isp += 2; /* Advance isp pointer */
- }
- return;
-}
-
-
+/* + ** Copyright 2003-2010, VisualOn, Inc. + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ + +/*********************************************************************** +* File: isp_az.c * +* * +* Description:Compute the LPC coefficients from isp (order=M) * +* * +************************************************************************/ + +#include "typedef.h" +#include "basic_op.h" +#include "oper_32b.h" +#include "cnst.h" + +#define NC (M/2) +#define NC16k (M16k/2) + +/* local function */ + +static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n); +static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n); + +void Isp_Az( + Word16 isp[], /* (i) Q15 : Immittance spectral pairs */ + Word16 a[], /* (o) Q12 : predictor coefficients (order = M) */ + Word16 m, + Word16 adaptive_scaling /* (i) 0 : adaptive scaling disabled */ + /* 1 : adaptive scaling enabled */ + ) +{ + Word32 i, j; + Word16 hi, lo; + Word32 f1[NC16k + 1], f2[NC16k]; + Word16 nc; + Word32 t0; + Word16 q, q_sug; + Word32 tmax; + + nc = (m >> 1); + if(nc > 8) + { + Get_isp_pol_16kHz(&isp[0], f1, nc); + for (i = 0; i <= nc; i++) + { + f1[i] = f1[i] << 2; + } + } else + Get_isp_pol(&isp[0], f1, nc); + + if (nc > 8) + { + Get_isp_pol_16kHz(&isp[1], f2, (nc - 1)); + for (i = 0; i <= nc - 1; i++) + { + f2[i] = f2[i] << 2; + } + } else + Get_isp_pol(&isp[1], f2, (nc - 1)); + + /*-----------------------------------------------------* + * Multiply F2(z) by (1 - z^-2) * + *-----------------------------------------------------*/ + + for (i = (nc - 1); i > 1; i--) + { + f2[i] = vo_L_sub(f2[i], f2[i - 2]); /* f2[i] -= f2[i-2]; */ + } + + /*----------------------------------------------------------* + * Scale F1(z) by (1+isp[m-1]) and F2(z) by (1-isp[m-1]) * + *----------------------------------------------------------*/ + + for (i = 0; i < nc; i++) + { + /* f1[i] *= (1.0 + isp[M-1]); */ + + hi = f1[i] >> 16; + lo = (f1[i] & 0xffff)>>1; + + t0 = Mpy_32_16(hi, lo, isp[m - 1]); + f1[i] = vo_L_add(f1[i], t0); + + /* f2[i] *= (1.0 - isp[M-1]); */ + + hi = f2[i] >> 16; + lo = (f2[i] & 0xffff)>>1; + t0 = Mpy_32_16(hi, lo, isp[m - 1]); + f2[i] = vo_L_sub(f2[i], t0); + } + + /*-----------------------------------------------------* + * A(z) = (F1(z)+F2(z))/2 * + * F1(z) is symmetric and F2(z) is antisymmetric * + *-----------------------------------------------------*/ + + /* a[0] = 1.0; */ + a[0] = 4096; + tmax = 1; + for (i = 1, j = m - 1; i < nc; i++, j--) + { + /* a[i] = 0.5*(f1[i] + f2[i]); */ + + t0 = vo_L_add(f1[i], f2[i]); /* f1[i] + f2[i] */ + tmax |= L_abs(t0); + a[i] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */ + + /* a[j] = 0.5*(f1[i] - f2[i]); */ + + t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */ + tmax |= L_abs(t0); + a[j] = (Word16)(vo_L_shr_r(t0, 12)); /* from Q23 to Q12 and * 0.5 */ + } + + /* rescale data if overflow has occured and reprocess the loop */ + if(adaptive_scaling == 1) + q = 4 - norm_l(tmax); /* adaptive scaling enabled */ + else + q = 0; /* adaptive scaling disabled */ + + if (q > 0) + { + q_sug = (12 + q); + for (i = 1, j = m - 1; i < nc; i++, j--) + { + /* a[i] = 0.5*(f1[i] + f2[i]); */ + t0 = vo_L_add(f1[i], f2[i]); /* f1[i] + f2[i] */ + a[i] = (Word16)(vo_L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */ + + /* a[j] = 0.5*(f1[i] - f2[i]); */ + t0 = vo_L_sub(f1[i], f2[i]); /* f1[i] - f2[i] */ + a[j] = (Word16)(vo_L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */ + } + a[0] = shr(a[0], q); + } + else + { + q_sug = 12; + q = 0; + } + /* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */ + hi = f1[nc] >> 16; + lo = (f1[nc] & 0xffff)>>1; + t0 = Mpy_32_16(hi, lo, isp[m - 1]); + t0 = vo_L_add(f1[nc], t0); + a[nc] = (Word16)(L_shr_r(t0, q_sug)); /* from Q23 to Q12 and * 0.5 */ + /* a[m] = isp[m-1]; */ + + a[m] = vo_shr_r(isp[m - 1], (3 + q)); /* from Q15 to Q12 */ + return; +} + +/*-----------------------------------------------------------* +* procedure Get_isp_pol: * +* ~~~~~~~~~~~ * +* Find the polynomial F1(z) or F2(z) from the ISPs. * +* This is performed by expanding the product polynomials: * +* * +* F1(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) * +* i=0,2,4,6,8 * +* F2(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) * +* i=1,3,5,7 * +* * +* where isp_i are the ISPs in the cosine domain. * +*-----------------------------------------------------------* +* * +* Parameters: * +* isp[] : isp vector (cosine domaine) in Q15 * +* f[] : the coefficients of F1 or F2 in Q23 * +* n : == NC for F1(z); == NC-1 for F2(z) * +*-----------------------------------------------------------*/ + +static void Get_isp_pol(Word16 * isp, Word32 * f, Word16 n) +{ + Word16 hi, lo; + Word32 i, j, t0; + /* All computation in Q23 */ + + f[0] = vo_L_mult(4096, 1024); /* f[0] = 1.0; in Q23 */ + f[1] = vo_L_mult(isp[0], -256); /* f[1] = -2.0*isp[0] in Q23 */ + + f += 2; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + for (i = 2; i <= n; i++) + { + *f = f[-2]; + for (j = 1; j < i; j++, f--) + { + hi = f[-1]>>16; + lo = (f[-1] & 0xffff)>>1; + + t0 = Mpy_32_16(hi, lo, *isp); /* t0 = f[-1] * isp */ + t0 = t0 << 1; + *f = vo_L_sub(*f, t0); /* *f -= t0 */ + *f = vo_L_add(*f, f[-2]); /* *f += f[-2] */ + } + *f -= (*isp << 9); /* *f -= isp<<8 */ + f += i; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + } + return; +} + +static void Get_isp_pol_16kHz(Word16 * isp, Word32 * f, Word16 n) +{ + Word16 hi, lo; + Word32 i, j, t0; + + /* All computation in Q23 */ + f[0] = L_mult(4096, 256); /* f[0] = 1.0; in Q23 */ + f[1] = L_mult(isp[0], -64); /* f[1] = -2.0*isp[0] in Q23 */ + + f += 2; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + + for (i = 2; i <= n; i++) + { + *f = f[-2]; + for (j = 1; j < i; j++, f--) + { + VO_L_Extract(f[-1], &hi, &lo); + t0 = Mpy_32_16(hi, lo, *isp); /* t0 = f[-1] * isp */ + t0 = L_shl2(t0, 1); + *f = L_sub(*f, t0); /* *f -= t0 */ + *f = L_add(*f, f[-2]); /* *f += f[-2] */ + } + *f = L_msu(*f, *isp, 64); /* *f -= isp<<8 */ + f += i; /* Advance f pointer */ + isp += 2; /* Advance isp pointer */ + } + return; +} + + |