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: pns_intensity_right.c
     21 
     22 ------------------------------------------------------------------------------
     23  INPUT AND OUTPUT DEFINITIONS
     24 
     25  Inputs:
     26 
     27     hasmask    = mask status for the frame. Enumerated.
     28 
     29     pFrameInfo = Pointer to structure that holds information about each group.
     30                  (long block flag, number of windows, scalefactor bands
     31                   per group, etc.)
     32                  [const pFrameInfo * const]
     33 
     34     group      = Array that contains indexes of the
     35                  first window in the next group.
     36                  [const Int *, length num_win]
     37 
     38     mask_map   = Array that denotes whether M/S stereo is turned on for
     39                  each grouped scalefactor band.
     40                  [const Int *, length MAX_SFB]
     41 
     42     codebook_map = Array that denotes which Huffman codebook was used for
     43                    the encoding of each grouped scalefactor band.
     44                    [const Int *, length MAX_SFB]
     45 
     46     factorsL     =  Array of grouped scalefactors for left chan.
     47                     [const Int *, length MAX_SFB]
     48 
     49     factorsR     =  Array of scalefactors for right chan.
     50                     [const Int *, length MAX_SFB]
     51 
     52     sfb_prediction_used =  Flag that denotes the activation of long term prediction
     53                            on a per-scalefactor band, non-grouped basis.
     54                            [const Int *, length MAX_SFB]
     55 
     56     ltp_data_present = Flag that indicates whether LTP is enbaled for this frame.
     57                        [const Bool]
     58 
     59     coefLeft = Array containing the fixed-point spectral coefficients
     60                        for the left channel.
     61                        [Int32 *, length 1024]
     62 
     63     coefRight = Array containing the fixed-point spectral coefficients
     64                         for the right channel.
     65                         [Int32 *, length 1024]
     66 
     67     q_formatLeft = The Q-format for the left channel's fixed-point spectral
     68                    coefficients, on a per-scalefactor band, non-grouped basis.
     69                    [Int *, length MAX_SFB]
     70 
     71     q_formatRight = The Q-format for the right channel's fixed-point spectral
     72                     coefficients, on a per-scalefactor band, non-grouped basis.
     73                     [Int *, length MAX_SFB]
     74 
     75     pCurrentSeed  = Pointer to the current seed for the random number
     76                     generator in the function gen_rand_vector().
     77                     [Int32 * const]
     78 
     79  Local Stores/Buffers/Pointers Needed:
     80     None
     81 
     82  Global Stores/Buffers/Pointers Needed:
     83     None
     84 
     85  Outputs:
     86     None
     87 
     88  Pointers and Buffers Modified:
     89     coefLeft  = Contains the new spectral information.
     90 
     91     coefRight = Contains the new spectral information.
     92 
     93     q_formatLeft      = Q-format may be updated with changed to fixed-point
     94                         data in coefLeft.
     95 
     96     q_formatRight     = Q-format may be updated with changed to fixed-point
     97                         data in coefRight.
     98 
     99     pCurrentSeed      = Value pointed to by pCurrentSeed updated by calls
    100                         to gen_rand_vector().
    101 
    102  Local Stores Modified:
    103     None
    104 
    105  Global Stores Modified:
    106     None
    107 
    108 ------------------------------------------------------------------------------
    109  FUNCTION DESCRIPTION
    110 
    111  This function steps through all of the scalefactor bands, looking for
    112  either PNS or IS to be enabled on the right channel.
    113 
    114  If the codebook used is >= NOISE_HCB, the code then checks for the use
    115  of Huffman codebooks NOISE_HCB, INTENSITY_HCB, or INTENSITY_HCB2.
    116 
    117  When a SFB utilizing the codebook NOISE_HCB is detected, a check is made to
    118  see if M/S has also been enabled for that SFB.
    119 
    120  If M/S is not enabled, the band's spectral information is filled with
    121  scaled random data.   The scaled random data is generated by the function
    122  gen_rand_vector.  This is done across all windows in the group.
    123 
    124  If M/S is enabled, the band's spectral information is derived from the data
    125  residing in the same band on the left channel.  The information on the right
    126  channel has independent scaling, so this is a bit more involved than a
    127  direct copy of the information on the left channel.  This is done by calling
    128  the inline function pns_corr().
    129 
    130  When a SFB utilizing an intensity codebook is detected, the band's spectral
    131  information is generated from the information on the left channel.
    132  This is done across all windows in the group.  M/S being enabled has the
    133  effect of reversing the sign of the data on the right channel.  This code
    134  resides in the inline function intensity_right().
    135 
    136 ------------------------------------------------------------------------------
    137  REQUIREMENTS
    138 
    139 
    140 ------------------------------------------------------------------------------
    141  REFERENCES
    142 
    143  (1) ISO/IEC 14496-3:1999(E)
    144      Part 3
    145         Subpart 4.6.7.1   M/S stereo
    146         Subpart 4.6.7.2.3 Decoding Process (Intensity Stereo)
    147         Subpart 4.6.12.3  Decoding Process (PNS)
    148         Subpart 4.6.2     ScaleFactors
    149 
    150  (2) MPEG-2 NBC Audio Decoder
    151    "This software module was originally developed by AT&T, Dolby
    152    Laboratories, Fraunhofer Gesellschaft IIS in the course of development
    153    of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
    154    3. This software module is an implementation of a part of one or more
    155    MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
    156    Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
    157    standards free license to this software module or modifications thereof
    158    for use in hardware or software products claiming conformance to the
    159    MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
    160    module in hardware or software products are advised that this use may
    161    infringe existing patents. The original developer of this software
    162    module and his/her company, the subsequent editors and their companies,
    163    and ISO/IEC have no liability for use of this software module or
    164    modifications thereof in an implementation. Copyright is not released
    165    for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
    166    developer retains full right to use the code for his/her own purpose,
    167    assign or donate the code to a third party and to inhibit third party
    168    from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
    169    This copyright notice must be included in all copies or derivative
    170    works."
    171    Copyright(c)1996.
    172 
    173 ------------------------------------------------------------------------------
    174  PSEUDO-CODE
    175     pCoefRight = coefRight;
    176     pCoefLeft = coefLeft;
    177 
    178     window_start = 0;
    179     tot_sfb = 0;
    180     start_indx = 0;
    181 
    182     coef_per_win = pFrameInfo->coef_per_win[0];
    183 
    184     sfb_per_win = pFrameInfo->sfb_per_win[0];
    185 
    186     DO
    187         pBand     = pFrameInfo->win_sfb_top[window_start];
    188 
    189         partition = *pGroup;
    190         pGroup = pGroup + 1;
    191 
    192         band_start = 0;
    193 
    194         wins_in_group = (partition - window_start);
    195 
    196         FOR (sfb = sfb_per_win; sfb > 0; sfb--)
    197 
    198             band_stop = *(pBand);
    199             pBand = pBand + 1;
    200 
    201             codebook = *(pCodebookMap);
    202             pCodebookMap = pCodebookMap + 1;
    203 
    204             mask_enabled = *(pMaskMap);
    205             pMaskMap = pMaskMap + 1;
    206 
    207             band_length = band_stop - band_start;
    208 
    209             IF (codebook == NOISE_HCB)
    210 
    211                 sfb_prediction_used[tot_sfb] &= ltp_data_present;
    212 
    213                 IF (sfb_prediction_used[tot_sfb] == FALSE)
    214 
    215                     mask_enabled = mask_enabled AND hasmask;
    216 
    217                     IF (mask_enabled == FALSE)
    218 
    219                         pWindow_CoefR = &(pCoefRight[band_start]);
    220 
    221                         start_indx = tot_sfb;
    222 
    223                         FOR (win_indx = wins_in_group;
    224                              win_indx > 0;
    225                              win_indx--)
    226 
    227                             CALL
    228                             q_formatRight[start_indx] =
    229                                  gen_rand_vector(
    230                                      pWindow_CoefR,
    231                                      band_length,
    232                                      pCurrentSeed,
    233                                      *(pFactorsRight));
    234                             MODIFYING
    235                                 pCoefRight[band_start]
    236                             RETURNING
    237                                 q_formatRight[start_indx]
    238 
    239                             pWindow_CoefR += coef_per_win;
    240 
    241                             start_indx = start_indx + sfb_per_win;
    242 
    243                         ENDFOR
    244 
    245                     ELSE
    246                         CALL
    247                         pns_corr(
    248                              (*(pFactorsRight) -
    249                               *(pFactorsLeft) ),
    250                              coef_per_win,
    251                              sfb_per_win,
    252                              wins_in_group,
    253                              band_length,
    254                              q_formatLeft[tot_sfb],
    255                             &(q_formatRight[tot_sfb]),
    256                             &(pCoefLeft[band_start]),
    257                             &(pCoefRight[band_start]));
    258 
    259                         MODIFYING
    260                             pCoefRightt[band_start]
    261                             q_formatRight[tot_sfb]
    262                         RETURNING
    263                 NONE
    264                     ENDIF
    265 
    266                 ENDIF
    267 
    268             ELSE IF (codebook >= INTENSITY_HCB2)
    269 
    270                 mask_enabled = mask_enabled AND hasmask;
    271 
    272                 CALL
    273                     intensity_right(
    274                         *(pFactorsRight),
    275                         coef_per_win,
    276                         sfb_per_win,
    277                         wins_in_group,
    278                         band_length,
    279                         codebook,
    280                         mask_enabled,
    281                        &(q_formatLeft[tot_sfb]),
    282                        &(q_formatRight[tot_sfb]),
    283                        &(pCoefLeft[band_start]),
    284                        &(pCoefRight[band_start]));
    285 
    286                 MODIFYING
    287                     pCoefRightt[band_start]
    288                     q_formatRight[tot_sfb]
    289                 RETURNING
    290                     NONE
    291 
    292             ENDIF
    293 
    294             band_start = band_stop;
    295 
    296             tot_sfb = tot_sfb + 1;
    297 
    298         ENDFOR
    299 
    300         coef_per_win = coef_per_win * (wins_in_group);
    301 
    302         wins_in_group = wins_in_group - 1;
    303 
    304         tot_sfb = tot_sfb + sfb_per_win * wins_in_group;
    305         pFactorsRight = pFactorsRight + sfb_per_win * wins_in_group;
    306         pFactorsLeft  = pFactorsLeft + sfb_per_win * wins_in_group;
    307 
    308         pCoefRight = pCoefRight + coef_per_win;
    309         pCoefLeft  = pCoefLeft + coef_per_win;
    310 
    311         window_start = partition;
    312 
    313     WHILE (partition < pFrameInfo->num_win);
    314 
    315     return;
    316 
    317 ------------------------------------------------------------------------------
    318  RESOURCES USED
    319    When the code is written for a specific target processor the
    320      resources used should be documented below.
    321 
    322  STACK USAGE: [stack count for this module] + [variable to represent
    323           stack usage for each subroutine called]
    324 
    325      where: [stack usage variable] = stack usage for [subroutine
    326          name] (see [filename].ext)
    327 
    328  DATA MEMORY USED: x words
    329 
    330  PROGRAM MEMORY USED: x words
    331 
    332  CLOCK CYCLES: [cycle count equation for this module] + [variable
    333            used to represent cycle count for each subroutine
    334            called]
    335 
    336      where: [cycle count variable] = cycle count for [subroutine
    337         name] (see [filename].ext)
    338 
    339 ------------------------------------------------------------------------------
    340 */
    341 
    342 
    343 /*----------------------------------------------------------------------------
    344 ; INCLUDES
    345 ----------------------------------------------------------------------------*/
    346 #include "pv_audio_type_defs.h"
    347 #include "pns_intensity_right.h"
    348 #include "e_huffmanconst.h"
    349 #include "gen_rand_vector.h"
    350 #include "intensity_right.h"
    351 #include "pns_corr.h"
    352 
    353 /*----------------------------------------------------------------------------
    354 ; MACROS
    355 ; Define module specific macros here
    356 ----------------------------------------------------------------------------*/
    357 
    358 /*----------------------------------------------------------------------------
    359 ; DEFINES
    360 ; Include all pre-processor statements here. Include conditional
    361 ; compile variables also.
    362 ----------------------------------------------------------------------------*/
    363 
    364 /*----------------------------------------------------------------------------
    365 ; LOCAL FUNCTION DEFINITIONS
    366 ; Function Prototype declaration
    367 ----------------------------------------------------------------------------*/
    368 
    369 /*----------------------------------------------------------------------------
    370 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    371 ; Variable declaration - defined here and used outside this module
    372 ----------------------------------------------------------------------------*/
    373 
    374 /*----------------------------------------------------------------------------
    375 ; EXTERNAL FUNCTION REFERENCES
    376 ; Declare functions defined elsewhere and referenced in this module
    377 ----------------------------------------------------------------------------*/
    378 
    379 
    380 /*----------------------------------------------------------------------------
    381 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    382 ; Declare variables used in this module but defined elsewhere
    383 ----------------------------------------------------------------------------*/
    384 
    385 /*----------------------------------------------------------------------------
    386 ; FUNCTION CODE
    387 ----------------------------------------------------------------------------*/
    388 
    389 void pns_intensity_right(
    390     const Int        hasmask,
    391     const FrameInfo * const pFrameInfo,
    392     const Int        group[],
    393     const Bool       mask_map[],
    394     const Int        codebook_map[],
    395     const Int        factorsL[],
    396     const Int        factorsR[],
    397     Int        sfb_prediction_used[],
    398     const Bool       ltp_data_present,
    399     Int32      coefLeft[],
    400     Int32      coefRight[],
    401     Int        q_formatLeft[MAXBANDS],
    402     Int        q_formatRight[MAXBANDS],
    403     Int32 * const pCurrentSeed)
    404 {
    405 
    406     Int32   *pCoefRight;
    407     Int32   *pWindow_CoefR;
    408 
    409     Int32   *pCoefLeft;
    410 
    411     Int     tot_sfb;
    412     Int     start_indx;
    413     Int     sfb;
    414 
    415     Int     band_length;
    416     Int     band_start;
    417     Int     band_stop;
    418     Int     coef_per_win;
    419 
    420     Int     codebook;
    421     Int     partition;
    422     Int     window_start;
    423 
    424     Int     sfb_per_win;
    425     Int     wins_in_group;
    426     Int     win_indx;
    427 
    428     const Int16 *pBand;
    429     const Int   *pFactorsLeft  = factorsL;
    430     const Int   *pFactorsRight = factorsR;
    431     const Int   *pCodebookMap  = codebook_map;
    432     const Int   *pGroup        = group;
    433     const Bool  *pMaskMap      = mask_map;
    434 
    435     Bool mask_enabled;
    436 
    437     pCoefRight = coefRight;
    438     pCoefLeft = coefLeft;
    439 
    440     window_start = 0;
    441     tot_sfb = 0;
    442     start_indx = 0;
    443 
    444     /*
    445      * Each window in the frame should have the same number of coef's,
    446      * so coef_per_win is constant in all the loops
    447      */
    448     coef_per_win = pFrameInfo->coef_per_win[0];
    449 
    450     /*
    451      * Because the number of scalefactor bands per window should be
    452      * constant for each frame, sfb_per_win can be determined outside
    453      * of the loop.
    454      *
    455      * For 44.1 kHz sampling rate   sfb_per_win = 14 for short windows
    456      *                              sfb_per_win = 49 for long  windows
    457      */
    458 
    459     sfb_per_win = pFrameInfo->sfb_per_win[0];
    460 
    461     do
    462     {
    463         pBand     = pFrameInfo->win_sfb_top[window_start];
    464 
    465         /*----------------------------------------------------------
    466         Partition is equal to the first window in the next group
    467 
    468         { Group 0    }{      Group 1      }{    Group 2 }{Group 3}
    469         [win 0][win 1][win 2][win 3][win 4][win 5][win 6][win 7]
    470 
    471         pGroup[0] = 2
    472         pGroup[1] = 5
    473         pGroup[2] = 7
    474         pGroup[3] = 8
    475         -----------------------------------------------------------*/
    476         partition = *(pGroup++);
    477 
    478         band_start = 0;
    479 
    480         wins_in_group = (partition - window_start);
    481 
    482         for (sfb = sfb_per_win; sfb > 0; sfb--)
    483         {
    484             /* band is offset table, band_stop is last coef in band */
    485             band_stop = *(pBand++);
    486 
    487             codebook = *(pCodebookMap++);
    488 
    489             mask_enabled = *(pMaskMap++);
    490 
    491             /*
    492              * When a tool utilizing sfb is found, apply the correct tool
    493              * to that sfb in each window in the group
    494              *
    495              * Example...  sfb[3] == NOISE_HCB
    496              *
    497              * [ Group 1                                      ]
    498              * [win 0                 ][win 1                 ]
    499              * [0][1][2][X][4][5][6][7][0][1][2][X][4][5][6][7]
    500              *
    501              * The for(sfb) steps through the sfb's 0-7 in win 0.
    502              *
    503              * Finding sfb[3]'s codebook == NOISE_HCB, the code
    504              * steps through all the windows in the group (they share
    505              * the same scalefactors) and replaces that sfb with noise.
    506              */
    507 
    508             /*
    509              * Experimental results suggest that ms_synt is the most
    510              * commonly used tool, so check for it first.
    511              *
    512              */
    513 
    514             band_length = band_stop - band_start;
    515 
    516             if (codebook == NOISE_HCB)
    517             {
    518                 sfb_prediction_used[tot_sfb] &= ltp_data_present;
    519 
    520                 if (sfb_prediction_used[tot_sfb] == FALSE)
    521                 {
    522                     /*
    523                      * The branch and the logical AND interact in the
    524                      * following manner...
    525                      *
    526                      * mask_enabled == 0 hasmask == X -- gen_rand_vector
    527                      * mask_enabled == 1 hasmask == 1 -- pns_corr
    528                      * mask_enabled == 0 hasmask == 1 -- gen_rand_vector
    529                      * mask_enabled == 1 hasmask == 2 -- gen_rand_vector
    530                      * mask_enabled == 0 hasmask == 2 -- gen_rand_vector
    531                      */
    532 
    533                     mask_enabled &= hasmask;
    534 
    535                     if (mask_enabled == FALSE)
    536                     {
    537                         pWindow_CoefR = &(pCoefRight[band_start]);
    538 
    539                         /*
    540                          * Step through all the windows in this group,
    541                          * replacing this band in each window's
    542                          * spectrum with random noise
    543                          */
    544                         start_indx = tot_sfb;
    545 
    546                         for (win_indx = wins_in_group;
    547                                 win_indx > 0;
    548                                 win_indx--)
    549                         {
    550 
    551                             /* generate random noise */
    552                             q_formatRight[start_indx] =
    553                                 gen_rand_vector(
    554                                     pWindow_CoefR,
    555                                     band_length,
    556                                     pCurrentSeed,
    557                                     *(pFactorsRight));
    558 
    559                             pWindow_CoefR += coef_per_win;
    560 
    561                             start_indx += sfb_per_win;
    562                         }
    563 
    564                     }
    565                     else
    566                     {
    567                         pns_corr(
    568                             (*(pFactorsRight) -
    569                              *(pFactorsLeft)),
    570                             coef_per_win,
    571                             sfb_per_win,
    572                             wins_in_group,
    573                             band_length,
    574                             q_formatLeft[tot_sfb],
    575                             &(q_formatRight[tot_sfb]),
    576                             &(pCoefLeft[band_start]),
    577                             &(pCoefRight[band_start]));
    578 
    579                     } /* if (mask_map == FALSE) */
    580 
    581                 } /* if (sfb_prediction_used[tot_sfb] == FALSE) */
    582 
    583             } /* if (codebook == 0) */
    584             else if (codebook >= INTENSITY_HCB2)
    585             {
    586                 /*
    587                  * The logical AND flags the inversion of intensity
    588                  * in the following manner.
    589                  *
    590                  * mask_enabled == X hasmask == 0 -- DO NOT INVERT
    591                  * mask_enabled == 0 hasmask == X -- DO NOT INVERT
    592                  * mask_enabled == 1 hasmask == 1 -- DO     INVERT
    593                  * mask_enabled == 0 hasmask == 1 -- DO NOT INVERT
    594                  * mask_enabled == 1 hasmask == 2 -- DO NOT INVERT
    595                  * mask_enabled == 0 hasmask == 2 -- DO NOT INVERT
    596                  */
    597 
    598                 mask_enabled &= hasmask;
    599 
    600                 intensity_right(
    601                     *(pFactorsRight),
    602                     coef_per_win,
    603                     sfb_per_win,
    604                     wins_in_group,
    605                     band_length,
    606                     codebook,
    607                     mask_enabled,
    608                     &(q_formatLeft[tot_sfb]),
    609                     &(q_formatRight[tot_sfb]),
    610                     &(pCoefLeft[band_start]),
    611                     &(pCoefRight[band_start]));
    612 
    613             } /* END else codebook must be INTENSITY_HCB or ... */
    614 
    615             band_start = band_stop;
    616 
    617             tot_sfb++;
    618 
    619             pFactorsLeft++;
    620             pFactorsRight++;
    621 
    622         } /* for (sfb) */
    623 
    624         /*
    625          * Increment pCoefRight and pCoefLeft by
    626          * coef_per_win * the number of windows
    627          */
    628 
    629         pCoefRight += coef_per_win * wins_in_group;
    630         pCoefLeft  += coef_per_win * wins_in_group--;
    631 
    632         /*
    633          * Increase tot_sfb by sfb_per_win times the number of windows minus 1.
    634          * The minus 1 comes from the fact that tot_sfb is already pointing
    635          * to the first sfb in the 2nd window of the group.
    636          */
    637         tot_sfb += sfb_per_win * wins_in_group;
    638 
    639         pFactorsRight += sfb_per_win * wins_in_group;
    640         pFactorsLeft  += sfb_per_win * wins_in_group;
    641 
    642         window_start = partition;
    643 
    644     }
    645     while (partition < pFrameInfo->num_win);
    646 
    647     /* pFrameInfo->num_win = 1 for long windows, 8 for short_windows */
    648 
    649     return;
    650 
    651 } /* pns_intensity_right() */
    652 
    653 
    654