Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84 /*!
     85   \file
     86   \brief  parametric stereo decoder
     87 */
     88 
     89 #include "psdec.h"
     90 
     91 
     92 
     93 #include "FDK_bitbuffer.h"
     94 #include "psdec_hybrid.h"
     95 
     96 #include "sbr_rom.h"
     97 #include "sbr_ram.h"
     98 
     99 #include "FDK_tools_rom.h"
    100 
    101 #include "genericStds.h"
    102 
    103 #include "FDK_trigFcts.h"
    104 
    105 
    106 /********************************************************************/
    107 /*                       MLQUAL DEFINES                             */
    108 /********************************************************************/
    109 
    110   #define FRACT_ZERO FRACT_BITS-1
    111 /********************************************************************/
    112 
    113 SBR_ERROR ResetPsDec( HANDLE_PS_DEC h_ps_d );
    114 
    115 void ResetPsDeCor( HANDLE_PS_DEC h_ps_d );
    116 
    117 
    118 /***** HELPERS *****/
    119 
    120 static void assignTimeSlotsPS (FIXP_DBL *bufAdr, FIXP_DBL **bufPtr, const int numSlots, const int numChan);
    121 
    122 
    123 
    124 /*******************/
    125 
    126 #define DIV3 FL2FXCONST_DBL(1.f/3.f)     /* division 3.0 */
    127 #define DIV1_5 FL2FXCONST_DBL(2.f/3.f)   /* division 1.5 */
    128 
    129 /***************************************************************************/
    130 /*!
    131   \brief  Creates one instance of the PS_DEC struct
    132 
    133   \return Error info
    134 
    135 ****************************************************************************/
    136 int
    137 CreatePsDec( HANDLE_PS_DEC *h_PS_DEC,   /*!< pointer to the module state */
    138              int aacSamplesPerFrame
    139            )
    140 {
    141   SBR_ERROR errorInfo = SBRDEC_OK;
    142   HANDLE_PS_DEC  h_ps_d;
    143   int i;
    144 
    145   if (*h_PS_DEC == NULL) {
    146     /* Get ps dec ram */
    147     h_ps_d = GetRam_ps_dec();
    148     if (h_ps_d == NULL) {
    149       errorInfo = SBRDEC_MEM_ALLOC_FAILED;
    150       goto bail;
    151     }
    152   } else {
    153     /* Reset an open instance */
    154     h_ps_d = *h_PS_DEC;
    155   }
    156 
    157    /* initialisation */
    158   switch (aacSamplesPerFrame) {
    159   case 960:
    160     h_ps_d->noSubSamples = 30;              /* col */
    161     break;
    162   case 1024:
    163     h_ps_d->noSubSamples = 32;              /* col */
    164     break;
    165   default:
    166     h_ps_d->noSubSamples = -1;
    167     break;
    168   }
    169 
    170   if (h_ps_d->noSubSamples >  MAX_NUM_COL
    171    || h_ps_d->noSubSamples <= 0)
    172   {
    173     goto bail;
    174   }
    175   h_ps_d->noChannels   = NO_QMF_CHANNELS;   /* row */
    176 
    177   h_ps_d->psDecodedPrv   =  0;
    178   h_ps_d->procFrameBased = -1;
    179   for (i = 0; i < (1)+1; i++) {
    180     h_ps_d->bPsDataAvail[i]  =  ppt_none;
    181   }
    182 
    183 
    184   for (i = 0; i < (1)+1; i++) {
    185     FDKmemclear(&h_ps_d->bsData[i].mpeg, sizeof(MPEG_PS_BS_DATA));
    186   }
    187 
    188   errorInfo = ResetPsDec( h_ps_d );
    189 
    190   if ( errorInfo != SBRDEC_OK )
    191     goto bail;
    192 
    193   ResetPsDeCor( h_ps_d );
    194 
    195   *h_PS_DEC = h_ps_d;
    196 
    197 
    198 
    199   return 0;
    200 
    201 bail:
    202   DeletePsDec(&h_ps_d);
    203 
    204   return -1;
    205 } /*END CreatePsDec */
    206 
    207 /***************************************************************************/
    208 /*!
    209   \brief  Delete one instance of the PS_DEC struct
    210 
    211   \return Error info
    212 
    213 ****************************************************************************/
    214 int
    215 DeletePsDec( HANDLE_PS_DEC *h_PS_DEC)  /*!< pointer to the module state */
    216 {
    217   if (*h_PS_DEC == NULL) {
    218     return -1;
    219   }
    220 
    221 
    222   FreeRam_ps_dec(h_PS_DEC);
    223 
    224 
    225   return 0;
    226 } /*END DeletePsDec */
    227 
    228 /***************************************************************************/
    229 /*!
    230   \brief resets some values of the PS handle to default states
    231 
    232   \return
    233 
    234 ****************************************************************************/
    235 SBR_ERROR ResetPsDec( HANDLE_PS_DEC h_ps_d )  /*!< pointer to the module state */
    236 {
    237   SBR_ERROR errorInfo = SBRDEC_OK;
    238   INT i;
    239 
    240   const UCHAR noQmfBandsInHybrid20 = 3;
    241   /* const UCHAR noQmfBandsInHybrid34 = 5; */
    242 
    243   const UCHAR aHybridResolution20[] = { HYBRID_8_CPLX,
    244                                         HYBRID_2_REAL,
    245                                         HYBRID_2_REAL };
    246 
    247   h_ps_d->specificTo.mpeg.delayBufIndex   = 0;
    248 
    249   /* explicitly init state variables to safe values (until first ps header arrives) */
    250 
    251   h_ps_d->specificTo.mpeg.lastUsb        =  0;
    252 
    253   h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer = -(DFRACT_BITS-1);
    254 
    255   FDKmemclear(h_ps_d->specificTo.mpeg.aDelayBufIndexDelayQmf, (NO_QMF_CHANNELS-FIRST_DELAY_SB)*sizeof(UCHAR));
    256   h_ps_d->specificTo.mpeg.noSampleDelay = delayIndexQmf[0];
    257 
    258   for (i=0 ; i < NO_SERIAL_ALLPASS_LINKS; i++) {
    259     h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[i] = 0;
    260   }
    261 
    262   h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[0] = h_ps_d->specificTo.mpeg.aaQmfDelayBufReal;
    263 
    264   assignTimeSlotsPS ( h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[0] + (NO_QMF_CHANNELS-FIRST_DELAY_SB),
    265                      &h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[1],
    266                       h_ps_d->specificTo.mpeg.noSampleDelay-1,
    267                       (NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB));
    268 
    269   h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[0] = h_ps_d->specificTo.mpeg.aaQmfDelayBufImag;
    270 
    271   assignTimeSlotsPS ( h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[0] + (NO_QMF_CHANNELS-FIRST_DELAY_SB),
    272                      &h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[1],
    273                       h_ps_d->specificTo.mpeg.noSampleDelay-1,
    274                       (NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB));
    275 
    276   /* Hybrid Filter Bank 1 creation. */
    277   errorInfo = InitHybridFilterBank ( &h_ps_d->specificTo.mpeg.hybrid,
    278                                       h_ps_d->noSubSamples,
    279                                       noQmfBandsInHybrid20,
    280                                       aHybridResolution20 );
    281 
    282   for ( i = 0; i < NO_IID_GROUPS; i++ )
    283   {
    284     h_ps_d->specificTo.mpeg.h11rPrev[i] = FL2FXCONST_DBL(0.5f);
    285     h_ps_d->specificTo.mpeg.h12rPrev[i] = FL2FXCONST_DBL(0.5f);
    286   }
    287 
    288   FDKmemclear( h_ps_d->specificTo.mpeg.h21rPrev, sizeof( h_ps_d->specificTo.mpeg.h21rPrev ) );
    289   FDKmemclear( h_ps_d->specificTo.mpeg.h22rPrev, sizeof( h_ps_d->specificTo.mpeg.h22rPrev ) );
    290 
    291   return errorInfo;
    292 }
    293 
    294 /***************************************************************************/
    295 /*!
    296   \brief  clear some buffers used in decorrelation process
    297 
    298   \return
    299 
    300 ****************************************************************************/
    301 void ResetPsDeCor( HANDLE_PS_DEC h_ps_d )  /*!< pointer to the module state */
    302 {
    303   INT i;
    304 
    305   FDKmemclear(h_ps_d->specificTo.mpeg.aPeakDecayFastBin, NO_MID_RES_BINS*sizeof(FIXP_DBL));
    306   FDKmemclear(h_ps_d->specificTo.mpeg.aPrevNrgBin, NO_MID_RES_BINS*sizeof(FIXP_DBL));
    307   FDKmemclear(h_ps_d->specificTo.mpeg.aPrevPeakDiffBin, NO_MID_RES_BINS*sizeof(FIXP_DBL));
    308   FDKmemclear(h_ps_d->specificTo.mpeg.aPowerPrevScal, NO_MID_RES_BINS*sizeof(SCHAR));
    309 
    310   for (i=0 ; i < FIRST_DELAY_SB ; i++) {
    311     FDKmemclear(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL));
    312     FDKmemclear(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL));
    313   }
    314   for (i=0 ; i < NO_SUB_QMF_CHANNELS ; i++) {
    315     FDKmemclear(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL));
    316     FDKmemclear(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL));
    317   }
    318 
    319 }
    320 
    321 /*******************************************************************************/
    322 
    323 /* slot based funcion prototypes */
    324 
    325 static void deCorrelateSlotBased( HANDLE_PS_DEC h_ps_d,
    326 
    327                                   FIXP_DBL    *mHybridRealLeft,
    328                                   FIXP_DBL    *mHybridImagLeft,
    329                                   SCHAR        sf_mHybridLeft,
    330 
    331                                   FIXP_DBL    *rIntBufferLeft,
    332                                   FIXP_DBL    *iIntBufferLeft,
    333                                   SCHAR        sf_IntBuffer,
    334 
    335                                   FIXP_DBL    *mHybridRealRight,
    336                                   FIXP_DBL    *mHybridImagRight,
    337 
    338                                   FIXP_DBL    *rIntBufferRight,
    339                                   FIXP_DBL    *iIntBufferRight );
    340 
    341 static void applySlotBasedRotation( HANDLE_PS_DEC h_ps_d,
    342 
    343                                     FIXP_DBL  *mHybridRealLeft,
    344                                     FIXP_DBL  *mHybridImagLeft,
    345 
    346                                     FIXP_DBL  *QmfLeftReal,
    347                                     FIXP_DBL  *QmfLeftImag,
    348 
    349                                     FIXP_DBL  *mHybridRealRight,
    350                                     FIXP_DBL  *mHybridImagRight,
    351 
    352                                     FIXP_DBL  *QmfRightReal,
    353                                     FIXP_DBL  *QmfRightImag
    354                                   );
    355 
    356 
    357 /***************************************************************************/
    358 /*!
    359   \brief  Get scale factor for all ps delay buffer.
    360 
    361   \return
    362 
    363 ****************************************************************************/
    364 static
    365 int getScaleFactorPsStatesBuffer(HANDLE_PS_DEC   h_ps_d)
    366 {
    367   INT i;
    368   int scale = DFRACT_BITS-1;
    369 
    370   for (i=0; i<NO_QMF_BANDS_HYBRID20; i++) {
    371     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.hybrid.mQmfBufferRealSlot[i], NO_SUB_QMF_CHANNELS));
    372     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.hybrid.mQmfBufferImagSlot[i], NO_SUB_QMF_CHANNELS));
    373   }
    374 
    375   for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) {
    376     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaRealDelayBufferQmf[i], FIRST_DELAY_SB));
    377     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaImagDelayBufferQmf[i], FIRST_DELAY_SB));
    378   }
    379 
    380   for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) {
    381     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaRealDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS));
    382     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaImagDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS));
    383   }
    384 
    385   for (i=0; i<FIRST_DELAY_SB; i++) {
    386     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS));
    387     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS));
    388   }
    389 
    390   for (i=0; i<NO_SUB_QMF_CHANNELS; i++) {
    391     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS));
    392     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS));
    393   }
    394 
    395   for (i=0; i<MAX_DELAY_BUFFER_SIZE; i++)
    396   {
    397     INT len;
    398     if (i==0)
    399       len = NO_QMF_CHANNELS-FIRST_DELAY_SB;
    400     else
    401       len = NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB;
    402 
    403     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[i], len));
    404     scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[i], len));
    405   }
    406 
    407   return (scale);
    408 }
    409 
    410 /***************************************************************************/
    411 /*!
    412   \brief  Rescale all ps delay buffer.
    413 
    414   \return
    415 
    416 ****************************************************************************/
    417 static
    418 void scalePsStatesBuffer(HANDLE_PS_DEC h_ps_d,
    419                          int           scale)
    420 {
    421   INT i;
    422 
    423   if (scale < 0)
    424     scale = fixMax((INT)scale,(INT)-(DFRACT_BITS-1));
    425   else
    426     scale = fixMin((INT)scale,(INT)DFRACT_BITS-1);
    427 
    428   for (i=0; i<NO_QMF_BANDS_HYBRID20; i++) {
    429     scaleValues( h_ps_d->specificTo.mpeg.hybrid.mQmfBufferRealSlot[i], NO_SUB_QMF_CHANNELS, scale );
    430     scaleValues( h_ps_d->specificTo.mpeg.hybrid.mQmfBufferImagSlot[i], NO_SUB_QMF_CHANNELS, scale );
    431   }
    432 
    433   for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) {
    434     scaleValues( h_ps_d->specificTo.mpeg.aaRealDelayBufferQmf[i], FIRST_DELAY_SB, scale );
    435     scaleValues( h_ps_d->specificTo.mpeg.aaImagDelayBufferQmf[i], FIRST_DELAY_SB, scale );
    436   }
    437 
    438   for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) {
    439     scaleValues( h_ps_d->specificTo.mpeg.aaRealDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS, scale );
    440     scaleValues( h_ps_d->specificTo.mpeg.aaImagDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS, scale );
    441   }
    442 
    443   for (i=0; i<FIRST_DELAY_SB; i++) {
    444     scaleValues( h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS, scale );
    445     scaleValues( h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS, scale );
    446   }
    447 
    448   for (i=0; i<NO_SUB_QMF_CHANNELS; i++) {
    449     scaleValues( h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS, scale );
    450     scaleValues( h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS, scale );
    451   }
    452 
    453   for (i=0; i<MAX_DELAY_BUFFER_SIZE; i++) {
    454     INT len;
    455     if (i==0)
    456       len = NO_QMF_CHANNELS-FIRST_DELAY_SB;
    457     else
    458       len = NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB;
    459 
    460     scaleValues( h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[i], len, scale );
    461     scaleValues( h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[i], len, scale );
    462   }
    463 
    464   scale <<= 1;
    465 
    466   scaleValues( h_ps_d->specificTo.mpeg.aPeakDecayFastBin, NO_MID_RES_BINS, scale );
    467   scaleValues( h_ps_d->specificTo.mpeg.aPrevPeakDiffBin, NO_MID_RES_BINS, scale );
    468   scaleValues( h_ps_d->specificTo.mpeg.aPrevNrgBin, NO_MID_RES_BINS, scale );
    469 }
    470 
    471 /***************************************************************************/
    472 /*!
    473   \brief  Scale input channel to the same scalefactor and rescale hybrid
    474           filterbank values
    475 
    476   \return
    477 
    478 ****************************************************************************/
    479 
    480 void scalFilterBankValues( HANDLE_PS_DEC   h_ps_d,
    481                            FIXP_DBL      **fixpQmfReal,
    482                            FIXP_DBL      **fixpQmfImag,
    483                            int             lsb,
    484                            int             scaleFactorLowBandSplitLow,
    485                            int             scaleFactorLowBandSplitHigh,
    486                            SCHAR          *scaleFactorLowBand_lb,
    487                            SCHAR          *scaleFactorLowBand_hb,
    488                            int             scaleFactorHighBands,
    489                            INT            *scaleFactorHighBand,
    490                            INT             noCols
    491                          )
    492 {
    493   INT maxScal;
    494 
    495   INT i;
    496 
    497   scaleFactorHighBands        =  -scaleFactorHighBands;
    498   scaleFactorLowBandSplitLow  =  -scaleFactorLowBandSplitLow;
    499   scaleFactorLowBandSplitHigh =  -scaleFactorLowBandSplitHigh;
    500 
    501   /* get max scale factor */
    502   maxScal = fixMax(scaleFactorHighBands,fixMax(scaleFactorLowBandSplitLow, scaleFactorLowBandSplitHigh ));
    503 
    504   {
    505     int headroom  = getScaleFactorPsStatesBuffer(h_ps_d);
    506     maxScal   = fixMax(maxScal,(INT)(h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer-headroom));
    507     maxScal  += 1;
    508   }
    509 
    510   /* scale whole left channel to the same scale factor */
    511 
    512   /* low band ( overlap buffer ) */
    513   if ( maxScal != scaleFactorLowBandSplitLow ) {
    514     INT scale = scaleFactorLowBandSplitLow - maxScal;
    515     for ( i=0; i<(6); i++ ) {
    516       scaleValues( fixpQmfReal[i], lsb, scale );
    517       scaleValues( fixpQmfImag[i], lsb, scale );
    518     }
    519   }
    520   /* low band ( current frame ) */
    521   if ( maxScal != scaleFactorLowBandSplitHigh ) {
    522     INT scale = scaleFactorLowBandSplitHigh - maxScal;
    523     /* for ( i=(6); i<(6)+MAX_NUM_COL; i++ ) { */
    524     for ( i=(6); i<(6)+noCols; i++ ) {
    525       scaleValues( fixpQmfReal[i], lsb, scale );
    526       scaleValues( fixpQmfImag[i], lsb, scale );
    527     }
    528   }
    529   /* high band */
    530   if ( maxScal != scaleFactorHighBands ) {
    531     INT scale = scaleFactorHighBands - maxScal;
    532     /* for ( i=0; i<MAX_NUM_COL; i++ ) { */
    533     for ( i=0; i<noCols; i++ ) {
    534       scaleValues( &fixpQmfReal[i][lsb], (64)-lsb, scale );
    535       scaleValues( &fixpQmfImag[i][lsb], (64)-lsb, scale );
    536     }
    537   }
    538 
    539   if ( maxScal != h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer )
    540     scalePsStatesBuffer(h_ps_d,(h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer-maxScal));
    541 
    542   h_ps_d->specificTo.mpeg.hybrid.sf_mQmfBuffer = maxScal;
    543   h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer = maxScal;
    544 
    545   *scaleFactorHighBand += maxScal - scaleFactorHighBands;
    546 
    547   h_ps_d->rescal = maxScal - scaleFactorLowBandSplitHigh;
    548   h_ps_d->sf_IntBuffer = maxScal;
    549 
    550   *scaleFactorLowBand_lb += maxScal - scaleFactorLowBandSplitLow;
    551   *scaleFactorLowBand_hb += maxScal - scaleFactorLowBandSplitHigh;
    552 }
    553 
    554 void rescalFilterBankValues( HANDLE_PS_DEC   h_ps_d,                      /* parametric stereo decoder handle     */
    555                              FIXP_DBL      **QmfBufferReal,               /* qmf filterbank values                */
    556                              FIXP_DBL      **QmfBufferImag,               /* qmf filterbank values                */
    557                              int             lsb,                         /* sbr start subband                    */
    558                              INT             noCols)
    559 {
    560   int i;
    561   /* scale back 6 timeslots look ahead for hybrid filterbank to original value */
    562   for ( i=noCols; i<noCols + (6); i++ ) {
    563     scaleValues( QmfBufferReal[i], lsb, h_ps_d->rescal );
    564     scaleValues( QmfBufferImag[i], lsb, h_ps_d->rescal );
    565   }
    566 }
    567 
    568 /***************************************************************************/
    569 /*!
    570   \brief  Generate decorrelated side channel using allpass/delay
    571 
    572   \return
    573 
    574 ****************************************************************************/
    575 static void
    576 deCorrelateSlotBased( HANDLE_PS_DEC h_ps_d,            /*!< pointer to the module state */
    577 
    578                       FIXP_DBL    *mHybridRealLeft,    /*!< left (mono) hybrid values real */
    579                       FIXP_DBL    *mHybridImagLeft,    /*!< left (mono) hybrid values imag */
    580                       SCHAR        sf_mHybridLeft,     /*!< scalefactor for left (mono) hybrid bands */
    581 
    582                       FIXP_DBL    *rIntBufferLeft,     /*!< real qmf bands left (mono) (38x64) */
    583                       FIXP_DBL    *iIntBufferLeft,     /*!< real qmf bands left (mono) (38x64) */
    584                       SCHAR        sf_IntBuffer,       /*!< scalefactor for all left and right qmf bands   */
    585 
    586                       FIXP_DBL    *mHybridRealRight,   /*!< right (decorrelated) hybrid values real */
    587                       FIXP_DBL    *mHybridImagRight,   /*!< right (decorrelated) hybrid values imag */
    588 
    589                       FIXP_DBL    *rIntBufferRight,    /*!< real qmf bands right (decorrelated) (38x64) */
    590                       FIXP_DBL    *iIntBufferRight )   /*!< real qmf bands right (decorrelated) (38x64) */
    591 {
    592 
    593   INT  i, m, sb, gr, bin;
    594 
    595   FIXP_DBL peakDiff, nrg, transRatio;
    596 
    597   FIXP_DBL *RESTRICT aaLeftReal;
    598   FIXP_DBL *RESTRICT aaLeftImag;
    599 
    600   FIXP_DBL *RESTRICT aaRightReal;
    601   FIXP_DBL *RESTRICT aaRightImag;
    602 
    603   FIXP_DBL *RESTRICT pRealDelayBuffer;
    604   FIXP_DBL *RESTRICT pImagDelayBuffer;
    605 
    606   C_ALLOC_SCRATCH_START(aaPowerSlot, FIXP_DBL, NO_MID_RES_BINS);
    607   C_ALLOC_SCRATCH_START(aaTransRatioSlot, FIXP_DBL, NO_MID_RES_BINS);
    608 
    609 /*!
    610 <pre>
    611    parameter index       qmf bands             hybrid bands
    612   ----------------------------------------------------------------------------
    613          0                   0                      0,7
    614          1                   0                      1,6
    615          2                   0                      2
    616          3                   0                      3           HYBRID BANDS
    617          4                   1                      9
    618          5                   1                      8
    619          6                   2                     10
    620          7                   2                     11
    621   ----------------------------------------------------------------------------
    622          8                   3
    623          9                   4
    624         10                   5
    625         11                   6
    626         12                   7
    627         13                   8
    628         14                   9,10      (2 )                      QMF BANDS
    629         15                   11 - 13   (3 )
    630         16                   14 - 17   (4 )
    631         17                   18 - 22   (5 )
    632         18                   23 - 34   (12)
    633         19                   35 - 63   (29)
    634   ----------------------------------------------------------------------------
    635 </pre>
    636 */
    637 
    638   #define FLTR_SCALE 3
    639 
    640   /* hybrid bands (parameter index 0 - 7) */
    641   aaLeftReal  = mHybridRealLeft;
    642   aaLeftImag  = mHybridImagLeft;
    643 
    644   aaPowerSlot[0] = ( fMultAddDiv2( fMultDiv2(aaLeftReal[0],  aaLeftReal[0]),  aaLeftImag[0],  aaLeftImag[0] ) >> FLTR_SCALE ) +
    645                    ( fMultAddDiv2( fMultDiv2(aaLeftReal[7],  aaLeftReal[7]),  aaLeftImag[7],  aaLeftImag[7] ) >> FLTR_SCALE );
    646 
    647   aaPowerSlot[1] = ( fMultAddDiv2( fMultDiv2(aaLeftReal[1],  aaLeftReal[1]),  aaLeftImag[1],  aaLeftImag[1] ) >> FLTR_SCALE ) +
    648                    ( fMultAddDiv2( fMultDiv2(aaLeftReal[6],  aaLeftReal[6]),  aaLeftImag[6],  aaLeftImag[6] ) >> FLTR_SCALE );
    649 
    650   aaPowerSlot[2] =   fMultAddDiv2( fMultDiv2(aaLeftReal[2],  aaLeftReal[2]),  aaLeftImag[2],  aaLeftImag[2] ) >> FLTR_SCALE;
    651   aaPowerSlot[3] =   fMultAddDiv2( fMultDiv2(aaLeftReal[3],  aaLeftReal[3]),  aaLeftImag[3],  aaLeftImag[3] ) >> FLTR_SCALE;
    652 
    653   aaPowerSlot[4] =   fMultAddDiv2( fMultDiv2(aaLeftReal[9],  aaLeftReal[9]),  aaLeftImag[9],  aaLeftImag[9] ) >> FLTR_SCALE;
    654   aaPowerSlot[5] =   fMultAddDiv2( fMultDiv2(aaLeftReal[8],  aaLeftReal[8]),  aaLeftImag[8],  aaLeftImag[8] ) >> FLTR_SCALE;
    655 
    656   aaPowerSlot[6] =   fMultAddDiv2( fMultDiv2(aaLeftReal[10], aaLeftReal[10]), aaLeftImag[10], aaLeftImag[10] ) >> FLTR_SCALE;
    657   aaPowerSlot[7] =   fMultAddDiv2( fMultDiv2(aaLeftReal[11], aaLeftReal[11]), aaLeftImag[11], aaLeftImag[11] ) >> FLTR_SCALE;
    658 
    659   /* qmf bands (parameter index 8 - 19) */
    660   for ( bin = 8; bin < NO_MID_RES_BINS; bin++ ) {
    661     FIXP_DBL slotNrg = FL2FXCONST_DBL(0.f);
    662 
    663     for ( i = groupBorders20[bin+2]; i < groupBorders20[bin+3]; i++ ) {  /* max loops: 29 */
    664       slotNrg += fMultAddDiv2 ( fMultDiv2(rIntBufferLeft[i], rIntBufferLeft[i]), iIntBufferLeft[i], iIntBufferLeft[i]) >> FLTR_SCALE;
    665     }
    666     aaPowerSlot[bin] = slotNrg;
    667 
    668   }
    669 
    670 
    671   /* calculation of transient ratio */
    672   for (bin=0; bin < NO_MID_RES_BINS; bin++) {   /* noBins = 20 ( BASELINE_PS ) */
    673 
    674     h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] = fMult( h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin], PEAK_DECAY_FACTOR );
    675 
    676     if (h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] < aaPowerSlot[bin]) {
    677       h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] = aaPowerSlot[bin];
    678     }
    679 
    680     /* calculate PSmoothPeakDecayDiffNrg */
    681     peakDiff = fMultAdd ( (h_ps_d->specificTo.mpeg.aPrevPeakDiffBin[bin]>>1),
    682                  INT_FILTER_COEFF, h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] - aaPowerSlot[bin] - h_ps_d->specificTo.mpeg.aPrevPeakDiffBin[bin]);
    683 
    684     /* save peakDiff for the next frame */
    685     h_ps_d->specificTo.mpeg.aPrevPeakDiffBin[bin] = peakDiff;
    686 
    687     nrg = h_ps_d->specificTo.mpeg.aPrevNrgBin[bin] + fMult( INT_FILTER_COEFF, aaPowerSlot[bin] - h_ps_d->specificTo.mpeg.aPrevNrgBin[bin] );
    688 
    689     /* Negative energies don't exist. But sometimes they appear due to rounding. */
    690 
    691     nrg = fixMax(nrg,FL2FXCONST_DBL(0.f));
    692 
    693     /* save nrg for the next frame */
    694     h_ps_d->specificTo.mpeg.aPrevNrgBin[bin] = nrg;
    695 
    696     nrg = fMult( nrg, TRANSIENT_IMPACT_FACTOR );
    697 
    698     /* save transient impact factor */
    699     if ( peakDiff <= nrg || peakDiff == FL2FXCONST_DBL(0.0) ) {
    700       aaTransRatioSlot[bin] = (FIXP_DBL)MAXVAL_DBL /* FL2FXCONST_DBL(1.0f)*/;
    701     }
    702     else if ( nrg <= FL2FXCONST_DBL(0.0f) ) {
    703         aaTransRatioSlot[bin] = FL2FXCONST_DBL(0.f);
    704       }
    705     else {
    706       /* scale to denominator */
    707       INT scale_left = fixMax(0, CntLeadingZeros(peakDiff) - 1);
    708       aaTransRatioSlot[bin] = schur_div( nrg<<scale_left, peakDiff<<scale_left, 16);
    709     }
    710   } /* bin */
    711 
    712 
    713 
    714 
    715   #define DELAY_GROUP_OFFSET    20
    716   #define NR_OF_DELAY_GROUPS     2
    717 
    718   FIXP_DBL rTmp, iTmp, rTmp0, iTmp0, rR0, iR0;
    719 
    720   INT TempDelay     = h_ps_d->specificTo.mpeg.delayBufIndex;  /* set delay indices */
    721 
    722   pRealDelayBuffer = h_ps_d->specificTo.mpeg.aaRealDelayBufferSubQmf[TempDelay];
    723   pImagDelayBuffer = h_ps_d->specificTo.mpeg.aaImagDelayBufferSubQmf[TempDelay];
    724 
    725   aaLeftReal  = mHybridRealLeft;
    726   aaLeftImag  = mHybridImagLeft;
    727   aaRightReal = mHybridRealRight;
    728   aaRightImag = mHybridImagRight;
    729 
    730   /************************/
    731   /* ICC groups :  0 -  9 */
    732   /************************/
    733 
    734   /* gr = ICC groups */
    735   for (gr=0; gr < SUBQMF_GROUPS; gr++) {
    736 
    737     transRatio = aaTransRatioSlot[bins2groupMap20[gr]];
    738 
    739     /* sb = subQMF/QMF subband */
    740     sb = groupBorders20[gr];
    741 
    742     /* Update delay buffers, sample delay allpass = 2 */
    743     rTmp0 = pRealDelayBuffer[sb];
    744     iTmp0 = pImagDelayBuffer[sb];
    745 
    746     pRealDelayBuffer[sb] = aaLeftReal[sb];
    747     pImagDelayBuffer[sb] = aaLeftImag[sb];
    748 
    749     /* delay by fraction */
    750     cplxMultDiv2(&rR0, &iR0, rTmp0, iTmp0, aaFractDelayPhaseFactorReSubQmf20[sb], aaFractDelayPhaseFactorImSubQmf20[sb]);
    751     rR0<<=1;
    752     iR0<<=1;
    753 
    754     FIXP_DBL *pAaaRealDelayRBufferSerSubQmf = h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[sb];
    755     FIXP_DBL *pAaaImagDelayRBufferSerSubQmf = h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[sb];
    756 
    757     for (m=0; m<NO_SERIAL_ALLPASS_LINKS ; m++) {
    758 
    759       INT tmpDelayRSer = h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m];
    760 
    761       /* get delayed values from according buffer : m(0)=3; m(1)=4; m(2)=5; */
    762       rTmp0 = pAaaRealDelayRBufferSerSubQmf[tmpDelayRSer];
    763       iTmp0 = pAaaImagDelayRBufferSerSubQmf[tmpDelayRSer];
    764 
    765       /* delay by fraction */
    766       cplxMultDiv2(&rTmp, &iTmp, rTmp0, iTmp0, aaFractDelayPhaseFactorSerReSubQmf20[sb][m], aaFractDelayPhaseFactorSerImSubQmf20[sb][m]);
    767 
    768       rTmp = (rTmp - fMultDiv2(aAllpassLinkDecaySer[m], rR0)) << 1;
    769       iTmp = (iTmp - fMultDiv2(aAllpassLinkDecaySer[m], iR0)) << 1;
    770 
    771       pAaaRealDelayRBufferSerSubQmf[tmpDelayRSer] = rR0 + fMult(aAllpassLinkDecaySer[m], rTmp);
    772       pAaaImagDelayRBufferSerSubQmf[tmpDelayRSer] = iR0 + fMult(aAllpassLinkDecaySer[m], iTmp);
    773 
    774       rR0 = rTmp;
    775       iR0 = iTmp;
    776 
    777       pAaaRealDelayRBufferSerSubQmf += aAllpassLinkDelaySer[m];
    778       pAaaImagDelayRBufferSerSubQmf += aAllpassLinkDelaySer[m];
    779 
    780     } /* m */
    781 
    782     /* duck if a past transient is found */
    783     aaRightReal[sb] = fMult(transRatio, rR0);
    784     aaRightImag[sb] = fMult(transRatio, iR0);
    785 
    786   } /* gr */
    787 
    788 
    789   scaleValues( mHybridRealLeft,  NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM );
    790   scaleValues( mHybridImagLeft,  NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM );
    791   scaleValues( mHybridRealRight, NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM );
    792   scaleValues( mHybridImagRight, NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM );
    793 
    794 
    795   /************************/
    796 
    797   aaLeftReal  = rIntBufferLeft;
    798   aaLeftImag  = iIntBufferLeft;
    799   aaRightReal = rIntBufferRight;
    800   aaRightImag = iIntBufferRight;
    801 
    802   pRealDelayBuffer = h_ps_d->specificTo.mpeg.aaRealDelayBufferQmf[TempDelay];
    803   pImagDelayBuffer = h_ps_d->specificTo.mpeg.aaImagDelayBufferQmf[TempDelay];
    804 
    805   /************************/
    806   /* ICC groups : 10 - 19 */
    807   /************************/
    808 
    809 
    810   /* gr = ICC groups */
    811   for (gr=SUBQMF_GROUPS; gr < NO_IID_GROUPS - NR_OF_DELAY_GROUPS; gr++) {
    812 
    813     transRatio = aaTransRatioSlot[bins2groupMap20[gr]];
    814 
    815     /* sb = subQMF/QMF subband */
    816     for (sb = groupBorders20[gr]; sb < groupBorders20[gr+1]; sb++) {
    817       FIXP_DBL resR, resI;
    818 
    819       /* decayScaleFactor = 1.0f + decay_cutoff * DECAY_SLOPE - DECAY_SLOPE * sb; DECAY_SLOPE = 0.05 */
    820       FIXP_DBL decayScaleFactor = decayScaleFactTable[sb];
    821 
    822       /* Update delay buffers, sample delay allpass = 2 */
    823       rTmp0 = pRealDelayBuffer[sb];
    824       iTmp0 = pImagDelayBuffer[sb];
    825 
    826       pRealDelayBuffer[sb] = aaLeftReal[sb];
    827       pImagDelayBuffer[sb] = aaLeftImag[sb];
    828 
    829       /* delay by fraction */
    830       cplxMultDiv2(&rR0, &iR0, rTmp0, iTmp0, aaFractDelayPhaseFactorReQmf[sb], aaFractDelayPhaseFactorImQmf[sb]);
    831       rR0<<=1;
    832       iR0<<=1;
    833 
    834       resR = fMult(decayScaleFactor, rR0);
    835       resI = fMult(decayScaleFactor, iR0);
    836 
    837       FIXP_DBL *pAaaRealDelayRBufferSerQmf = h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[sb];
    838       FIXP_DBL *pAaaImagDelayRBufferSerQmf = h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[sb];
    839 
    840       for (m=0; m<NO_SERIAL_ALLPASS_LINKS ; m++) {
    841 
    842         INT tmpDelayRSer = h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m];
    843 
    844         /* get delayed values from according buffer : m(0)=3; m(1)=4; m(2)=5; */
    845         rTmp0 = pAaaRealDelayRBufferSerQmf[tmpDelayRSer];
    846         iTmp0 = pAaaImagDelayRBufferSerQmf[tmpDelayRSer];
    847 
    848         /* delay by fraction */
    849         cplxMultDiv2(&rTmp, &iTmp, rTmp0, iTmp0, aaFractDelayPhaseFactorSerReQmf[sb][m], aaFractDelayPhaseFactorSerImQmf[sb][m]);
    850 
    851         rTmp = (rTmp - fMultDiv2(aAllpassLinkDecaySer[m], resR))<<1;
    852         iTmp = (iTmp - fMultDiv2(aAllpassLinkDecaySer[m], resI))<<1;
    853 
    854         resR = fMult(decayScaleFactor, rTmp);
    855         resI = fMult(decayScaleFactor, iTmp);
    856 
    857         pAaaRealDelayRBufferSerQmf[tmpDelayRSer] = rR0 + fMult(aAllpassLinkDecaySer[m], resR);
    858         pAaaImagDelayRBufferSerQmf[tmpDelayRSer] = iR0 + fMult(aAllpassLinkDecaySer[m], resI);
    859 
    860         rR0 = rTmp;
    861         iR0 = iTmp;
    862 
    863         pAaaRealDelayRBufferSerQmf += aAllpassLinkDelaySer[m];
    864         pAaaImagDelayRBufferSerQmf += aAllpassLinkDelaySer[m];
    865 
    866       } /* m */
    867 
    868       /* duck if a past transient is found */
    869       aaRightReal[sb] = fMult(transRatio, rR0);
    870       aaRightImag[sb] = fMult(transRatio, iR0);
    871 
    872     } /* sb */
    873   } /* gr */
    874 
    875   /************************/
    876   /* ICC groups : 20,  21 */
    877   /************************/
    878 
    879 
    880   /* gr = ICC groups */
    881   for (gr=DELAY_GROUP_OFFSET; gr < NO_IID_GROUPS; gr++) {
    882 
    883     INT sbStart = groupBorders20[gr];
    884     INT sbStop  = groupBorders20[gr+1];
    885 
    886     UCHAR *pDelayBufIdx = &h_ps_d->specificTo.mpeg.aDelayBufIndexDelayQmf[sbStart-FIRST_DELAY_SB];
    887 
    888     transRatio = aaTransRatioSlot[bins2groupMap20[gr]];
    889 
    890     /* sb = subQMF/QMF subband */
    891     for (sb = sbStart; sb < sbStop; sb++) {
    892 
    893       /* Update delay buffers */
    894       rR0 = h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB];
    895       iR0 = h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB];
    896 
    897       h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB] = aaLeftReal[sb];
    898       h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB] = aaLeftImag[sb];
    899 
    900       /* duck if a past transient is found */
    901       aaRightReal[sb] = fMult(transRatio, rR0);
    902       aaRightImag[sb] = fMult(transRatio, iR0);
    903 
    904       if (++(*pDelayBufIdx) >= delayIndexQmf[sb]) {
    905         *pDelayBufIdx = 0;
    906       }
    907       pDelayBufIdx++;
    908 
    909     } /* sb */
    910   } /* gr */
    911 
    912 
    913   /* Update delay buffer index */
    914   if (++h_ps_d->specificTo.mpeg.delayBufIndex >= NO_SAMPLE_DELAY_ALLPASS)
    915     h_ps_d->specificTo.mpeg.delayBufIndex = 0;
    916 
    917   for (m=0; m<NO_SERIAL_ALLPASS_LINKS ; m++) {
    918     if (++h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m] >= aAllpassLinkDelaySer[m])
    919       h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m] = 0;
    920   }
    921 
    922 
    923   scaleValues( &rIntBufferLeft[NO_QMF_BANDS_HYBRID20],  NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM );
    924   scaleValues( &iIntBufferLeft[NO_QMF_BANDS_HYBRID20],  NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM );
    925   scaleValues( &rIntBufferRight[NO_QMF_BANDS_HYBRID20], NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM );
    926   scaleValues( &iIntBufferRight[NO_QMF_BANDS_HYBRID20], NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM );
    927 
    928   /* free memory on scratch */
    929   C_ALLOC_SCRATCH_END(aaTransRatioSlot, FIXP_DBL, NO_MID_RES_BINS);
    930   C_ALLOC_SCRATCH_END(aaPowerSlot, FIXP_DBL, NO_MID_RES_BINS);
    931 }
    932 
    933 
    934 void initSlotBasedRotation( HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */
    935                             int env,
    936                             int usb
    937                             ) {
    938 
    939   INT     group = 0;
    940   INT     bin =  0;
    941   INT     noIidSteps;
    942 
    943 /*  const UCHAR *pQuantizedIIDs;*/
    944 
    945   FIXP_SGL  invL;
    946   FIXP_DBL  ScaleL, ScaleR;
    947   FIXP_DBL  Alpha, Beta;
    948   FIXP_DBL  h11r, h12r, h21r, h22r;
    949 
    950   const FIXP_DBL  *PScaleFactors;
    951 
    952   /* Overwrite old values in delay buffers when upper subband is higher than in last frame */
    953   if (env == 0) {
    954 
    955     if ((usb > h_ps_d->specificTo.mpeg.lastUsb) && h_ps_d->specificTo.mpeg.lastUsb) {
    956 
    957       INT i,k,length;
    958 
    959       for (i=h_ps_d->specificTo.mpeg.lastUsb ; i < FIRST_DELAY_SB; i++) {
    960         FDKmemclear(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL));
    961         FDKmemclear(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL));
    962       }
    963 
    964       for (k=0 ; k<NO_SAMPLE_DELAY_ALLPASS; k++) {
    965         FDKmemclear(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[k], FIRST_DELAY_SB*sizeof(FIXP_DBL));
    966       }
    967       length = (usb-FIRST_DELAY_SB)*sizeof(FIXP_DBL);
    968       if(length>0) {
    969         FDKmemclear(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[0], length);
    970         FDKmemclear(h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[0], length);
    971       }
    972       length = (fixMin(NO_DELAY_BUFFER_BANDS,(INT)usb)-FIRST_DELAY_SB)*sizeof(FIXP_DBL);
    973       if(length>0) {
    974         for (k=1 ; k < h_ps_d->specificTo.mpeg.noSampleDelay; k++) {
    975           FDKmemclear(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[k], length);
    976           FDKmemclear(h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[k], length);
    977         }
    978       }
    979     }
    980     h_ps_d->specificTo.mpeg.lastUsb = usb;
    981   } /* env == 0 */
    982 
    983   if (h_ps_d->bsData[h_ps_d->processSlot].mpeg.bFineIidQ)
    984   {
    985     PScaleFactors = ScaleFactorsFine; /* values are shiftet right by one */
    986     noIidSteps = NO_IID_STEPS_FINE;
    987     /*pQuantizedIIDs = quantizedIIDsFine;*/
    988   }
    989 
    990   else
    991   {
    992     PScaleFactors = ScaleFactors; /* values are shiftet right by one */
    993     noIidSteps = NO_IID_STEPS;
    994     /*pQuantizedIIDs = quantizedIIDs;*/
    995   }
    996 
    997 
    998   /* dequantize and decode */
    999   for ( group = 0; group < NO_IID_GROUPS; group++ ) {
   1000 
   1001     bin = bins2groupMap20[group];
   1002 
   1003     /*!
   1004     <h3> type 'A' rotation </h3>
   1005     mixing procedure R_a, used in baseline version<br>
   1006 
   1007      Scale-factor vectors c1 and c2 are precalculated in initPsTables () and stored in
   1008      scaleFactors[] and scaleFactorsFine[] = pScaleFactors [].
   1009      From the linearized IID parameters (intensity differences), two scale factors are
   1010      calculated. They are used to obtain the coefficients h11... h22.
   1011     */
   1012 
   1013     /* ScaleR and ScaleL are scaled by 1 shift right */
   1014 
   1015     ScaleR = PScaleFactors[noIidSteps + h_ps_d->specificTo.mpeg.coef.aaIidIndexMapped[env][bin]];
   1016     ScaleL = PScaleFactors[noIidSteps - h_ps_d->specificTo.mpeg.coef.aaIidIndexMapped[env][bin]];
   1017 
   1018     Beta   = fMult (fMult( Alphas[h_ps_d->specificTo.mpeg.coef.aaIccIndexMapped[env][bin]], ( ScaleR - ScaleL )), FIXP_SQRT05);
   1019     Alpha  = Alphas[h_ps_d->specificTo.mpeg.coef.aaIccIndexMapped[env][bin]]>>1;
   1020 
   1021     /* Alpha and Beta are now both scaled by 2 shifts right */
   1022 
   1023     /* calculate the coefficients h11... h22 from scale-factors and ICC parameters */
   1024 
   1025     /* h values are scaled by 1 shift right */
   1026     {
   1027       FIXP_DBL trigData[4];
   1028 
   1029       inline_fixp_cos_sin(Beta + Alpha, Beta - Alpha, 2, trigData);
   1030       h11r = fMult( ScaleL, trigData[0]);
   1031       h12r = fMult( ScaleR, trigData[2]);
   1032       h21r = fMult( ScaleL, trigData[1]);
   1033       h22r = fMult( ScaleR, trigData[3]);
   1034     }
   1035     /*****************************************************************************************/
   1036     /* Interpolation of the matrices H11... H22:                                             */
   1037     /*                                                                                       */
   1038     /* H11(k,n) = H11(k,n[e]) + (n-n[e]) * (H11(k,n[e+1] - H11(k,n[e])) / (n[e+1] - n[e])    */
   1039     /* ...                                                                                   */
   1040     /*****************************************************************************************/
   1041 
   1042     /* invL = 1/(length of envelope) */
   1043     invL = FX_DBL2FX_SGL(GetInvInt(h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env + 1] - h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env]));
   1044 
   1045     h_ps_d->specificTo.mpeg.coef.H11r[group]  = h_ps_d->specificTo.mpeg.h11rPrev[group];
   1046     h_ps_d->specificTo.mpeg.coef.H12r[group]  = h_ps_d->specificTo.mpeg.h12rPrev[group];
   1047     h_ps_d->specificTo.mpeg.coef.H21r[group]  = h_ps_d->specificTo.mpeg.h21rPrev[group];
   1048     h_ps_d->specificTo.mpeg.coef.H22r[group]  = h_ps_d->specificTo.mpeg.h22rPrev[group];
   1049 
   1050     h_ps_d->specificTo.mpeg.coef.DeltaH11r[group]  = fMult ( h11r - h_ps_d->specificTo.mpeg.coef.H11r[group], invL );
   1051     h_ps_d->specificTo.mpeg.coef.DeltaH12r[group]  = fMult ( h12r - h_ps_d->specificTo.mpeg.coef.H12r[group], invL );
   1052     h_ps_d->specificTo.mpeg.coef.DeltaH21r[group]  = fMult ( h21r - h_ps_d->specificTo.mpeg.coef.H21r[group], invL );
   1053     h_ps_d->specificTo.mpeg.coef.DeltaH22r[group]  = fMult ( h22r - h_ps_d->specificTo.mpeg.coef.H22r[group], invL );
   1054 
   1055     /* update prev coefficients for interpolation in next envelope */
   1056 
   1057     h_ps_d->specificTo.mpeg.h11rPrev[group] = h11r;
   1058     h_ps_d->specificTo.mpeg.h12rPrev[group] = h12r;
   1059     h_ps_d->specificTo.mpeg.h21rPrev[group] = h21r;
   1060     h_ps_d->specificTo.mpeg.h22rPrev[group] = h22r;
   1061 
   1062   } /* group loop */
   1063 }
   1064 
   1065 
   1066 static void applySlotBasedRotation( HANDLE_PS_DEC h_ps_d,        /*!< pointer to the module state */
   1067 
   1068                                     FIXP_DBL  *mHybridRealLeft,  /*!< hybrid values real left  */
   1069                                     FIXP_DBL  *mHybridImagLeft,  /*!< hybrid values imag left  */
   1070 
   1071                                     FIXP_DBL  *QmfLeftReal,      /*!< real bands left qmf channel */
   1072                                     FIXP_DBL  *QmfLeftImag,      /*!< imag bands left qmf channel */
   1073 
   1074                                     FIXP_DBL  *mHybridRealRight, /*!< hybrid values real right  */
   1075                                     FIXP_DBL  *mHybridImagRight, /*!< hybrid values imag right  */
   1076 
   1077                                     FIXP_DBL  *QmfRightReal,     /*!< real bands right qmf channel */
   1078                                     FIXP_DBL  *QmfRightImag      /*!< imag bands right qmf channel */
   1079                                    )
   1080 {
   1081   INT     group;
   1082   INT     subband;
   1083 
   1084   FIXP_DBL *RESTRICT HybrLeftReal;
   1085   FIXP_DBL *RESTRICT HybrLeftImag;
   1086   FIXP_DBL *RESTRICT HybrRightReal;
   1087   FIXP_DBL *RESTRICT HybrRightImag;
   1088 
   1089   FIXP_DBL tmpLeft, tmpRight;
   1090 
   1091 
   1092   /**********************************************************************************************/
   1093   /*!
   1094   <h2> Mapping </h2>
   1095 
   1096   The number of stereo bands that is actually used depends on the number of availble
   1097   parameters for IID and ICC:
   1098   <pre>
   1099    nr. of IID para.| nr. of ICC para. | nr. of Stereo bands
   1100    ----------------|------------------|-------------------
   1101      10,20         |     10,20        |        20
   1102      10,20         |     34           |        34
   1103      34            |     10,20        |        34
   1104      34            |     34           |        34
   1105   </pre>
   1106   In the case the number of parameters for IIS and ICC differs from the number of stereo
   1107   bands, a mapping from the lower number to the higher number of parameters is applied.
   1108   Index mapping of IID and ICC parameters is already done in psbitdec.cpp. Further mapping is
   1109   not needed here in baseline version.
   1110   **********************************************************************************************/
   1111 
   1112   /************************************************************************************************/
   1113   /*!
   1114   <h2> Mixing </h2>
   1115 
   1116   To generate the QMF subband signals for the subband samples n = n[e]+1 ,,, n_[e+1] the
   1117   parameters at position n[e] and n[e+1] are required as well as the subband domain signals
   1118   s_k(n) and d_k(n) for n = n[e]+1... n_[e+1]. n[e] represents the start position for
   1119   envelope e. The border positions n[e] are handled in DecodePS().
   1120 
   1121   The stereo sub subband signals are constructed as:
   1122   <pre>
   1123   l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n)
   1124   r_k(n) = H21(k,n) s_k(n) + H22(k,n) d_k(n)
   1125   </pre>
   1126   In order to obtain the matrices H11(k,n)... H22 (k,n), the vectors h11(b)... h22(b) need to
   1127   be calculated first (b: parameter index). Depending on ICC mode either mixing procedure R_a
   1128   or R_b is used for that. For both procedures, the parameters for parameter position n[e+1]
   1129   is used.
   1130   ************************************************************************************************/
   1131 
   1132 
   1133   /************************************************************************************************/
   1134   /*!
   1135   <h2>Phase parameters </h2>
   1136   With disabled phase parameters (which is the case in baseline version), the H-matrices are
   1137   just calculated by:
   1138 
   1139   <pre>
   1140   H11(k,n[e+1] = h11(b(k))
   1141   (...)
   1142   b(k): parameter index according to mapping table
   1143   </pre>
   1144 
   1145   <h2>Processing of the samples in the sub subbands </h2>
   1146   this loop includes the interpolation of the coefficients Hxx
   1147   ************************************************************************************************/
   1148 
   1149 
   1150   /* loop thru all groups ... */
   1151   HybrLeftReal  = mHybridRealLeft;
   1152   HybrLeftImag  = mHybridImagLeft;
   1153   HybrRightReal = mHybridRealRight;
   1154   HybrRightImag = mHybridImagRight;
   1155 
   1156   /******************************************************/
   1157   /* construct stereo sub subband signals according to: */
   1158   /*                                                    */
   1159   /* l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n)         */
   1160   /* r_k(n) = H12(k,n) s_k(n) + H22(k,n) d_k(n)         */
   1161   /******************************************************/
   1162   for ( group = 0; group < SUBQMF_GROUPS; group++ ) {
   1163 
   1164     h_ps_d->specificTo.mpeg.coef.H11r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH11r[group];
   1165     h_ps_d->specificTo.mpeg.coef.H12r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH12r[group];
   1166     h_ps_d->specificTo.mpeg.coef.H21r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH21r[group];
   1167     h_ps_d->specificTo.mpeg.coef.H22r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH22r[group];
   1168 
   1169     subband = groupBorders20[group];
   1170 
   1171     tmpLeft  = fMultAddDiv2( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightReal[subband]);
   1172     tmpRight = fMultAddDiv2( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightReal[subband]);
   1173     HybrLeftReal [subband] = tmpLeft<<1;
   1174     HybrRightReal[subband] = tmpRight<<1;
   1175 
   1176     tmpLeft  = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightImag[subband]);
   1177     tmpRight = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightImag[subband]);
   1178     HybrLeftImag [subband] = tmpLeft;
   1179     HybrRightImag[subband] = tmpRight;
   1180   }
   1181 
   1182   /* continue in the qmf buffers */
   1183   HybrLeftReal  = QmfLeftReal;
   1184   HybrLeftImag  = QmfLeftImag;
   1185   HybrRightReal = QmfRightReal;
   1186   HybrRightImag = QmfRightImag;
   1187 
   1188   for (; group < NO_IID_GROUPS; group++ ) {
   1189 
   1190     h_ps_d->specificTo.mpeg.coef.H11r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH11r[group];
   1191     h_ps_d->specificTo.mpeg.coef.H12r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH12r[group];
   1192     h_ps_d->specificTo.mpeg.coef.H21r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH21r[group];
   1193     h_ps_d->specificTo.mpeg.coef.H22r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH22r[group];
   1194 
   1195     for ( subband = groupBorders20[group]; subband < groupBorders20[group + 1]; subband++ )
   1196     {
   1197       tmpLeft  = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightReal[subband]);
   1198       tmpRight = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightReal[subband]);
   1199       HybrLeftReal [subband] = tmpLeft;
   1200       HybrRightReal[subband] = tmpRight;
   1201 
   1202       tmpLeft  = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightImag[subband]);
   1203       tmpRight = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightImag[subband]);
   1204       HybrLeftImag [subband] = tmpLeft;
   1205       HybrRightImag[subband] = tmpRight;
   1206 
   1207     } /* subband */
   1208   }
   1209 }
   1210 
   1211 
   1212 /***************************************************************************/
   1213 /*!
   1214   \brief  Applies IID, ICC, IPD and OPD parameters to the current frame.
   1215 
   1216   \return none
   1217 
   1218 ****************************************************************************/
   1219 void
   1220 ApplyPsSlot( HANDLE_PS_DEC h_ps_d,         /*!< handle PS_DEC*/
   1221              FIXP_DBL  **rIntBufferLeft,   /*!< real bands left qmf channel (38x64)  */
   1222              FIXP_DBL  **iIntBufferLeft,   /*!< imag bands left qmf channel (38x64)  */
   1223              FIXP_DBL  *rIntBufferRight,   /*!< real bands right qmf channel (38x64) */
   1224              FIXP_DBL  *iIntBufferRight    /*!< imag bands right qmf channel (38x64) */
   1225            )
   1226 {
   1227 
   1228   /*!
   1229   The 64-band QMF representation of the monaural signal generated by the SBR tool
   1230   is used as input of the PS tool. After the PS processing, the outputs of the left
   1231   and right hybrid synthesis filterbanks are used to generate the stereo output
   1232   signal.
   1233 
   1234   <pre>
   1235 
   1236              -------------            ----------            -------------
   1237             | Hybrid      | M_n[k,m] |          | L_n[k,m] | Hybrid      | l[n]
   1238    m[n] --->| analysis    |--------->|          |--------->| synthesis   |----->
   1239             | filter bank |          |          |          | filter bank |
   1240              -------------           | Stereo   |           -------------
   1241                    |                 | recon-   |
   1242                    |                 | stuction |
   1243                   \|/                |          |
   1244              -------------           |          |
   1245             | De-         | D_n[k,m] |          |
   1246             | correlation |--------->|          |
   1247              -------------           |          |           -------------
   1248                                      |          | R_n[k,m] | Hybrid      | r[n]
   1249                                      |          |--------->| synthesis   |----->
   1250    IID, ICC ------------------------>|          |          | filter bank |
   1251   (IPD, OPD)                          ----------            -------------
   1252 
   1253   m[n]:      QMF represantation of the mono input
   1254   M_n[k,m]:  (sub-)sub-band domain signals of the mono input
   1255   D_n[k,m]:  decorrelated (sub-)sub-band domain signals
   1256   L_n[k,m]:  (sub-)sub-band domain signals of the left output
   1257   R_n[k,m]:  (sub-)sub-band domain signals of the right output
   1258   l[n],r[n]: left/right output signals
   1259 
   1260   </pre>
   1261   */
   1262 
   1263   /* get temporary hybrid qmf values of one timeslot */
   1264   C_ALLOC_SCRATCH_START(hybridRealLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1265   C_ALLOC_SCRATCH_START(hybridImagLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1266   C_ALLOC_SCRATCH_START(hybridRealRight, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1267   C_ALLOC_SCRATCH_START(hybridImagRight, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1268 
   1269   SCHAR sf_IntBuffer     = h_ps_d->sf_IntBuffer;
   1270 
   1271   /* clear workbuffer */
   1272   FDKmemclear(hybridRealLeft,  NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL));
   1273   FDKmemclear(hybridImagLeft,  NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL));
   1274   FDKmemclear(hybridRealRight, NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL));
   1275   FDKmemclear(hybridImagRight, NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL));
   1276 
   1277 
   1278   /*!
   1279   Hybrid analysis filterbank:
   1280   The lower 3 (5) of the 64 QMF subbands are further split to provide better frequency resolution.
   1281   for PS processing.
   1282   For the 10 and 20 stereo bands configuration, the QMF band H_0(w) is split
   1283   up into 8 (sub-) sub-bands and the QMF bands H_1(w) and H_2(w) are spit into 2 (sub-)
   1284   4th. (See figures 8.20 and 8.22 of ISO/IEC 14496-3:2001/FDAM 2:2004(E) )
   1285   */
   1286 
   1287 
   1288   if (h_ps_d->procFrameBased == 1)    /* If we have switched from frame to slot based processing  */
   1289   {                                   /* fill hybrid delay buffer.                                */
   1290     h_ps_d->procFrameBased = 0;
   1291 
   1292     fillHybridDelayLine( rIntBufferLeft,
   1293                          iIntBufferLeft,
   1294                          hybridRealLeft,
   1295                          hybridImagLeft,
   1296                          hybridRealRight,
   1297                          hybridImagRight,
   1298                         &h_ps_d->specificTo.mpeg.hybrid );
   1299   }
   1300 
   1301   slotBasedHybridAnalysis ( rIntBufferLeft[HYBRID_FILTER_DELAY], /* qmf filterbank values                         */
   1302                             iIntBufferLeft[HYBRID_FILTER_DELAY], /* qmf filterbank values                         */
   1303                             hybridRealLeft,                      /* hybrid filterbank values                      */
   1304                             hybridImagLeft,                      /* hybrid filterbank values                      */
   1305                            &h_ps_d->specificTo.mpeg.hybrid);          /* hybrid filterbank handle                      */
   1306 
   1307 
   1308   SCHAR hybridScal = h_ps_d->specificTo.mpeg.hybrid.sf_mQmfBuffer;
   1309 
   1310 
   1311   /*!
   1312   Decorrelation:
   1313   By means of all-pass filtering and delaying, the (sub-)sub-band samples s_k(n) are
   1314   converted into de-correlated (sub-)sub-band samples d_k(n).
   1315   - k: frequency in hybrid spectrum
   1316   - n: time index
   1317   */
   1318 
   1319   deCorrelateSlotBased( h_ps_d,              /* parametric stereo decoder handle       */
   1320                         hybridRealLeft,      /* left hybrid time slot                  */
   1321                         hybridImagLeft,
   1322                         hybridScal,      /* scale factor of left hybrid time slot  */
   1323                         rIntBufferLeft[0],   /* left qmf time slot                     */
   1324                         iIntBufferLeft[0],
   1325                         sf_IntBuffer,        /* scale factor of left and right qmf time slot */
   1326                         hybridRealRight,     /* right hybrid time slot                 */
   1327                         hybridImagRight,
   1328                         rIntBufferRight,     /* right qmf time slot                    */
   1329                         iIntBufferRight );
   1330 
   1331 
   1332 
   1333   /*!
   1334   Stereo Processing:
   1335   The sets of (sub-)sub-band samples s_k(n) and d_k(n) are processed according to
   1336   the stereo cues which are defined per stereo band.
   1337   */
   1338 
   1339 
   1340   applySlotBasedRotation( h_ps_d,            /* parametric stereo decoder handle       */
   1341                           hybridRealLeft,    /* left hybrid time slot                  */
   1342                           hybridImagLeft,
   1343                           rIntBufferLeft[0], /* left qmf time slot                     */
   1344                           iIntBufferLeft[0],
   1345                           hybridRealRight,   /* right hybrid time slot                 */
   1346                           hybridImagRight,
   1347                           rIntBufferRight,   /* right qmf time slot                    */
   1348                           iIntBufferRight );
   1349 
   1350 
   1351 
   1352 
   1353   /*!
   1354   Hybrid synthesis filterbank:
   1355   The stereo processed hybrid subband signals l_k(n) and r_k(n) are fed into the hybrid synthesis
   1356   filterbanks which are identical to the 64 complex synthesis filterbank of the SBR tool. The
   1357   input to the filterbank are slots of 64 QMF samples. For each slot the filterbank outputs one
   1358   block of 64 samples of one reconstructed stereo channel. The hybrid synthesis filterbank is
   1359   computed seperatly for the left and right channel.
   1360   */
   1361 
   1362 
   1363   /* left channel */
   1364   slotBasedHybridSynthesis ( hybridRealLeft,         /* one timeslot of hybrid filterbank values */
   1365                              hybridImagLeft,
   1366                              rIntBufferLeft[0],      /* one timeslot of qmf filterbank values    */
   1367                              iIntBufferLeft[0],
   1368                             &h_ps_d->specificTo.mpeg.hybrid );      /* hybrid filterbank handle                 */
   1369 
   1370   /* right channel */
   1371   slotBasedHybridSynthesis ( hybridRealRight,        /* one timeslot of hybrid filterbank values */
   1372                              hybridImagRight,
   1373                              rIntBufferRight,        /* one timeslot of qmf filterbank values    */
   1374                              iIntBufferRight,
   1375                             &h_ps_d->specificTo.mpeg.hybrid );      /* hybrid filterbank handle                 */
   1376 
   1377 
   1378 
   1379 
   1380 
   1381 
   1382 
   1383   /* free temporary hybrid qmf values of one timeslot */
   1384   C_ALLOC_SCRATCH_END(hybridImagRight, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1385   C_ALLOC_SCRATCH_END(hybridRealRight, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1386   C_ALLOC_SCRATCH_END(hybridImagLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1387   C_ALLOC_SCRATCH_END(hybridRealLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS);
   1388 
   1389 }/* END ApplyPsSlot */
   1390 
   1391 
   1392 /***************************************************************************/
   1393 /*!
   1394 
   1395   \brief  assigns timeslots to an array
   1396 
   1397   \return
   1398 
   1399 ****************************************************************************/
   1400 
   1401 static void assignTimeSlotsPS (FIXP_DBL *bufAdr,
   1402                                FIXP_DBL **bufPtr,
   1403                                const int numSlots,
   1404                                const int numChan)
   1405 {
   1406   FIXP_DBL  *ptr;
   1407   int slot;
   1408   ptr = bufAdr;
   1409   for(slot=0; slot < numSlots; slot++) {
   1410    bufPtr [slot] = ptr;
   1411     ptr += numChan;
   1412   }
   1413 }
   1414 
   1415