summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrnb/enc/src/levinson.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/amrnb/enc/src/levinson.cpp')
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/levinson.cpp824
1 files changed, 824 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/amrnb/enc/src/levinson.cpp b/media/libstagefright/codecs/amrnb/enc/src/levinson.cpp
new file mode 100644
index 0000000..001897b
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/src/levinson.cpp
@@ -0,0 +1,824 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * 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.
+ * -------------------------------------------------------------------
+ */
+/****************************************************************************************
+Portions of this file are derived from the following 3GPP standard:
+
+ 3GPP TS 26.073
+ ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
+ Available from http://www.3gpp.org
+
+(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
+Permission to distribute, modify and use this file under the standard license
+terms listed above has been obtained from the copyright holder.
+****************************************************************************************/
+/*
+------------------------------------------------------------------------------
+
+
+
+ Pathname: ./audio/gsm-amr/c/src/levinson.c
+ Funtions: Levinson_init
+ Levinson_reset
+ Levinson_exit
+ Levinson
+
+------------------------------------------------------------------------------
+ MODULE DESCRIPTION
+
+ This file contains the function the implements the Levinson-Durbin algorithm
+ using double-precision arithmetic. This file also includes functions to
+ initialize, allocate, and deallocate memory used by the Levinson function.
+
+------------------------------------------------------------------------------
+*/
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include <stdlib.h>
+#include <string.h>
+
+#include "levinson.h"
+#include "basicop_malloc.h"
+#include "basic_op.h"
+#include "div_32.h"
+#include "cnst.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL VARIABLE DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Levinson_init
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ state = pointer to an array of pointers to structures of type
+ LevinsonState
+
+ Outputs:
+ pointer pointed to by state points to the newly allocated memory to
+ be used by Levinson function
+
+ Returns:
+ return_value = 0, if initialization was successful; -1, otherwise (int)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function allocates and initializes the state memory used by the
+ Levinson function.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+int Levinson_init (LevinsonState **state)
+{
+ LevinsonState* s;
+
+ if (state == (LevinsonState **) NULL){
+ //fprint(stderr, "Levinson_init: invalid parameter\n");
+ return -1;
+ }
+ *state = NULL;
+
+ // allocate memory
+ if ((s= (LevinsonState *) malloc(sizeof(LevinsonState))) == NULL){
+ //fprint(stderr, "Levinson_init: can not malloc state structure\n");
+ return -1;
+ }
+
+ Levinson_reset(s);
+ *state = s;
+
+ return 0;
+}
+
+------------------------------------------------------------------------------
+ RESOURCES USED [optional]
+
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ HEAP MEMORY USED: x bytes
+
+ STACK MEMORY USED: x bytes
+
+ CLOCK CYCLES: (cycle count equation for this function) + (variable
+ used to represent cycle count for each subroutine
+ called)
+ where: (cycle count variable) = cycle count for [subroutine
+ name]
+
+------------------------------------------------------------------------------
+ CAUTION [optional]
+ [State any special notes, constraints or cautions for users of this function]
+
+------------------------------------------------------------------------------
+*/
+
+Word16 Levinson_init(LevinsonState **state)
+{
+ LevinsonState* s;
+
+ if (state == (LevinsonState **) NULL)
+ {
+ /* fprint(stderr, "Levinson_init: invalid parameter\n"); */
+ return(-1);
+ }
+ *state = NULL;
+
+ /* allocate memory */
+ if ((s = (LevinsonState *) malloc(sizeof(LevinsonState))) == NULL)
+ {
+ /* fprint(stderr, "Levinson_init:
+ can not malloc state structure\n"); */
+ return(-1);
+ }
+
+ Levinson_reset(s);
+ *state = s;
+
+ return(0);
+}
+
+/****************************************************************************/
+
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Levinson_reset
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ state = pointer to structures of type LevinsonState
+
+ Outputs:
+ old_A field of structure pointed to by state is initialized to 4096
+ (first location) and the rest to zeros
+
+ Returns:
+ return_value = 0, if reset was successful; -1, otherwise (int)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function initializes the state memory used by the Levinson function to
+ zero.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+int Levinson_reset (LevinsonState *state)
+{
+ Word16 i;
+
+ if (state == (LevinsonState *) NULL){
+ fprint(stderr, "Levinson_reset: invalid parameter\n");
+ return -1;
+ }
+
+ state->old_A[0] = 4096;
+ for(i = 1; i < M + 1; i++)
+ state->old_A[i] = 0;
+
+ return 0;
+}
+
+------------------------------------------------------------------------------
+ RESOURCES USED [optional]
+
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ HEAP MEMORY USED: x bytes
+
+ STACK MEMORY USED: x bytes
+
+ CLOCK CYCLES: (cycle count equation for this function) + (variable
+ used to represent cycle count for each subroutine
+ called)
+ where: (cycle count variable) = cycle count for [subroutine
+ name]
+
+------------------------------------------------------------------------------
+ CAUTION [optional]
+ [State any special notes, constraints or cautions for users of this function]
+
+------------------------------------------------------------------------------
+*/
+
+Word16 Levinson_reset(LevinsonState *state)
+{
+ Word16 i;
+
+ if (state == (LevinsonState *) NULL)
+ {
+ /* fprint(stderr, "Levinson_reset: invalid parameter\n"); */
+ return(-1);
+ }
+
+ state->old_A[0] = 4096;
+ for (i = 1; i < M + 1; i++)
+ {
+ state->old_A[i] = 0;
+ }
+
+ return(0);
+}
+
+/****************************************************************************/
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Levinson_exit
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ state = pointer to an array of pointers to structures of type
+ LevinsonState
+
+ Outputs:
+ pointer pointed to by state is set to the NULL address
+
+ Returns:
+ None
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function deallocates the state memory used by the Levinson function.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+void Levinson_exit (LevinsonState **state)
+{
+ if (state == NULL || *state == NULL)
+ return;
+
+ // deallocate memory
+ free(*state);
+ *state = NULL;
+
+ return;
+}
+
+------------------------------------------------------------------------------
+ RESOURCES USED [optional]
+
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ HEAP MEMORY USED: x bytes
+
+ STACK MEMORY USED: x bytes
+
+ CLOCK CYCLES: (cycle count equation for this function) + (variable
+ used to represent cycle count for each subroutine
+ called)
+ where: (cycle count variable) = cycle count for [subroutine
+ name]
+
+------------------------------------------------------------------------------
+ CAUTION [optional]
+ [State any special notes, constraints or cautions for users of this function]
+
+------------------------------------------------------------------------------
+*/
+
+void Levinson_exit(LevinsonState **state)
+{
+ if (state == NULL || *state == NULL)
+ {
+ return;
+ }
+
+ /* deallocate memory */
+ free(*state);
+ *state = NULL;
+
+ return;
+}
+
+/****************************************************************************/
+
+
+/*
+------------------------------------------------------------------------------
+ FUNCTION NAME: Levinson
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ st = pointer to structures of type LevinsonState
+ Rh = vector containing most significant byte of
+ autocorrelation values (Word16)
+ Rl = vector containing least significant byte of
+ autocorrelation values (Word16)
+ A = vector of LPC coefficients (10th order) (Word16)
+ rc = vector containing first four reflection coefficients (Word16)
+ pOverflow = pointer to overflow indicator (Flag)
+
+ Outputs:
+ A contains the newly calculated LPC coefficients
+ rc contains the newly calculated reflection coefficients
+
+ Returns:
+ return_value = 0 (int)
+
+ Global Variables Used:
+ None
+
+ Local Variables Needed:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function implements the Levinson-Durbin algorithm using double-
+ precision arithmetic. This is used to compute the Linear Predictive (LP)
+ filter parameters from the speech autocorrelation values.
+
+ The algorithm implemented is as follows:
+ A[0] = 1
+ K = -R[1]/R[0]
+ A[1] = K
+ Alpha = R[0] * (1-K**2]
+
+ FOR i = 2 to M
+
+ S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i]
+ K = -S / Alpha
+
+ FOR j = 1 to i-1
+ An[j] = A[j] + K*A[i-j] where An[i] = new A[i]
+ ENDFOR
+
+ An[i]=K
+ Alpha=Alpha * (1-K**2)
+
+ END
+
+ where:
+ R[i] = autocorrelations
+ A[i] = filter coefficients
+ K = reflection coefficient
+ Alpha = prediction gain
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ None
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+int Levinson (
+ LevinsonState *st,
+ Word16 Rh[], // i : Rh[m+1] Vector of autocorrelations (msb)
+ Word16 Rl[], // i : Rl[m+1] Vector of autocorrelations (lsb)
+ Word16 A[], // o : A[m] LPC coefficients (m = 10)
+ Word16 rc[] // o : rc[4] First 4 reflection coefficients
+)
+{
+ Word16 i, j;
+ Word16 hi, lo;
+ Word16 Kh, Kl; // reflexion 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
+
+ // K = A[1] = -R[1] / R[0]
+
+ t1 = L_Comp (Rh[1], Rl[1]);
+ t2 = L_abs (t1); // abs R[1]
+ t0 = Div_32 (t2, Rh[0], Rl[0]); // R[1]/R[0]
+ if (t1 > 0)
+ t0 = L_negate (t0); // -R[1]/R[0]
+ L_Extract (t0, &Kh, &Kl); // K in DPF
+
+ rc[0] = pv_round (t0);
+
+ t0 = L_shr (t0, 4); // A[1] in
+ L_Extract (t0, &Ah[1], &Al[1]); // A[1] in DPF
+
+ // Alpha = R[0] * (1-K**2)
+
+ t0 = Mpy_32 (Kh, Kl, Kh, Kl); // K*K
+ t0 = L_abs (t0); // Some case <0 !!
+ t0 = L_sub ((Word32) 0x7fffffffL, t0); // 1 - K*K
+ L_Extract (t0, &hi, &lo); // DPF format
+ t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); // Alpha in
+
+ // Normalize Alpha
+
+ alp_exp = norm_l (t0);
+ t0 = L_shl (t0, alp_exp);
+ L_Extract (t0, &alp_h, &alp_l); // DPF format
+
+ *--------------------------------------*
+ * 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 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j]));
+ }
+ t0 = L_shl (t0, 4);
+
+ t1 = L_Comp (Rh[i], Rl[i]);
+ t0 = L_add (t0, t1); // add R[i]
+
+ // K = -t0 / Alpha
+
+ t1 = L_abs (t0);
+ t2 = Div_32 (t1, alp_h, alp_l); // abs(t0)/Alpha
+ if (t0 > 0)
+ t2 = L_negate (t2); // K =-t0/Alpha
+ t2 = L_shl (t2, alp_exp); // denormalize; compare to Alpha
+ L_Extract (t2, &Kh, &Kl); // K in DPF
+
+ if (sub (i, 5) < 0)
+ {
+ rc[i - 1] = pv_round (t2);
+ }
+ // Test for unstable filter. If unstable keep old A(z)
+
+ if (sub (abs_s (Kh), 32750) > 0)
+ {
+ for (j = 0; j <= M; j++)
+ {
+ A[j] = st->old_A[j];
+ }
+
+ for (j = 0; j < 4; j++)
+ {
+ rc[j] = 0;
+ }
+
+ return 0;
+ }
+ *------------------------------------------*
+ * 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 = L_add(t0, L_Comp(Ah[j], Al[j]));
+ L_Extract (t0, &Anh[j], &Anl[j]);
+ }
+ t2 = L_shr (t2, 4);
+ L_Extract (t2, &Anh[i], &Anl[i]);
+
+ // Alpha = Alpha * (1-K**2)
+
+ t0 = Mpy_32 (Kh, Kl, Kh, Kl); // K*K
+ t0 = L_abs (t0); // Some case <0 !!
+ t0 = L_sub ((Word32) 0x7fffffffL, t0); // 1 - K*K
+ L_Extract (t0, &hi, &lo); // DPF format
+ t0 = Mpy_32 (alp_h, alp_l, hi, lo);
+
+ // Normalize Alpha
+
+ j = norm_l (t0);
+ t0 = L_shl (t0, j);
+ L_Extract (t0, &alp_h, &alp_l); // DPF format
+ alp_exp = add (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];
+ }
+ }
+
+ A[0] = 4096;
+ for (i = 1; i <= M; i++)
+ {
+ t0 = L_Comp (Ah[i], Al[i]);
+ st->old_A[i] = A[i] = pv_round (L_shl (t0, 1));
+ }
+
+ return 0;
+}
+
+------------------------------------------------------------------------------
+ RESOURCES USED [optional]
+
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ HEAP MEMORY USED: x bytes
+
+ STACK MEMORY USED: x bytes
+
+ CLOCK CYCLES: (cycle count equation for this function) + (variable
+ used to represent cycle count for each subroutine
+ called)
+ where: (cycle count variable) = cycle count for [subroutine
+ name]
+
+------------------------------------------------------------------------------
+ CAUTION [optional]
+ [State any special notes, constraints or cautions for users of this function]
+
+------------------------------------------------------------------------------
+*/
+
+Word16 Levinson(
+ LevinsonState *st,
+ Word16 Rh[], /* i : Rh[m+1] Vector of autocorrelations (msb) */
+ Word16 Rl[], /* i : Rl[m+1] Vector of autocorrelations (lsb) */
+ Word16 A[], /* o : A[m] LPC coefficients (m = 10) */
+ Word16 rc[], /* o : rc[4] First 4 reflection coefficients */
+ Flag *pOverflow
+)
+{
+ register Word16 i;
+ register Word16 j;
+ Word16 hi;
+ Word16 lo;
+ Word16 Kh; /* reflexion coefficient; hi and lo */
+ Word16 Kl;
+ Word16 alp_h; /* Prediction gain; hi lo and exponent*/
+ Word16 alp_l;
+ Word16 alp_exp;
+ Word16 Ah[M + 1]; /* LPC coef. in double prec. */
+ Word16 Al[M + 1];
+ Word16 Anh[M + 1]; /* LPC coef.for next iteration in */
+ Word16 Anl[M + 1]; /* double prec. */
+ register Word32 t0; /* temporary variable */
+ register Word32 t1; /* temporary variable */
+ register Word32 t2; /* temporary variable */
+
+ Word16 *p_Rh;
+ Word16 *p_Rl;
+ Word16 *p_Ah;
+ Word16 *p_Al;
+ Word16 *p_Anh;
+ Word16 *p_Anl;
+ Word16 *p_A;
+
+ /* K = A[1] = -R[1] / R[0] */
+ t1 = ((Word32) * (Rh + 1)) << 16;
+ t1 += *(Rl + 1) << 1;
+
+ t2 = L_abs(t1); /* abs R[1] - required by Div_32 */
+ t0 = Div_32(t2, *Rh, *Rl, pOverflow); /* R[1]/R[0] */
+
+ if (t1 > 0)
+ {
+ t0 = L_negate(t0); /* -R[1]/R[0] */
+ }
+
+ /* K in DPF */
+ Kh = (Word16)(t0 >> 16);
+ Kl = (Word16)((t0 >> 1) - ((Word32)(Kh) << 15));
+
+ *rc = pv_round(t0, pOverflow);
+
+ t0 = t0 >> 4;
+
+ /* A[1] in DPF */
+ *(Ah + 1) = (Word16)(t0 >> 16);
+
+ *(Al + 1) = (Word16)((t0 >> 1) - ((Word32)(*(Ah + 1)) << 15));
+
+ /* Alpha = R[0] * (1-K**2) */
+ t0 = Mpy_32(Kh, Kl, Kh, Kl, pOverflow); /* K*K */
+ t0 = L_abs(t0); /* Some case <0 !! */
+ t0 = 0x7fffffffL - t0; /* 1 - K*K */
+
+ /* DPF format */
+ hi = (Word16)(t0 >> 16);
+ lo = (Word16)((t0 >> 1) - ((Word32)(hi) << 15));
+
+ t0 = Mpy_32(*Rh, *Rl, hi, lo, pOverflow); /* Alpha in */
+
+ /* Normalize Alpha */
+
+ alp_exp = norm_l(t0);
+ t0 = t0 << alp_exp;
+
+ /* DPF format */
+ alp_h = (Word16)(t0 >> 16);
+ alp_l = (Word16)((t0 >> 1) - ((Word32)(alp_h) << 15));
+
+ /*--------------------------------------*
+ * 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;
+ p_Rh = &Rh[1];
+ p_Rl = &Rl[1];
+ p_Ah = &Ah[i-1];
+ p_Al = &Al[i-1];
+ for (j = 1; j < i; j++)
+ {
+ t0 += (((Word32) * (p_Rh)* *(p_Al--)) >> 15);
+ t0 += (((Word32) * (p_Rl++)* *(p_Ah)) >> 15);
+ t0 += ((Word32) * (p_Rh++)* *(p_Ah--));
+ }
+
+ t0 = t0 << 5;
+
+ t1 = ((Word32) * (Rh + i) << 16) + ((Word32)(*(Rl + i)) << 1);
+ t0 += t1;
+
+ /* K = -t0 / Alpha */
+
+ t1 = L_abs(t0);
+ t2 = Div_32(t1, alp_h, alp_l, pOverflow); /* abs(t0)/Alpha */
+
+ if (t0 > 0)
+ {
+ t2 = L_negate(t2); /* K =-t0/Alpha */
+ }
+
+ t2 = L_shl(t2, alp_exp, pOverflow); /* denormalize; compare to Alpha */
+ Kh = (Word16)(t2 >> 16);
+ Kl = (Word16)((t2 >> 1) - ((Word32)(Kh) << 15));
+
+ if (i < 5)
+ {
+ *(rc + i - 1) = (Word16)((t2 + 0x00008000L) >> 16);
+ }
+ /* Test for unstable filter. If unstable keep old A(z) */
+ if ((abs_s(Kh)) > 32750)
+ {
+ memcpy(A, &(st->old_A[0]), sizeof(Word16)*(M + 1));
+ memset(rc, 0, sizeof(Word16)*4);
+ return(0);
+ }
+ /*------------------------------------------*
+ * Compute new LPC coeff. -> An[i] *
+ * An[j]= A[j] + K*A[i-j] , j=1 to i-1 *
+ * An[i]= K *
+ *------------------------------------------*/
+ p_Ah = &Ah[i-1];
+ p_Al = &Al[i-1];
+ p_Anh = &Anh[1];
+ p_Anl = &Anl[1];
+ for (j = 1; j < i; j++)
+ {
+ t0 = (((Word32)Kh* *(p_Al--)) >> 15);
+ t0 += (((Word32)Kl* *(p_Ah)) >> 15);
+ t0 += ((Word32)Kh* *(p_Ah--));
+
+ t0 += (Ah[j] << 15) + Al[j];
+
+ *(p_Anh) = (Word16)(t0 >> 15);
+ *(p_Anl++) = (Word16)(t0 - ((Word32)(*(p_Anh++)) << 15));
+ }
+
+ *(p_Anh) = (Word16)(t2 >> 20);
+ *(p_Anl) = (Word16)((t2 >> 5) - ((Word32)(*(Anh + i)) << 15));
+
+ /* Alpha = Alpha * (1-K**2) */
+
+ t0 = Mpy_32(Kh, Kl, Kh, Kl, pOverflow); /* K*K */
+ t0 = L_abs(t0); /* Some case <0 !! */
+ t0 = 0x7fffffffL - t0; /* 1 - K*K */
+
+ hi = (Word16)(t0 >> 16);
+ lo = (Word16)((t0 >> 1) - ((Word32)(hi) << 15));
+
+ t0 = (((Word32)alp_h * lo) >> 15);
+ t0 += (((Word32)alp_l * hi) >> 15);
+ t0 += ((Word32)alp_h * hi);
+
+ t0 <<= 1;
+ /* Normalize Alpha */
+
+ j = norm_l(t0);
+ t0 <<= j;
+ alp_h = (Word16)(t0 >> 16);
+ alp_l = (Word16)((t0 >> 1) - ((Word32)(alp_h) << 15));
+ alp_exp += j; /* Add normalization to alp_exp */
+
+ /* A[j] = An[j] */
+ memcpy(&Ah[1], &Anh[1], sizeof(Word16)*i);
+ memcpy(&Al[1], &Anl[1], sizeof(Word16)*i);
+ }
+
+ p_A = &A[0];
+ *(p_A++) = 4096;
+ p_Ah = &Ah[1];
+ p_Al = &Al[1];
+
+ for (i = 1; i <= M; i++)
+ {
+ t0 = ((Word32) * (p_Ah++) << 15) + *(p_Al++);
+ st->old_A[i] = *(p_A++) = (Word16)((t0 + 0x00002000) >> 14);
+ }
+
+ return(0);
+}