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: intensity_right.c
     21 
     22 ------------------------------------------------------------------------------
     23  REVISION HISTORY
     24 
     25  Description: Modified per review comments.
     26 
     27  Description: Noticed that the code could be more efficient by
     28  using some other method for storing the sign.  The code was changed to
     29  use a signed Int to store the table, and an adjustment of the q-format to
     30  reflect the difference between the data being shifted by 16 and the table
     31  being stored in q-15 format.
     32 
     33  Description: Updated pseudocode
     34 
     35  Description: When the multiplication of two 16-bits variables is stored in
     36               an 32-bits variable, the result should be typecasted explicitly
     37               to Int32 before it is stored.
     38               *(pCoefRight++) = (Int32) tempInt2 * multiplier;
     39 
     40  Description:
     41 ------------------------------------------------------------------------------
     42  INPUT AND OUTPUT DEFINITIONS
     43 
     44  Inputs:
     45 
     46     scalefactor  =  Multiplier used to scale the data extracted from the left
     47                     channel for use on the right.
     48                     [const Int]
     49 
     50     coef_per_win =  Number of coefficients per window.
     51                     (128 for short, 1024 for long)
     52                     [const Int]
     53 
     54     sfb_per_win  =  Number of scalefactor bands per window.  This should be
     55                     a number divisible by four.
     56                     [const Int]
     57 
     58     wins_in_group = The number of windows in the group being decoded.
     59                     This number falls within the range 1-8.
     60                     [const Int]
     61 
     62     band_length  =  The length of the scalefactor band being decoded.
     63                     This value is divisible by 4.
     64                     [const Int]
     65 
     66     codebook     =  Value that denotes which Huffman codebook was used for
     67                     the encoding of this grouped scalefactor band.
     68                     [const Int]
     69 
     70     ms_used      =  Flag that denotes whether M/S is active for this band.
     71                     [const Bool]
     72 
     73     q_formatLeft = The Q-format for the left channel's fixed-point spectral
     74                    coefficients, on a per-scalefactor band, non-grouped basis.
     75                    [const Int *, length MAXBANDS]
     76 
     77     q_formatRight = The Q-format for the right channel's fixed-point spectral
     78                     coefficients, on a per-scalefactor band, non-grouped basis.
     79                     [Int *, length MAXBANDS]
     80 
     81     coefLeft =  Array containing the fixed-point spectral coefficients
     82                 for the left channel.
     83                 [const Int32 *, length 1024]
     84 
     85     coefRight = Array containing the fixed-point spectral coefficients
     86                 for the right channel.
     87                 [Int32 *, length 1024]
     88 
     89  Local Stores/Buffers/Pointers Needed:
     90     intensity_factor =  Table which stores the values of
     91                         0.5^(0), 0.5^(1/4), 0.5^(2/4) and 0.5^(3/4)
     92                         [UInt, length 4]
     93 
     94  Global Stores/Buffers/Pointers Needed:
     95     None
     96 
     97  Outputs:
     98     None
     99 
    100  Pointers and Buffers Modified:
    101     coefRight[]         Contains the new spectral information
    102 
    103     q_formatRight[]     Q-format may be updated with changed fixed-point
    104                         data in coefRight.
    105 
    106  Local Stores Modified:
    107     None
    108 
    109  Global Stores Modified:
    110     None
    111 
    112 ------------------------------------------------------------------------------
    113  FUNCTION DESCRIPTION
    114 
    115  This function applies Intensity Stereo, generating data on the right channel
    116  that is derived from data on the Left.  A scalefactor is applied using the
    117  following formula...
    118 
    119  RightCh = LeftCh*0.5^(scalefactor/4)
    120 
    121  This function works for one scalefactor band, which may belong to a group.
    122  (i.e. the same scalefactor band repeated across multiple windows belonging
    123   to one group.)
    124 
    125 ------------------------------------------------------------------------------
    126  REQUIREMENTS
    127 
    128  codebook must be either INTENSITY_HCB or INTENSITY_HCB2 when this function
    129  is called.
    130 
    131  ms_used must be 1 when TRUE, 0 when FALSE.
    132 
    133  wins_in_group falls within the range [1-8]
    134 
    135 ------------------------------------------------------------------------------
    136  REFERENCES
    137 
    138  (1) ISO/IEC 14496-3:1999(E)
    139      Part 3
    140         Subpart 4.6.7.2.3 Decoding Process (Intensity Stereo)
    141 
    142  (2) MPEG-2 NBC Audio Decoder
    143    "This software module was originally developed by AT&T, Dolby
    144    Laboratories, Fraunhofer Gesellschaft IIS in the course of development
    145    of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
    146    3. This software module is an implementation of a part of one or more
    147    MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
    148    Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
    149    standards free license to this software module or modifications thereof
    150    for use in hardware or software products claiming conformance to the
    151    MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
    152    module in hardware or software products are advised that this use may
    153    infringe existing patents. The original developer of this software
    154    module and his/her company, the subsequent editors and their companies,
    155    and ISO/IEC have no liability for use of this software module or
    156    modifications thereof in an implementation. Copyright is not released
    157    for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
    158    developer retains full right to use the code for his/her  own purpose,
    159    assign or donate the code to a third party and to inhibit third party
    160    from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
    161    This copyright notice must be included in all copies or derivative
    162    works."
    163    Copyright(c)1996.
    164 
    165 ------------------------------------------------------------------------------
    166  PSEUDO-CODE
    167     multiplier = codebook AND 0x1;
    168 
    169     multiplier = multiplier XOR ms_used;
    170 
    171     multiplier = multiplier << 1;
    172 
    173     multiplier = multiplier - 1;
    174 
    175     multiplier = multiplier * intensity_factor[scalefactor & 0x3];
    176 
    177     scf_div_4 = (scalefactor >> 2);
    178 
    179     nextWinPtrUpdate = (coef_per_win - band_length);
    180 
    181     FOR (win_indx = wins_in_group; win_indx > 0; win_indx--)
    182 
    183         *(pQformatRight) = scf_div_4 + *(pQformatLeft) - 1;
    184 
    185         FOR (tempInt = band_length; tempInt > 0; tempInt--)
    186            tempInt2 = (Int)(*(pCoefLeft) >> 16);
    187 
    188            *(pCoefRight) = tempInt2 * multiplier;
    189 
    190            pCoefRight = pCoefRight + 1;
    191            pCoefLeft  = pCoefLeft  + 1;
    192 
    193         ENDFOR
    194 
    195         pCoefRight = pCoefRight + nextWinPtrUpdate;
    196         pCoefLeft  = pCoefLeft + nextWinPtrUpdate;
    197 
    198         pQformatRight = pQformatRight + sfb_per_win;
    199         pQformatLeft  = pQformatLeft  + sfb_per_win;
    200     ENDFOR
    201 
    202 ------------------------------------------------------------------------------
    203  RESOURCES USED
    204    When the code is written for a specific target processor the
    205    resources used should be documented below.
    206 
    207  STACK USAGE: [stack count for this module] + [variable to represent
    208           stack usage for each subroutine called]
    209 
    210      where: [stack usage variable] = stack usage for [subroutine
    211          name] (see [filename].ext)
    212 
    213  DATA MEMORY USED: x words
    214 
    215  PROGRAM MEMORY USED: x words
    216 
    217  CLOCK CYCLES: [cycle count equation for this module] + [variable
    218            used to represent cycle count for each subroutine
    219            called]
    220 
    221      where: [cycle count variable] = cycle count for [subroutine
    222         name] (see [filename].ext)
    223 
    224 ------------------------------------------------------------------------------
    225 */
    226 
    227 
    228 /*----------------------------------------------------------------------------
    229 ; INCLUDES
    230 ----------------------------------------------------------------------------*/
    231 #include "pv_audio_type_defs.h"
    232 #include "intensity_right.h"
    233 #include "e_huffmanconst.h"
    234 
    235 #include "fxp_mul32.h"
    236 #include "aac_mem_funcs.h"
    237 
    238 
    239 /*----------------------------------------------------------------------------
    240 ; MACROS
    241 ; Define module specific macros here
    242 ----------------------------------------------------------------------------*/
    243 
    244 /*----------------------------------------------------------------------------
    245 ; DEFINES
    246 ; Include all pre-processor statements here. Include conditional
    247 ; compile variables also.
    248 ----------------------------------------------------------------------------*/
    249 
    250 /*----------------------------------------------------------------------------
    251 ; LOCAL FUNCTION DEFINITIONS
    252 ; Function Prototype declaration
    253 ----------------------------------------------------------------------------*/
    254 
    255 /*----------------------------------------------------------------------------
    256 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    257 ; Variable declaration - defined here and used outside this module
    258 ----------------------------------------------------------------------------*/
    259 const Int16 intensity_factor[4] =
    260 {
    261     32767,  /* (0.5^0.00)*2^15 - 1 (minus 1 for storage as type Int) */
    262     27554,  /* (0.5^0.25)*2^15 */
    263     23170,  /* (0.5^0.50)*2^15 */
    264     19484
    265 }; /* (0.5^0.75)*2^15 */
    266 
    267 
    268 /*----------------------------------------------------------------------------
    269 ; EXTERNAL FUNCTION REFERENCES
    270 ; Declare functions defined elsewhere and referenced in this module
    271 ----------------------------------------------------------------------------*/
    272 
    273 /*----------------------------------------------------------------------------
    274 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    275 ; Declare variables used in this module but defined elsewhere
    276 ----------------------------------------------------------------------------*/
    277 
    278 /*----------------------------------------------------------------------------
    279 ; FUNCTION CODE
    280 ----------------------------------------------------------------------------*/
    281 
    282 void intensity_right(
    283     const Int   scalefactor,
    284     const Int   coef_per_win,
    285     const Int   sfb_per_win,
    286     const Int   wins_in_group,
    287     const Int   band_length,
    288     const Int   codebook,
    289     const Bool  ms_used,
    290     const Int   q_formatLeft[],
    291     Int   q_formatRight[],
    292     const Int32 coefLeft[],
    293     Int32 coefRight[])
    294 
    295 {
    296     const Int32 *pCoefLeft  = coefLeft;
    297     Int32 *pCoefRight = coefRight;
    298 
    299     const Int *pQformatLeft  = q_formatLeft;
    300     Int *pQformatRight = q_formatRight;
    301 
    302     Int   multiplier;
    303     Int   scf_div_4;
    304     Int   nextWinPtrUpdate;
    305 
    306     /*
    307      * The sign of the intensity multiplier obeys the following table...
    308      *
    309      * codebook       | ms_used | multiplier
    310      * --------------------------------------
    311      * INTENSITY_HCB  | TRUE    |    -1
    312      * INTENSITY_HCB  | FALSE   |    +1
    313      * INTENSITY_HCB2 | TRUE    |    +1
    314      * INTENSITY_HCB2 | FALSE   |    -1
    315      *
    316      * In binary, the above table is represented as...
    317      *
    318      * codebook       | ms_used | multiplier
    319      * --------------------------------------
    320      * 1111b          | 1       |    -1
    321      * 1111b          | 0       |    +1
    322      * 1110b          | 1       |    +1
    323      * 1110b          | 0       |    -1
    324      *
    325      */
    326 
    327     /*
    328      * Deriving the correct value for "multiplier" is illustrated
    329      * below for all 4 possible combinations of codebook and ms_used
    330      */
    331 
    332     /*
    333      * 1111b AND 0x1 = 1b
    334      * 1111b AND 0x1 = 1b
    335      * 1110b AND 0x1 = 0b
    336      * 1110b AND 0x1 = 0b
    337      */
    338     multiplier  = (codebook & 0x1);
    339 
    340     /*
    341      * 1b XOR 1 = 0b
    342      * 1b XOR 0 = 1b
    343      * 0b XOR 1 = 1b
    344      * 0b XOR 0 = 0b
    345      */
    346     multiplier ^= ms_used;
    347 
    348     /*
    349      * 0b << 1 = 0
    350      * 1b << 1 = 2
    351      * 1b << 1 = 2
    352      * 0b << 1 = 0
    353      */
    354     multiplier <<= 1;
    355 
    356     /*
    357      * 0 - 1 = -1
    358      * 2 - 1 = +1
    359      * 2 - 1 = +1
    360      * 0 - 1 = -1
    361      */
    362     multiplier--;
    363 
    364     multiplier *= intensity_factor[scalefactor & 0x3];
    365 
    366     scf_div_4 = (scalefactor >> 2);
    367 
    368     /*
    369      * Step through all the windows in this group, replacing this
    370      * band in each window's spectrum with
    371      * left-channel correlated data
    372      */
    373 
    374     nextWinPtrUpdate = (coef_per_win - band_length);
    375 
    376     for (Int win_indx = wins_in_group; win_indx > 0; win_indx--)
    377     {
    378 
    379         /*
    380          * Calculate q_formatRight
    381          *
    382          * q_formatLeft must be included, since the values
    383          * on the right-channel are derived from the values
    384          * on the left-channel.
    385          *
    386          * scalefactor/4 is included, since the intensity
    387          * formula is RightCh = LeftCh*0.5^(scalefactor/4)
    388          *
    389          * powers of 0.5 increase the q_format by 1.
    390          * (Another way to multiply something by 0.5^(x)
    391          *  is to increase its q-format by x.)
    392          *
    393          * Finally the q-format must be decreased by 1.
    394          * The reason for this is because the table is stored
    395          * in q-15 format, but we are shifting by 16 to do
    396          * a 16 x 16 multiply.
    397          */
    398 
    399         *(pQformatRight) = scf_div_4 + *(pQformatLeft);
    400 
    401         /*
    402          * reconstruct right intensity values
    403          *
    404          * to make things faster, this for loop
    405          * can be partially unrolled, since band_length is a multiple
    406          * of four.
    407          */
    408 
    409 
    410         if (multiplier == 32767)
    411         {
    412             Int32 tempInt2 = *(pCoefLeft++);
    413             Int32 tempInt22 = *(pCoefLeft++);
    414 
    415             for (Int tempInt = band_length >> 1; tempInt > 0; tempInt--)
    416             {
    417                 *(pCoefRight++) = tempInt2;
    418                 *(pCoefRight++) = tempInt22;
    419                 tempInt2 = *(pCoefLeft++);
    420                 tempInt22 = *(pCoefLeft++);
    421             }
    422 
    423         }
    424         else
    425         {
    426 
    427             Int32 tempInt2 = *(pCoefLeft++);
    428             Int32 tempInt22 = *(pCoefLeft++);
    429             for (Int tempInt = band_length >> 1; tempInt > 0; tempInt--)
    430             {
    431                 *(pCoefRight++) = fxp_mul32_by_16(tempInt2, multiplier) << 1;
    432                 *(pCoefRight++) = fxp_mul32_by_16(tempInt22, multiplier) << 1;
    433                 tempInt2 = *(pCoefLeft++);
    434                 tempInt22 = *(pCoefLeft++);
    435             }
    436         }
    437 
    438         /*
    439          * Set pCoefRight and pCoefLeft to the beginning of
    440          * this sfb in the next window in the group.
    441          */
    442 
    443         pCoefRight += nextWinPtrUpdate;
    444         pCoefLeft  += (nextWinPtrUpdate - 2);
    445 
    446         /*
    447          * Update pQformatRight and pQformatLeft to this sfb in
    448          * in the next window in the group.
    449          */
    450 
    451         pQformatRight += sfb_per_win;
    452         pQformatLeft  += sfb_per_win;
    453 
    454     } /* for (win_indx) */
    455 
    456 
    457 } /* void intensity_right */
    458