Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      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
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     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
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /****************************************************************************************
     19 Portions of this file are derived from the following 3GPP standard:
     20 
     21     3GPP TS 26.073
     22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
     23     Available from http://www.3gpp.org
     24 
     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 ****************************************************************************************/
     29 /*
     30 
     31  Pathname: ./audio/gsm-amr/c/src/lsp_az.c
     32  Funtions: Get_lsp_pol
     33            Lsp_Az
     34 
     35 ------------------------------------------------------------------------------
     36  REVISION HISTORY
     37 
     38  Description: Updated template used to PV coding template. First attempt at
     39           optimizing C code.
     40 
     41  Description: Deleted all Local stores needed/modified. Optimized Lsp_Az
     42           function by getting rid of call to L_shr_r function.
     43 
     44  Description: Updated file per comments gathered from Phase 2/3 review.
     45 
     46  Description: Added setting of Overflow flag in the inlined code.
     47 
     48  Description: 1. Optimized Lsp_Az function code.
     49               2. Changed Input/Output definitions by adding Word type.
     50 
     51  Description: Made changes based on review meeting.
     52               1. Removed pseudocode.
     53 
     54  Description: Synchronized file with UMTS version 3.2.0. Updated coding
     55               template. Removed unnecessary include files.
     56 
     57  Description: Replaced basic_op.h and oper_32b.h with the header files of the
     58               math functions used in the file.
     59 
     60  Description: Modified to pass overflow flag through to L_add and L_sub.  The
     61  flag is passed back to the calling function by pointer reference.
     62 
     63  Description: Removed the id line since it was removed in the header file by
     64               Ken.
     65 
     66  Description: Added the write-only variable, pOverflow, to the inputs section.
     67 
     68  Description:  For lsp_az() and Get_lsp_pol()
     69               1. Eliminated unused include files.
     70               2. Replaced array addressing by pointers
     71               3. Eliminated math operations that unnecessary checked for
     72                  saturation, in some cases this by shifting before adding and
     73                  in other cases by evaluating the operands
     74               4. Unrolled loops to speed up processing
     75               5. Replaced mpy_32_16 by multpilcations in place
     76               6. Eliminated if-else statements for sign extension when
     77                  right-shifting
     78 
     79  Description:  Added casting to eliminate warnings, and eliminated include
     80                files that now are chosen by OSCL definitions
     81 
     82  Description:  Replaced "int" and/or "char" with defined types.
     83                Added proper casting (Word32) to some left shifting operations
     84 
     85  Who:                           Date:
     86  Description:
     87 
     88 ------------------------------------------------------------------------------
     89  MODULE DESCRIPTION
     90 
     91  This file contains functions that convert line spectral pairs (LSP) to
     92  linear predictive (LP) coefficients (filter order = 10). The functions
     93  included in this file include Get_lsp_pol, which finds the coefficients of
     94  F1(z) and F2(z), and Lsp_Az, which converts LSP to LPC by multiplying
     95  F1(z) by 1+z^(-1) and F2(z) by 1-z^(-1), then calculating A(z) = (F1(z) +
     96  F2(z))/2.
     97 
     98 ------------------------------------------------------------------------------
     99 */
    100 
    101 /*----------------------------------------------------------------------------
    102 ; INCLUDES
    103 ----------------------------------------------------------------------------*/
    104 #include "lsp_az.h"
    105 
    106 /*----------------------------------------------------------------------------
    107 ; MACROS
    108 ; Define module specific macros here
    109 ----------------------------------------------------------------------------*/
    110 
    111 /*----------------------------------------------------------------------------
    112 ; DEFINES
    113 ; Include all pre-processor statements here. Include conditional
    114 ; compile variables also.
    115 ----------------------------------------------------------------------------*/
    116 
    117 /*----------------------------------------------------------------------------
    118 ; LOCAL FUNCTION DEFINITIONS
    119 ; Function Prototype declaration
    120 ----------------------------------------------------------------------------*/
    121 
    122 /*----------------------------------------------------------------------------
    123 ; LOCAL VARIABLE DEFINITIONS
    124 ; Variable declaration - defined here and used outside this module
    125 ----------------------------------------------------------------------------*/
    126 
    127 
    128 /*
    129 ------------------------------------------------------------------------------
    130  FUNCTION NAME: Get_lsp_pol
    131 ------------------------------------------------------------------------------
    132  INPUT AND OUTPUT DEFINITIONS
    133 
    134  Inputs:
    135     lsp = pointer to the buffer containing the line spectral pairs (LSP)
    136           of type Word16
    137     f = pointer to the polynomial of type Word32 to be generated
    138 
    139     pOverflow  = pointer set in case where one of the operations overflows.
    140                  [data type Pointer to Flag]
    141 
    142  Outputs:
    143     buffer pointed to by f contains the polynomial generated
    144 
    145     pOverflow  = pointer set in case where one of the operations overflows.
    146                  [data type Pointer to Flag]
    147 
    148  Returns:
    149     None
    150 
    151  Global Variables Used:
    152     None
    153 
    154  Local Variables Needed:
    155     None
    156 
    157 ------------------------------------------------------------------------------
    158  FUNCTION DESCRIPTION
    159 
    160  This function finds the polynomial F1(z) or F2(z) from the LSPs. If the LSP
    161  vector is passed at address 0, F1(z) is computed and if it is passed at
    162  address 1, F2(z) is computed.
    163 
    164  This is performed by expanding the product polynomials:
    165 
    166     F1(z) =   product   ( 1 - 2 lsp[i] z^-1 + z^-2 )
    167         i=0,2,4,6,8
    168     F2(z) =   product   ( 1 - 2 lsp[i] z^-1 + z^-2 )
    169         i=1,3,5,7,9
    170 
    171  where lsp[] is the LSP vector in the cosine domain.
    172 
    173  The expansion is performed using the following recursion:
    174 
    175     f[0] = 1
    176     b = -2.0 * lsp[0]
    177     f[1] = b
    178     for i=2 to 5 do
    179         b = -2.0 * lsp[2*i-2];
    180         for j=i-1 down to 2 do
    181             f[j] = f[j] + b*f[j-1] + f[j-2];
    182         f[1] = f[1] + b;
    183 
    184 ------------------------------------------------------------------------------
    185  REQUIREMENTS
    186 
    187  None
    188 
    189 ------------------------------------------------------------------------------
    190  REFERENCES
    191 
    192  lsp_az.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    193 
    194 ------------------------------------------------------------------------------
    195  PSEUDO-CODE
    196 
    197 static void Get_lsp_pol (Word16 *lsp, Word32 *f)
    198 {
    199     Word16 i, j, hi, lo;
    200     Word32 t0;
    201 
    202     // f[0] = 1.0;
    203     *f = L_mult (4096, 2048);
    204     f++;
    205     *f = L_msu ((Word32) 0, *lsp, 512);    // f[1] =  -2.0 * lsp[0];
    206     f++;
    207     lsp += 2;                              // Advance lsp pointer
    208 
    209     for (i = 2; i <= 5; i++)
    210     {
    211         *f = f[-2];
    212 
    213         for (j = 1; j < i; j++, f--)
    214         {
    215             L_Extract (f[-1], &hi, &lo);
    216             t0 = Mpy_32_16 (hi, lo, *lsp); // t0 = f[-1] * lsp
    217             t0 = L_shl (t0, 1);
    218             *f = L_add (*f, f[-2]); // *f += f[-2]
    219             *f = L_sub (*f, t0); // *f -= t0
    220         }
    221         *f = L_msu (*f, *lsp, 512); // *f -= lsp<<9
    222         f += i;                            // Advance f pointer
    223         lsp += 2;                          // Advance lsp pointer
    224     }
    225 
    226     return;
    227 }
    228 
    229 ------------------------------------------------------------------------------
    230  RESOURCES USED [optional]
    231 
    232  When the code is written for a specific target processor the
    233  the resources used should be documented below.
    234 
    235  HEAP MEMORY USED: x bytes
    236 
    237  STACK MEMORY USED: x bytes
    238 
    239  CLOCK CYCLES: (cycle count equation for this function) + (variable
    240                 used to represent cycle count for each subroutine
    241                 called)
    242      where: (cycle count variable) = cycle count for [subroutine
    243                                      name]
    244 
    245 ------------------------------------------------------------------------------
    246  CAUTION [optional]
    247  [State any special notes, constraints or cautions for users of this function]
    248 
    249 ------------------------------------------------------------------------------
    250 */
    251 
    252 static void Get_lsp_pol(
    253     Word16 *lsp,
    254     Word32 *f,
    255     Flag   *pOverflow)
    256 {
    257     Word16 i;
    258     Word16 j;
    259 
    260     Word16 hi;
    261     Word16 lo;
    262     Word32 t0;
    263     OSCL_UNUSED_ARG(pOverflow);
    264 
    265     /* f[0] = 1.0;             */
    266     *f++ = (Word32) 0x01000000;
    267     *f++ = (Word32) - *(lsp++) << 10;       /* f[1] =  -2.0 * lsp[0];  */
    268     lsp++;                                  /* Advance lsp pointer     */
    269 
    270     for (i = 2; i <= 5; i++)
    271     {
    272         *f = *(f - 2);
    273 
    274         for (j = 1; j < i; j++)
    275         {
    276             hi = (Word16)(*(f - 1) >> 16);
    277 
    278             lo = (Word16)((*(f - 1) >> 1) - ((Word32) hi << 15));
    279 
    280             t0  = ((Word32)hi * *lsp);
    281             t0 += ((Word32)lo * *lsp) >> 15;
    282 
    283             *(f) +=  *(f - 2);          /*      *f += f[-2]      */
    284             *(f--) -=  t0 << 2;         /*      *f -= t0         */
    285 
    286         }
    287 
    288         *f -= (Word32)(*lsp++) << 10;
    289 
    290         f  += i;
    291         lsp++;
    292     }
    293 
    294     return;
    295 }
    296 
    297 /****************************************************************************/
    298 
    299 
    300 /*
    301 ------------------------------------------------------------------------------
    302  FUNCTION NAME: Get_lsp_pol_wrapper
    303 ------------------------------------------------------------------------------
    304  INPUT AND OUTPUT DEFINITIONS
    305 
    306  Inputs:
    307     lsp = pointer to the buffer containing the line spectral pairs (LSP)
    308           of type Word16
    309     f = pointer to the polynomial of type Word32 to be generated
    310 
    311     pOverflow  = pointer set in case where one of the operations overflows.
    312                  [data type Pointer to Flag]
    313 
    314  Outputs:
    315     buffer pointed to by f contains the polynomial generated
    316 
    317     pOverflow  = pointer set in case where one of the operations overflows.
    318                  [data type Pointer to Flag]
    319 
    320  Returns:
    321     None
    322 
    323  Global Variables Used:
    324     None
    325 
    326  Local Variables Needed:
    327     None
    328 
    329 ------------------------------------------------------------------------------
    330  FUNCTION DESCRIPTION
    331 
    332  This function provides external access to the static function Get_lsp_pol.
    333 
    334 ------------------------------------------------------------------------------
    335  REQUIREMENTS
    336 
    337  None
    338 
    339 ------------------------------------------------------------------------------
    340  REFERENCES
    341 
    342  None
    343 
    344 ------------------------------------------------------------------------------
    345  PSEUDO-CODE
    346 
    347  CALL Get_lsp_pol(lsp = lsp_ptr
    348                   f = f_ptr )
    349    MODIFYING(nothing)
    350    RETURNING(nothing)
    351 
    352 ------------------------------------------------------------------------------
    353  RESOURCES USED [optional]
    354 
    355  When the code is written for a specific target processor the
    356  the resources used should be documented below.
    357 
    358  HEAP MEMORY USED: x bytes
    359 
    360  STACK MEMORY USED: x bytes
    361 
    362  CLOCK CYCLES: (cycle count equation for this function) + (variable
    363                 used to represent cycle count for each subroutine
    364                 called)
    365      where: (cycle count variable) = cycle count for [subroutine
    366                                      name]
    367 
    368 ------------------------------------------------------------------------------
    369  CAUTION [optional]
    370  [State any special notes, constraints or cautions for users of this function]
    371 
    372 ------------------------------------------------------------------------------
    373 */
    374 
    375 void Get_lsp_pol_wrapper(
    376     Word16 *lsp,
    377     Word32 *f,
    378     Flag   *pOverflow)
    379 {
    380     /*----------------------------------------------------------------------------
    381      CALL Get_lsp_pol(lsp = lsp_ptr
    382               f = f_ptr )
    383     ----------------------------------------------------------------------------*/
    384     Get_lsp_pol(lsp, f, pOverflow);
    385 
    386     /*----------------------------------------------------------------------------
    387        MODIFYING(nothing)
    388        RETURNING(nothing)
    389     ----------------------------------------------------------------------------*/
    390     return;
    391 }
    392 
    393 /****************************************************************************/
    394 
    395 
    396 /*
    397 ------------------------------------------------------------------------------
    398  FUNCTION NAME: Lsp_Az
    399 ------------------------------------------------------------------------------
    400  INPUT AND OUTPUT DEFINITIONS
    401 
    402  Inputs:
    403     lsp = pointer to the buffer containing the line spectral pairs (LSP)
    404           of type Word16
    405 
    406       a = pointer to the buffer containing Linear Predictive (LP)
    407           coefficients of type Word16 to be generated
    408 
    409     pOverflow  = pointer set in case where one of the operations overflows.
    410                  [data type Pointer to Flag]
    411 
    412  Local Stores/Buffers/Pointers Needed:
    413     None
    414 
    415  Global Stores/Buffers/Pointers Needed:
    416     None
    417 
    418  Outputs:
    419     pOverflow  = pointer set in case where one of the operations overflows.
    420                  [data type Pointer to Flag]
    421 
    422  Pointers and Buffers Modified:
    423     a buffer contains the generated Linear Predictive (LP) coefficients
    424 
    425  Local Stores Modified:
    426     None
    427 
    428  Global Stores Modified:
    429         None
    430 
    431 ------------------------------------------------------------------------------
    432  FUNCTION DESCRIPTION
    433 
    434  This function converts from the line spectral pairs (LSP) to LP coefficients
    435  for a 10th order filter.
    436 
    437  This is done by:
    438     (1) Find the coefficients of F1(z) and F2(z) (see Get_lsp_pol)
    439     (2) Multiply F1(z) by 1+z^{-1} and F2(z) by 1-z^{-1}
    440     (3) A(z) = ( F1(z) + F2(z) ) / 2
    441 
    442 ------------------------------------------------------------------------------
    443  REQUIREMENTS
    444 
    445  None
    446 
    447 ------------------------------------------------------------------------------
    448  REFERENCES
    449 
    450  lsp_az.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    451 
    452 ------------------------------------------------------------------------------
    453  PSEUDO-CODE
    454 
    455 void Lsp_Az (
    456     Word16 lsp[],        // (i)  : line spectral frequencies
    457     Word16 a[]           // (o)  : predictor coefficients (order = 10)
    458 )
    459 {
    460     Word16 i, j;
    461     Word32 f1[6], f2[6];
    462     Word32 t0;
    463 
    464     Get_lsp_pol (&lsp[0], f1);
    465     Get_lsp_pol (&lsp[1], f2);
    466 
    467     for (i = 5; i > 0; i--)
    468     {
    469         f1[i] = L_add (f1[i], f1[i - 1]); // f1[i] += f1[i-1];
    470         f2[i] = L_sub (f2[i], f2[i - 1]); // f2[i] -= f2[i-1];
    471     }
    472 
    473     a[0] = 4096;
    474     for (i = 1, j = 10; i <= 5; i++, j--)
    475     {
    476         t0 = L_add (f1[i], f2[i]);           // f1[i] + f2[i]
    477         a[i] = extract_l (L_shr_r (t0, 13));
    478         t0 = L_sub (f1[i], f2[i]);           // f1[i] - f2[i]
    479         a[j] = extract_l (L_shr_r (t0, 13));
    480     }
    481 
    482     return;
    483 }
    484 
    485 ------------------------------------------------------------------------------
    486  RESOURCES USED [optional]
    487 
    488  When the code is written for a specific target processor the
    489  the resources used should be documented below.
    490 
    491  HEAP MEMORY USED: x bytes
    492 
    493  STACK MEMORY USED: x bytes
    494 
    495  CLOCK CYCLES: (cycle count equation for this function) + (variable
    496                 used to represent cycle count for each subroutine
    497                 called)
    498      where: (cycle count variable) = cycle count for [subroutine
    499                                      name]
    500 
    501 ------------------------------------------------------------------------------
    502  CAUTION [optional]
    503  [State any special notes, constraints or cautions for users of this function]
    504 
    505 ------------------------------------------------------------------------------
    506 */
    507 
    508 void Lsp_Az(
    509     Word16 lsp[],        /* (i)  : line spectral frequencies            */
    510     Word16 a[],          /* (o)  : predictor coefficients (order = 10)  */
    511     Flag  *pOverflow     /* (o)  : overflow flag                        */
    512 )
    513 {
    514     Word16 i;
    515     Word16 j;
    516 
    517     Word32 f1[6];
    518     Word32 f2[6];
    519     Word32 t0;
    520     Word32 t1;
    521     Word16 *p_a = &a[0];
    522     Word32 *p_f1;
    523     Word32 *p_f2;
    524 
    525     Get_lsp_pol(&lsp[0], f1, pOverflow);
    526 
    527     Get_lsp_pol(&lsp[1], f2, pOverflow);
    528 
    529     p_f1 = &f1[5];
    530     p_f2 = &f2[5];
    531 
    532     for (i = 5; i > 0; i--)
    533     {
    534         *(p_f1--) += f1[i-1];
    535         *(p_f2--) -= f2[i-1];
    536     }
    537 
    538     *(p_a++) = 4096;
    539     p_f1 = &f1[1];
    540     p_f2 = &f2[1];
    541 
    542     for (i = 1, j = 10; i <= 5; i++, j--)
    543     {
    544         t0 = *(p_f1) + *(p_f2);               /* f1[i] + f2[i] */
    545         t1 = *(p_f1++) - *(p_f2++);           /* f1[i] - f2[i] */
    546 
    547         t0 = t0 + ((Word32) 1 << 12);
    548         t1 = t1 + ((Word32) 1 << 12);
    549 
    550         *(p_a++) = (Word16)(t0 >> 13);
    551         a[j]     = (Word16)(t1 >> 13);
    552     }
    553 
    554     return;
    555 }
    556