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: apply_tns.c
     21 
     22 ------------------------------------------------------------------------------
     23  INPUT AND OUTPUT DEFINITIONS
     24 
     25  Inputs:
     26     coef =       Array of input coefficients.
     27                  [Int32 *, length 1024]
     28 
     29     q_format   = Array of q-formats, one per scalefactor band, for the
     30                  entire frame.  In the case of tns_inv_filter, only the
     31                  first element is used, since the input to tns_inv_filter
     32                  is all of the same q-format.
     33                  [Int * const, length MAX_SFB]
     34 
     35     pFrameInfo = Pointer to structure that holds information about each group.
     36                  (long block flag, number of windows, scalefactor bands
     37                   per group, etc.)
     38                  [const FrameInfo * const]
     39 
     40     pTNS_frame_info = pointer to structure containing the details on each
     41                       TNS filter (order, filter coefficients,
     42                       coefficient res., etc.)
     43                       [TNS_frame_info * const]
     44 
     45     inverse_flag   = TRUE  if inverse filter is to be applied.
     46                      FALSE if forward filter is to be applied.
     47                      [Bool]
     48 
     49     scratch_Int_buffer = Pointer to scratch memory to store the
     50                            filter's state memory.  Used by both
     51                            tns_inv_filter.
     52                            [Int *, length TNS_MAX_ORDER]
     53 
     54  Local Stores/Buffers/Pointers Needed:
     55     None
     56 
     57  Global Stores/Buffers/Pointers Needed:
     58     None
     59 
     60  Outputs:
     61     None
     62 
     63  Pointers and Buffers Modified:
     64     coef[]   = TNS altered data.
     65     q_format = q-formats in TNS scalefactor bands may be modified.
     66 
     67  Local Stores Modified:
     68     None
     69 
     70  Global Stores Modified:
     71     None
     72 
     73 ------------------------------------------------------------------------------
     74  FUNCTION DESCRIPTION
     75 
     76     This function applies either the TNS forward or TNS inverse filter, based
     77     on inverse_flag being FALSE or TRUE, respectively.
     78 
     79     For the TNS forward filter, the data fed into tns_ar_filter is normalized
     80     all to the same q-format.
     81 
     82 ------------------------------------------------------------------------------
     83  REQUIREMENTS
     84 
     85     The input, coef, should use all 32-bits, else the scaling by tns_ar_filter
     86     may eliminate the data.
     87 
     88 ------------------------------------------------------------------------------
     89  REFERENCES
     90 
     91  (1) ISO/IEC 14496-3:1999(E)
     92      Part 3
     93         Subpart 4.6.8 (Temporal Noise Shaping)
     94 
     95 ------------------------------------------------------------------------------
     96  PSEUDO-CODE
     97 
     98     NO PSEUDO-CODE
     99 
    100 ------------------------------------------------------------------------------
    101  RESOURCES USED
    102    When the code is written for a specific target processor
    103      the resources used should be documented below.
    104 
    105  STACK USAGE: [stack count for this module] + [variable to represent
    106           stack usage for each subroutine called]
    107 
    108      where: [stack usage variable] = stack usage for [subroutine
    109          name] (see [filename].ext)
    110 
    111  DATA MEMORY USED: x words
    112 
    113  PROGRAM MEMORY USED: x words
    114 
    115  CLOCK CYCLES: [cycle count equation for this module] + [variable
    116            used to represent cycle count for each subroutine
    117            called]
    118 
    119      where: [cycle count variable] = cycle count for [subroutine
    120         name] (see [filename].ext)
    121 
    122 ------------------------------------------------------------------------------
    123 */
    124 
    125 /*----------------------------------------------------------------------------
    126 ; INCLUDES
    127 ----------------------------------------------------------------------------*/
    128 #include "pv_audio_type_defs.h"
    129 #include "s_tns_frame_info.h"
    130 #include "s_tnsfilt.h"
    131 #include "s_frameinfo.h"
    132 #include "tns_inv_filter.h"
    133 #include "tns_ar_filter.h"
    134 #include "apply_tns.h"
    135 
    136 /*----------------------------------------------------------------------------
    137 ; MACROS
    138 ; Define module specific macros here
    139 ----------------------------------------------------------------------------*/
    140 
    141 /*----------------------------------------------------------------------------
    142 ; DEFINES
    143 ; Include all pre-processor statements here. Include conditional
    144 ; compile variables also.
    145 ----------------------------------------------------------------------------*/
    146 
    147 /*----------------------------------------------------------------------------
    148 ; LOCAL FUNCTION DEFINITIONS
    149 ; Function Prototype declaration
    150 ----------------------------------------------------------------------------*/
    151 
    152 /*----------------------------------------------------------------------------
    153 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    154 ; Variable declaration - defined here and used outside this module
    155 ----------------------------------------------------------------------------*/
    156 
    157 /*----------------------------------------------------------------------------
    158 ; EXTERNAL FUNCTION REFERENCES
    159 ; Declare functions defined elsewhere and referenced in this module
    160 ----------------------------------------------------------------------------*/
    161 
    162 /*----------------------------------------------------------------------------
    163 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    164 ; Declare variables used in this module but defined elsewhere
    165 ----------------------------------------------------------------------------*/
    166 
    167 /*----------------------------------------------------------------------------
    168 ; FUNCTION CODE
    169 ----------------------------------------------------------------------------*/
    170 
    171 void apply_tns(
    172     Int32                  coef[],
    173     Int                    q_format[],
    174     const FrameInfo      * const pFrameInfo,
    175     TNS_frame_info * const pTNS_frame_info,
    176     const Bool                   inverse_flag,
    177     Int32                  scratch_Int_buffer[])
    178 {
    179     Int num_tns_bands;
    180     Int num_TNS_coef;
    181 
    182     Int f;
    183 
    184     Int tempInt;
    185     Int tempInt2;
    186 
    187     Int sfb_per_win;
    188     Int sfbWidth;
    189 
    190     Int coef_per_win;
    191     Int min_q;
    192     Int win;
    193 
    194     Int32 *pCoef = coef;
    195     Int32 *pTempCoef;
    196 
    197     Int   *pStartQformat = q_format;
    198 
    199     Int   *pQformat;
    200     Int32 *pLpcCoef;
    201 
    202     Int sfb_offset;
    203 
    204     const Int16 *pWinSfbTop;
    205 
    206     TNSfilt *pFilt;
    207 
    208     coef_per_win = pFrameInfo->coef_per_win[0];
    209     sfb_per_win  = pFrameInfo->sfb_per_win[0];
    210 
    211     win = 0;
    212 
    213     pLpcCoef = pTNS_frame_info->lpc_coef;
    214 
    215     pFilt = pTNS_frame_info->filt;
    216 
    217     do
    218     {
    219         for (f = pTNS_frame_info->n_filt[win]; f > 0; f--)
    220         {
    221             /* Skip to the next filter if the order is 0 */
    222             tempInt = pFilt->order;
    223 
    224             if (tempInt > 0)
    225             {
    226                 /*
    227                  * Do not call tns_ar_filter or tns_inv_filter
    228                  * if the difference
    229                  * between start_coef and stop_stop is <= 0.
    230                  *
    231                  */
    232                 num_TNS_coef = (pFilt->stop_coef - pFilt->start_coef);
    233 
    234                 if (num_TNS_coef > 0)
    235                 {
    236                     if (inverse_flag != FALSE)
    237                     {
    238                         tns_inv_filter(
    239                             &(pCoef[pFilt->start_coef]),
    240                             num_TNS_coef,
    241                             pFilt->direction,
    242                             pLpcCoef,
    243                             pFilt->q_lpc,
    244                             pFilt->order,
    245                             scratch_Int_buffer);
    246                     }
    247                     else
    248                     {
    249                         num_tns_bands = (pFilt->stop_band - pFilt->start_band);
    250 
    251                         /*
    252                          * pQformat is initialized only once.
    253                          *
    254                          * Here is how TNS is applied on scalefactor bands
    255                          *
    256                          * [0][1][2][3][4][5][6][7][8]
    257                          *  |                        \
    258                          * start_band               stop_band
    259                          *
    260                          * In this example, TNS would be applied to 8
    261                          * scalefactor bands, 0-7.
    262                          *
    263                          * pQformat is initially set to &(pStartQformat[8])
    264                          *
    265                          * 1st LOOP
    266                          *      Entry: pQformat = &(pStartQformat[8])
    267                          *
    268                          *      pQformat is pre-decremented 8 times in the
    269                          *      search for min_q
    270                          *
    271                          *      Exit:  pQformat = &(pStartQformat[0])
    272                          *
    273                          * 2nd LOOP
    274                          *      Entry: pQformat = &(pStartQformat[0])
    275                          *
    276                          *      pQformat is post-incremented 8 times in the
    277                          *      normalization of the data loop.
    278                          *
    279                          *      Exit:  pQformat = &(pStartQformat[8]
    280                          *
    281                          *
    282                          * shift_amt = tns_ar_filter(...)
    283                          *
    284                          * 3rd LOOP
    285                          *      Entry: pQformat = &(pStartQformat[8])
    286                          *
    287                          *      pQformat is pre-decremented 8 times in the
    288                          *      adjustment of the q-format to min_q - shift_amt
    289                          *
    290                          *      Exit:  pQformat = &(pStartQformat[0])
    291                          *
    292                          */
    293 
    294                         pQformat =
    295                             &(pStartQformat[pFilt->stop_band]);
    296 
    297                         /*
    298                          * Scan the array of q-formats and find the minimum over
    299                          * the range where the filter is to be applied.
    300                          *
    301                          * At the end of this scan,
    302                          * pQformat = &(q-format[pFilt->start_band]);
    303                          *
    304                          */
    305 
    306                         min_q = INT16_MAX;
    307 
    308                         for (tempInt = num_tns_bands; tempInt > 0; tempInt--)
    309                         {
    310                             tempInt2 = *(--pQformat);
    311 
    312                             if (tempInt2 < min_q)
    313                             {
    314                                 min_q = tempInt2;
    315                             }
    316                         } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/
    317 
    318                         /*
    319                          * Set up the pointers so we can index into coef[]
    320                          * on a scalefactor band basis.
    321                          */
    322                         tempInt = pFilt->start_band;
    323 
    324                         tempInt--;
    325 
    326                         /* Initialize sfb_offset and pWinSfbTop */
    327                         if (tempInt >= 0)
    328                         {
    329                             pWinSfbTop =
    330                                 &(pFrameInfo->win_sfb_top[win][tempInt]);
    331 
    332                             sfb_offset = *(pWinSfbTop++);
    333                         }
    334                         else
    335                         {
    336                             pWinSfbTop = pFrameInfo->win_sfb_top[win];
    337                             sfb_offset = 0;
    338                         }
    339 
    340                         pTempCoef = pCoef + pFilt->start_coef;
    341 
    342                         /* Scale the data in the TNS bands to min_q q-format */
    343                         for (tempInt = num_tns_bands; tempInt > 0; tempInt--)
    344                         {
    345                             sfbWidth  = *(pWinSfbTop++) - sfb_offset;
    346 
    347                             sfb_offset += sfbWidth;
    348 
    349                             tempInt2 = *(pQformat++) - min_q;
    350 
    351                             /*
    352                              * This should zero out the data in one scalefactor
    353                              * band if it is so much less than the neighboring
    354                              * scalefactor bands.
    355                              *
    356                              * The only way this "should" happen is if one
    357                              * scalefactor band contains zero data.
    358                              *
    359                              * Zero data can be of any q-format, but we always
    360                              * set it very high to avoid the zero-data band being
    361                              * picked as the one to normalize to in the scan for
    362                              * min_q.
    363                              *
    364                              */
    365                             if (tempInt2 > 31)
    366                             {
    367                                 tempInt2 = 31;
    368                             }
    369 
    370                             for (sfbWidth >>= 2; sfbWidth > 0; sfbWidth--)
    371                             {
    372                                 *(pTempCoef++) >>= tempInt2;
    373                                 *(pTempCoef++) >>= tempInt2;
    374                                 *(pTempCoef++) >>= tempInt2;
    375                                 *(pTempCoef++) >>= tempInt2;
    376                             }
    377 
    378                         } /* for(tempInt = num_bands; tempInt > 0; tempInt--)*/
    379 
    380                         tempInt2 =
    381                             tns_ar_filter(
    382                                 &(pCoef[pFilt->start_coef]),
    383                                 num_TNS_coef,
    384                                 pFilt->direction,
    385                                 pLpcCoef,
    386                                 pFilt->q_lpc,
    387                                 pFilt->order);
    388 
    389                         /*
    390                          * Update the q-format for all the scalefactor bands
    391                          * taking into account the adjustment caused by
    392                          * tns_ar_filter
    393                          */
    394 
    395                         min_q -= tempInt2;
    396 
    397                         for (tempInt = num_tns_bands; tempInt > 0; tempInt--)
    398                         {
    399                             *(--pQformat) = min_q;
    400                         }
    401 
    402                     } /* if (inverse_flag != FALSE) */
    403 
    404                 } /* if (num_TNS_coef > 0) */
    405 
    406                 pLpcCoef += pFilt->order;
    407 
    408             } /* if (tempInt > 0) */
    409 
    410             pFilt++;
    411 
    412         } /* for (f = pTNSinfo->n_filt; f > 0; f--) */
    413 
    414         pCoef += coef_per_win;
    415         pStartQformat += sfb_per_win;
    416 
    417         win++;
    418 
    419     }
    420     while (win < pFrameInfo->num_win);
    421 
    422     return;
    423 
    424 } /* apply_tns() */
    425