1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
30 ------------------------------------------------------------------------------
34 Filename: levinson.cpp
35 Funtions: Levinson_init
40 ------------------------------------------------------------------------------
43 This file contains the function the implements the Levinson-Durbin algorithm
44 using double-precision arithmetic. This file also includes functions to
45 initialize, allocate, and deallocate memory used by the Levinson function.
47 ------------------------------------------------------------------------------
50 /*----------------------------------------------------------------------------
52 ----------------------------------------------------------------------------*/
54 #include "basicop_malloc.h"
61 /*----------------------------------------------------------------------------
63 ; Define module specific macros here
64 ----------------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------------
68 ; Include all pre-processor statements here. Include conditional
69 ; compile variables also.
70 ----------------------------------------------------------------------------*/
72 /*----------------------------------------------------------------------------
73 ; LOCAL FUNCTION DEFINITIONS
74 ; Function Prototype declaration
75 ----------------------------------------------------------------------------*/
77 /*----------------------------------------------------------------------------
78 ; LOCAL VARIABLE DEFINITIONS
79 ; Variable declaration - defined here and used outside this module
80 ----------------------------------------------------------------------------*/
84 ------------------------------------------------------------------------------
85 FUNCTION NAME: Levinson_init
86 ------------------------------------------------------------------------------
87 INPUT AND OUTPUT DEFINITIONS
90 state = pointer to an array of pointers to structures of type
94 pointer pointed to by state points to the newly allocated memory to
95 be used by Levinson function
98 return_value = 0, if initialization was successful; -1, otherwise (int)
100 Global Variables Used:
103 Local Variables Needed:
106 ------------------------------------------------------------------------------
109 This function allocates and initializes the state memory used by the
112 ------------------------------------------------------------------------------
117 ------------------------------------------------------------------------------
120 levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
122 ------------------------------------------------------------------------------
125 int Levinson_init (LevinsonState **state)
129 if (state == (LevinsonState **) NULL){
130 //fprint(stderr, "Levinson_init: invalid parameter\n");
136 if ((s= (LevinsonState *) malloc(sizeof(LevinsonState))) == NULL){
137 //fprint(stderr, "Levinson_init: can not malloc state structure\n");
147 ------------------------------------------------------------------------------
149 [State any special notes, constraints or cautions for users of this function]
151 ------------------------------------------------------------------------------
154 Word16 Levinson_init(LevinsonState **state)
158 if (state == (LevinsonState **) NULL)
160 /* fprint(stderr, "Levinson_init: invalid parameter\n"); */
165 /* allocate memory */
166 if ((s = (LevinsonState *) oscl_malloc(sizeof(LevinsonState))) == NULL)
168 /* fprint(stderr, "Levinson_init:
169 can not malloc state structure\n"); */
179 /****************************************************************************/
183 ------------------------------------------------------------------------------
184 FUNCTION NAME: Levinson_reset
185 ------------------------------------------------------------------------------
186 INPUT AND OUTPUT DEFINITIONS
189 state = pointer to structures of type LevinsonState
192 old_A field of structure pointed to by state is initialized to 4096
193 (first location) and the rest to zeros
196 return_value = 0, if reset was successful; -1, otherwise (int)
198 Global Variables Used:
201 Local Variables Needed:
204 ------------------------------------------------------------------------------
207 This function initializes the state memory used by the Levinson function to
210 ------------------------------------------------------------------------------
215 ------------------------------------------------------------------------------
218 levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
220 ------------------------------------------------------------------------------
223 int Levinson_reset (LevinsonState *state)
227 if (state == (LevinsonState *) NULL){
228 fprint(stderr, "Levinson_reset: invalid parameter\n");
232 state->old_A[0] = 4096;
233 for(i = 1; i < M + 1; i++)
239 ------------------------------------------------------------------------------
241 [State any special notes, constraints or cautions for users of this function]
243 ------------------------------------------------------------------------------
246 Word16 Levinson_reset(LevinsonState *state)
250 if (state == (LevinsonState *) NULL)
252 /* fprint(stderr, "Levinson_reset: invalid parameter\n"); */
256 state->old_A[0] = 4096;
257 for (i = 1; i < M + 1; i++)
265 /****************************************************************************/
268 ------------------------------------------------------------------------------
269 FUNCTION NAME: Levinson_exit
270 ------------------------------------------------------------------------------
271 INPUT AND OUTPUT DEFINITIONS
274 state = pointer to an array of pointers to structures of type
278 pointer pointed to by state is set to the NULL address
283 Global Variables Used:
286 Local Variables Needed:
289 ------------------------------------------------------------------------------
292 This function deallocates the state memory used by the Levinson function.
294 ------------------------------------------------------------------------------
299 ------------------------------------------------------------------------------
302 levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
304 ------------------------------------------------------------------------------
307 void Levinson_exit (LevinsonState **state)
309 if (state == NULL || *state == NULL)
319 ------------------------------------------------------------------------------
321 [State any special notes, constraints or cautions for users of this function]
323 ------------------------------------------------------------------------------
326 void Levinson_exit(LevinsonState **state)
328 if (state == NULL || *state == NULL)
333 /* deallocate memory */
340 /****************************************************************************/
344 ------------------------------------------------------------------------------
345 FUNCTION NAME: Levinson
346 ------------------------------------------------------------------------------
347 INPUT AND OUTPUT DEFINITIONS
350 st = pointer to structures of type LevinsonState
351 Rh = vector containing most significant byte of
352 autocorrelation values (Word16)
353 Rl = vector containing least significant byte of
354 autocorrelation values (Word16)
355 A = vector of LPC coefficients (10th order) (Word16)
356 rc = vector containing first four reflection coefficients (Word16)
357 pOverflow = pointer to overflow indicator (Flag)
360 A contains the newly calculated LPC coefficients
361 rc contains the newly calculated reflection coefficients
364 return_value = 0 (int)
366 Global Variables Used:
369 Local Variables Needed:
372 ------------------------------------------------------------------------------
375 This function implements the Levinson-Durbin algorithm using double-
376 precision arithmetic. This is used to compute the Linear Predictive (LP)
377 filter parameters from the speech autocorrelation values.
379 The algorithm implemented is as follows:
383 Alpha = R[0] * (1-K**2]
387 S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i]
391 An[j] = A[j] + K*A[i-j] where An[i] = new A[i]
395 Alpha=Alpha * (1-K**2)
400 R[i] = autocorrelations
401 A[i] = filter coefficients
402 K = reflection coefficient
403 Alpha = prediction gain
405 ------------------------------------------------------------------------------
410 ------------------------------------------------------------------------------
413 levinson.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
415 ------------------------------------------------------------------------------
420 Word16 Rh[], // i : Rh[m+1] Vector of autocorrelations (msb)
421 Word16 Rl[], // i : Rl[m+1] Vector of autocorrelations (lsb)
422 Word16 A[], // o : A[m] LPC coefficients (m = 10)
423 Word16 rc[] // o : rc[4] First 4 reflection coefficients
428 Word16 Kh, Kl; // reflexion coefficient; hi and lo
429 Word16 alp_h, alp_l, alp_exp; // Prediction gain; hi lo and exponent
430 Word16 Ah[M + 1], Al[M + 1]; // LPC coef. in double prec.
431 Word16 Anh[M + 1], Anl[M + 1];// LPC coef.for next iteration in double
433 Word32 t0, t1, t2; // temporary variable
435 // K = A[1] = -R[1] / R[0]
437 t1 = L_Comp (Rh[1], Rl[1]);
438 t2 = L_abs (t1); // abs R[1]
439 t0 = Div_32 (t2, Rh[0], Rl[0]); // R[1]/R[0]
441 t0 = L_negate (t0); // -R[1]/R[0]
442 L_Extract (t0, &Kh, &Kl); // K in DPF
444 rc[0] = pv_round (t0);
446 t0 = L_shr (t0, 4); // A[1] in
447 L_Extract (t0, &Ah[1], &Al[1]); // A[1] in DPF
449 // Alpha = R[0] * (1-K**2)
451 t0 = Mpy_32 (Kh, Kl, Kh, Kl); // K*K
452 t0 = L_abs (t0); // Some case <0 !!
453 t0 = L_sub ((Word32) 0x7fffffffL, t0); // 1 - K*K
454 L_Extract (t0, &hi, &lo); // DPF format
455 t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); // Alpha in
459 alp_exp = norm_l (t0);
460 t0 = L_shl (t0, alp_exp);
461 L_Extract (t0, &alp_h, &alp_l); // DPF format
463 *--------------------------------------*
464 * ITERATIONS I=2 to M *
465 *--------------------------------------*
467 for (i = 2; i <= M; i++)
469 // t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i]
472 for (j = 1; j < i; j++)
474 t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j]));
478 t1 = L_Comp (Rh[i], Rl[i]);
479 t0 = L_add (t0, t1); // add R[i]
484 t2 = Div_32 (t1, alp_h, alp_l); // abs(t0)/Alpha
486 t2 = L_negate (t2); // K =-t0/Alpha
487 t2 = L_shl (t2, alp_exp); // denormalize; compare to Alpha
488 L_Extract (t2, &Kh, &Kl); // K in DPF
492 rc[i - 1] = pv_round (t2);
494 // Test for unstable filter. If unstable keep old A(z)
496 if (sub (abs_s (Kh), 32750) > 0)
498 for (j = 0; j <= M; j++)
503 for (j = 0; j < 4; j++)
510 *------------------------------------------*
511 * Compute new LPC coeff. -> An[i] *
512 * An[j]= A[j] + K*A[i-j] , j=1 to i-1 *
514 *------------------------------------------*
516 for (j = 1; j < i; j++)
518 t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]);
519 t0 = L_add(t0, L_Comp(Ah[j], Al[j]));
520 L_Extract (t0, &Anh[j], &Anl[j]);
523 L_Extract (t2, &Anh[i], &Anl[i]);
525 // Alpha = Alpha * (1-K**2)
527 t0 = Mpy_32 (Kh, Kl, Kh, Kl); // K*K
528 t0 = L_abs (t0); // Some case <0 !!
529 t0 = L_sub ((Word32) 0x7fffffffL, t0); // 1 - K*K
530 L_Extract (t0, &hi, &lo); // DPF format
531 t0 = Mpy_32 (alp_h, alp_l, hi, lo);
537 L_Extract (t0, &alp_h, &alp_l); // DPF format
538 alp_exp = add (alp_exp, j); // Add normalization to
543 for (j = 1; j <= i; j++)
551 for (i = 1; i <= M; i++)
553 t0 = L_Comp (Ah[i], Al[i]);
554 st->old_A[i] = A[i] = pv_round (L_shl (t0, 1));
560 ------------------------------------------------------------------------------
562 [State any special notes, constraints or cautions for users of this function]
564 ------------------------------------------------------------------------------
569 Word16 Rh[], /* i : Rh[m+1] Vector of autocorrelations (msb) */
570 Word16 Rl[], /* i : Rl[m+1] Vector of autocorrelations (lsb) */
571 Word16 A[], /* o : A[m] LPC coefficients (m = 10) */
572 Word16 rc[], /* o : rc[4] First 4 reflection coefficients */
580 Word16 Kh; /* reflexion coefficient; hi and lo */
582 Word16 alp_h; /* Prediction gain; hi lo and exponent*/
585 Word16 Ah[M + 1]; /* LPC coef. in double prec. */
587 Word16 Anh[M + 1]; /* LPC coef.for next iteration in */
588 Word16 Anl[M + 1]; /* double prec. */
589 register Word32 t0; /* temporary variable */
590 register Word32 t1; /* temporary variable */
591 register Word32 t2; /* temporary variable */
601 /* K = A[1] = -R[1] / R[0] */
602 t1 = ((Word32) * (Rh + 1)) << 16;
603 t1 += *(Rl + 1) << 1;
605 t2 = L_abs(t1); /* abs R[1] - required by Div_32 */
606 t0 = Div_32(t2, *Rh, *Rl, pOverflow); /* R[1]/R[0] */
610 t0 = L_negate(t0); /* -R[1]/R[0] */
614 Kh = (Word16)(t0 >> 16);
615 Kl = (Word16)((t0 >> 1) - ((Word32)(Kh) << 15));
617 *rc = pv_round(t0, pOverflow);
622 *(Ah + 1) = (Word16)(t0 >> 16);
624 *(Al + 1) = (Word16)((t0 >> 1) - ((Word32)(*(Ah + 1)) << 15));
626 /* Alpha = R[0] * (1-K**2) */
627 t0 = Mpy_32(Kh, Kl, Kh, Kl, pOverflow); /* K*K */
628 t0 = L_abs(t0); /* Some case <0 !! */
629 t0 = 0x7fffffffL - t0; /* 1 - K*K */
632 hi = (Word16)(t0 >> 16);
633 lo = (Word16)((t0 >> 1) - ((Word32)(hi) << 15));
635 t0 = Mpy_32(*Rh, *Rl, hi, lo, pOverflow); /* Alpha in */
637 /* Normalize Alpha */
639 alp_exp = norm_l(t0);
643 alp_h = (Word16)(t0 >> 16);
644 alp_l = (Word16)((t0 >> 1) - ((Word32)(alp_h) << 15));
646 /*--------------------------------------*
647 * ITERATIONS I=2 to M *
648 *--------------------------------------*/
650 for (i = 2; i <= M; i++)
652 /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */
659 for (j = 1; j < i; j++)
661 t0 += (((Word32) * (p_Rh)* *(p_Al--)) >> 15);
662 t0 += (((Word32) * (p_Rl++)* *(p_Ah)) >> 15);
663 t0 += ((Word32) * (p_Rh++)* *(p_Ah--));
668 t1 = ((Word32) * (Rh + i) << 16) + ((Word32)(*(Rl + i)) << 1);
671 /* K = -t0 / Alpha */
674 t2 = Div_32(t1, alp_h, alp_l, pOverflow); /* abs(t0)/Alpha */
678 t2 = L_negate(t2); /* K =-t0/Alpha */
681 t2 = L_shl(t2, alp_exp, pOverflow); /* denormalize; compare to Alpha */
682 Kh = (Word16)(t2 >> 16);
683 Kl = (Word16)((t2 >> 1) - ((Word32)(Kh) << 15));
687 *(rc + i - 1) = (Word16)((t2 + 0x00008000L) >> 16);
689 /* Test for unstable filter. If unstable keep old A(z) */
690 if ((abs_s(Kh)) > 32750)
692 oscl_memcpy(A, &(st->old_A[0]), sizeof(Word16)*(M + 1));
693 oscl_memset(rc, 0, sizeof(Word16)*4);
696 /*------------------------------------------*
697 * Compute new LPC coeff. -> An[i] *
698 * An[j]= A[j] + K*A[i-j] , j=1 to i-1 *
700 *------------------------------------------*/
705 for (j = 1; j < i; j++)
707 t0 = (((Word32)Kh* *(p_Al--)) >> 15);
708 t0 += (((Word32)Kl* *(p_Ah)) >> 15);
709 t0 += ((Word32)Kh* *(p_Ah--));
711 t0 += (Ah[j] << 15) + Al[j];
713 *(p_Anh) = (Word16)(t0 >> 15);
714 *(p_Anl++) = (Word16)(t0 - ((Word32)(*(p_Anh++)) << 15));
717 *(p_Anh) = (Word16)(t2 >> 20);
718 *(p_Anl) = (Word16)((t2 >> 5) - ((Word32)(*(Anh + i)) << 15));
720 /* Alpha = Alpha * (1-K**2) */
722 t0 = Mpy_32(Kh, Kl, Kh, Kl, pOverflow); /* K*K */
723 t0 = L_abs(t0); /* Some case <0 !! */
724 t0 = 0x7fffffffL - t0; /* 1 - K*K */
726 hi = (Word16)(t0 >> 16);
727 lo = (Word16)((t0 >> 1) - ((Word32)(hi) << 15));
729 t0 = (((Word32)alp_h * lo) >> 15);
730 t0 += (((Word32)alp_l * hi) >> 15);
731 t0 += ((Word32)alp_h * hi);
734 /* Normalize Alpha */
738 alp_h = (Word16)(t0 >> 16);
739 alp_l = (Word16)((t0 >> 1) - ((Word32)(alp_h) << 15));
740 alp_exp += j; /* Add normalization to alp_exp */
743 oscl_memcpy(&Ah[1], &Anh[1], sizeof(Word16)*i);
744 oscl_memcpy(&Al[1], &Anl[1], sizeof(Word16)*i);
752 for (i = 1; i <= M; i++)
754 t0 = ((Word32) * (p_Ah++) << 15) + *(p_Al++);
755 st->old_A[i] = *(p_A++) = (Word16)((t0 + 0x00002000) >> 14);