Home | History | Annotate | Download | only in aacdec
      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 
     20  Pathname: tns_ar_filter.c
     21 
     22 ------------------------------------------------------------------------------
     23  REVISION HISTORY
     24 
     25  Description:  Modified from original shareware code
     26 
     27  Description:  Implemented 24-bit fixed point version
     28                Optimized C code
     29 
     30  Description:
     31             - Added OVERFLOW_SHIFT_DOWN to avoid overflow.
     32             - Increased precision by using the Q format of the LPC coefficient.
     33             - Modified interface to add LPC Q format and scratch memory
     34               for the state variables.
     35             - Added pv_memset to clear state filter
     36             - Updated format for comments (to PV standard)
     37             - Updated copyright notice
     38 
     39  Description:
     40             - Changed multiplication scheme to increase precision. This
     41               works better than older version.
     42 
     43  Description:
     44             - Include log2(order) as a scaling down parameter.
     45 
     46  Description:
     47             Modified to reflect code review comments
     48                 - misspelled words, extra comments and explicit requirements
     49 
     50  Description:
     51             deleted comment about fix Q format (L 107)
     52 
     53  Description:  Implemented a more efficient version, which eliminated the use
     54  of "scratch memory" via introducing a pointer that references the actual
     55  output.
     56 
     57  Description: Removed the parameter "scratch_Int32_buffer" as this space
     58  in memory is no longer needed by this function.
     59 
     60  Description: Removed references to "scratch_Int32_buffer" in the Inputs
     61  section.
     62 
     63  Description:
     64     Modified casting to ensure proper operations for different platforms
     65 
     66  Description:
     67     Per code review comment:
     68     Eliminated casting to UInt and Int in b_low and b_high, they are
     69     redundant and may add unncessary extra cycles in some platforms
     70 
     71  Description: Updated the SW template to include the full pathname to the
     72  source file and a slightly modified copyright header.
     73 
     74  Description: Changed the order of the unsigned * signed multiply so the
     75  casting to Int32 is performed on the unsigned operand.
     76 
     77  Description:
     78     Modified 32 by 16 bit multiplications to avoid unnecessary moves to
     79     registers. Also split the code (based on flag direction) to simplify
     80     pointer's updates
     81 
     82  Description:
     83 
     84 ------------------------------------------------------------------------------
     85  INPUT AND OUTPUT DEFINITIONS
     86 
     87  Inputs:
     88     spec  = spectral input to be shaped by the filter.
     89             Fixed point format
     90             Int32[]
     91             length = spec_length
     92 
     93     spec_length  = length of spec array.
     94             const Int
     95 
     96     direction = direction for application of tns filter.
     97                 +1  filters spectrum from low to high frequencies
     98                     (first input to filter is spec[0])
     99                 -1  filters spectrum from high to low frequencies
    100                     (first input to filter is spec[spec_length-1])
    101                 const Int
    102 
    103     lpc   = array of lpc coefficients, minus lpc[0] which is assumed to be "1"
    104             Fixed point format
    105             const Int[]
    106             length = TNS_MAX_ORDER
    107 
    108     Q_lpc = Q format for the lpc coeffcients (for max. precision, it assumes
    109             that all 16 bits are used)
    110             const Int
    111 
    112     order = order of the TNS filter (Range of 1 - TNS_MAX_ORDER)
    113             Int
    114 
    115  Local Stores/Buffers/Pointers Needed:
    116     None
    117 
    118  Global Stores/Buffers/Pointers Needed:
    119     None
    120 
    121  Outputs:
    122     None
    123 
    124  Pointers and Buffers Modified:
    125     spec = contains spectral data after application of TNS filter
    126            Int32 array
    127            length = spec_length
    128 
    129 
    130  Local Stores Modified:
    131 
    132  Global Stores Modified:
    133 
    134 
    135 ------------------------------------------------------------------------------
    136  FUNCTION DESCRIPTION
    137 
    138     A block of spectral data (Int32 spec[]) of length (const Int spec_length)
    139     is processed by a simple all-pole filter defined by
    140     LPC coefficients passed via (const Int lpc[])
    141 
    142     TNS filter equation
    143         y(n) =  x(n) - lpc(2)*y(n-1) - ... - lpc(order+1)*y(n-order)
    144 
    145     The filter calculation is performed in place, i.e. the output is passed
    146     back to the calling function via (Int32 spec[])
    147 
    148     The filter's order is defined by the variable (const Int order)
    149     The direction of the filter's application is defined by (const Int inc)
    150 
    151 ------------------------------------------------------------------------------
    152  REQUIREMENTS
    153 
    154     This function should match the functionality of the ISO code.
    155     The implementation does support filter orders bigger or equal to 1.
    156     The size of the spectral coeffcients has to be bigger or equal than 1.
    157 
    158 ------------------------------------------------------------------------------
    159  REFERENCES
    160 
    161  (1) ISO/IEC 14496-3:1999(E)
    162      Part 3
    163         Subpart 4.6.8 (Temporal Noise Shaping)
    164 
    165  (2) MPEG-2 NBC Audio Decoder
    166    "This software module was originally developed by AT&T, Dolby
    167    Laboratories, Fraunhofer Gesellschaft IIS in the course of development
    168    of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
    169    3. This software module is an implementation of a part of one or more
    170    MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
    171    Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
    172    standards free license to this software module or modifications thereof
    173    for use in hardware or software products claiming conformance to the
    174    MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
    175    module in hardware or software products are advised that this use may
    176    infringe existing patents. The original developer of this software
    177    module and his/her company, the subsequent editors and their companies,
    178    and ISO/IEC have no liability for use of this software module or
    179    modifications thereof in an implementation. Copyright is not released
    180    for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
    181    developer retains full right to use the code for his/her  own purpose,
    182    assign or donate the code to a third party and to inhibit third party
    183    from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
    184    This copyright notice must be included in all copies or derivative
    185    works."
    186    Copyright(c)1996.
    187 
    188 ------------------------------------------------------------------------------
    189  PSEUDO-CODE
    190 
    191 
    192     FOR (i=0; i<order; i++)
    193         state[i] = 0;
    194     ENDFOR
    195 
    196     IF (inc == -1)
    197     THEN
    198         spec = spec + spec_length - 1;
    199     ENDIF
    200 
    201     FOR (i=0; i<spec_length; i++)
    202 
    203         y = *spec;
    204 
    205         FOR (j=0; j<order; j++)
    206 
    207             y -= lpc[j] * state[j];
    208 
    209         ENDFOR
    210 
    211         FOR (j=order-1; j>0; j--)
    212 
    213             state[j] = state[j-1];
    214 
    215         ENDFOR
    216 
    217         state[0] = y;
    218 
    219         *spec = y;
    220 
    221         spec = spec + inc;
    222 
    223     ENDFOR
    224 
    225 
    226 ------------------------------------------------------------------------------
    227  RESOURCES USED
    228 
    229    When the code is written for a specific target processor
    230      the resources used should be documented below.
    231 
    232  STACK USAGE: [stack count for this module] + [variable to represent
    233           stack usage for each subroutine called]
    234 
    235      where: [stack usage variable] = stack usage for [subroutine
    236          name] (see [filename].ext)
    237 
    238  DATA MEMORY USED: x words
    239 
    240  PROGRAM MEMORY USED: x words
    241 
    242  CLOCK CYCLES: [cycle count equation for this module] + [variable
    243            used to represent cycle count for each subroutine
    244            called]
    245 
    246      where: [cycle count variable] = cycle count for [subroutine
    247         name] (see [filename].ext)
    248 
    249 ------------------------------------------------------------------------------
    250 */
    251 
    252 /*----------------------------------------------------------------------------
    253 ; INCLUDES
    254 ----------------------------------------------------------------------------*/
    255 #include "pv_audio_type_defs.h"
    256 #include "e_tns_const.h"
    257 #include "tns_ar_filter.h"
    258 #include "fxp_mul32.h"
    259 
    260 /*----------------------------------------------------------------------------
    261 ; MACROS
    262 ; Define module specific macros here
    263 ----------------------------------------------------------------------------*/
    264 
    265 /*----------------------------------------------------------------------------
    266 ; DEFINES
    267 ; Include all pre-processor statements here. Include conditional
    268 ; compile variables also.
    269 ----------------------------------------------------------------------------*/
    270 #define MASK_LOW16               0xFFFF
    271 #define UPPER16                      16
    272 
    273 /*----------------------------------------------------------------------------
    274 ; LOCAL FUNCTION DEFINITIONS
    275 ; Function Prototype declaration
    276 ----------------------------------------------------------------------------*/
    277 
    278 /*----------------------------------------------------------------------------
    279 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    280 ; Variable declaration - defined here and used outside this module
    281 ----------------------------------------------------------------------------*/
    282 
    283 /*----------------------------------------------------------------------------
    284 ; EXTERNAL FUNCTION REFERENCES
    285 ; Declare functions defined elsewhere and referenced in this module
    286 ----------------------------------------------------------------------------*/
    287 
    288 /*----------------------------------------------------------------------------
    289 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    290 ; Declare variables used in this module but defined elsewhere
    291 ----------------------------------------------------------------------------*/
    292 
    293 /*----------------------------------------------------------------------------
    294 ; FUNCTION CODE
    295 ----------------------------------------------------------------------------*/
    296 
    297 Int tns_ar_filter(
    298     Int32 spec[],
    299     const Int spec_length,
    300     const Int direction,
    301     const Int32 lpc[],
    302     const Int Q_lpc,
    303     const Int order)
    304 {
    305 
    306     Int i;
    307     Int j;
    308 
    309     /*
    310      * Multiplication related variables
    311      */
    312 
    313     Int32 temp;
    314 
    315     /*
    316      *  Filter related variables
    317      */
    318     Int32 y0;
    319 
    320     /*
    321      *  Circular buffer to hold the filter's state
    322      *  (y[n-1],y[n-2],y[n-3],etc.)
    323      *
    324      *  p_state and p_lpc should take advantage
    325      *  of any special circular buffer instructions
    326      *  if this code is hand-optimized in assembly.
    327      */
    328 
    329     Int32 *p_state = NULL;
    330 
    331     const Int32 *p_lpc;
    332 
    333 
    334     Int shift_up;
    335     Int shift_down_amount;
    336 
    337     /*
    338      *  Pointer to the I/O memory space
    339      */
    340     Int32 *p_spec = spec;
    341 
    342 
    343     i = 0;
    344     j = order;
    345 
    346     /*
    347      *  get the power of 2 that is bigger than the order
    348      *  i is the bit counter and j is modified until exceed
    349      *  the power of 2 corresponding to TNS_MAX_ORDER
    350      */
    351 
    352     while (j < 0x010)
    353     {
    354         j <<= 1;
    355         i++;
    356     }
    357 
    358     /*
    359      *  5 is the number of bits needed to represent 0x010
    360      *  TNS_MAX_ORDER = 20, power of 2 that include 20 is 5
    361      */
    362     shift_down_amount = 4 - i;
    363 
    364     shift_up = UPPER16 - Q_lpc;
    365 
    366     /*
    367      *  shift_down_amount == power of 2 that is bigger than the order - 1
    368      */
    369 
    370     shift_down_amount += shift_up;
    371 
    372     if (direction == -1)
    373     {
    374         p_spec += spec_length - 1;
    375 
    376         for (i = order; i != 0; i--)
    377         {
    378 
    379             y0 = *p_spec >> shift_down_amount;
    380 
    381             p_lpc = lpc;
    382 
    383             /* 32 by 32 bit multiplication */
    384             for (j = order; j > i; j--)
    385             {
    386                 temp = *p_state++;
    387                 y0 -= fxp_mul32_Q31(temp, *(p_lpc++)) << shift_up;
    388             }
    389 
    390             /*
    391             * Record the output in-place
    392             */
    393             p_state     = p_spec;
    394             *(p_spec--) = y0;
    395 
    396         }
    397 
    398         if (spec_length > order)
    399         {
    400             for (i = (spec_length - order); i != 0; i--)
    401             {
    402                 y0 = *p_spec >> shift_down_amount;
    403 
    404                 p_lpc = &(lpc[0]);
    405 
    406                 /* 32 by 32 bit multiplication */
    407                 for (j = order; j != 0; j--)
    408                 {
    409                     temp = *p_state++;
    410                     y0 -= fxp_mul32_Q31(temp, *(p_lpc++)) << shift_up;
    411                 }
    412 
    413                 /*
    414                  * Record the output in-place
    415                  */
    416                 p_state     = p_spec;
    417                 *(p_spec--) = y0;
    418 
    419             } /* END for (i = (spec_length - order); i>0; i--) */
    420         }
    421 
    422     }
    423     else
    424     {
    425         for (i = order; i != 0; i--)
    426         {
    427 
    428             p_lpc =  lpc;
    429 
    430             y0 = 0;
    431 
    432             /* 32 by 32 bit multiplication */
    433             for (j = order; j > i; j--)
    434             {
    435                 y0 -= fxp_mul32_Q31(*p_state--, *(p_lpc++));
    436             }
    437 
    438             p_state     = p_spec;
    439             /*
    440             * Record the output in-place
    441             */
    442             *(p_spec) = (*p_spec >> shift_down_amount) + (y0 << shift_up);
    443             p_spec++;
    444         }
    445 
    446         if (spec_length > order)
    447         {
    448             for (i = (spec_length - order); i != 0; i--)
    449             {
    450                 p_lpc =  lpc;
    451 
    452                 y0 = 0;
    453 
    454                 /* 32 by 32 bit multiplication */
    455                 for (j = order; j != 0; j--)
    456                 {
    457                     y0 -= fxp_mul32_Q31(*p_state--, *(p_lpc++));
    458                 }
    459 
    460                 p_state     = p_spec;
    461                 /*
    462                  * Record the output in-place
    463                  */
    464                 *(p_spec) = (*p_spec >> shift_down_amount) + (y0 << shift_up);
    465                 p_spec++;
    466 
    467             } /* END for (i = (spec_length - order); i>0; i--) */
    468         }
    469     }
    470 
    471     return(shift_down_amount);
    472 
    473 
    474 } /* tns_ar_filter */
    475