• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  
2  /* -----------------------------------------------------------------------------------------------------------
3  Software License for The Fraunhofer FDK AAC Codec Library for Android
4  
5  � Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung 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@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
CreatePsDec(HANDLE_PS_DEC * h_PS_DEC,int aacSamplesPerFrame)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
DeletePsDec(HANDLE_PS_DEC * h_PS_DEC)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  ****************************************************************************/
ResetPsDec(HANDLE_PS_DEC h_ps_d)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  ****************************************************************************/
ResetPsDeCor(HANDLE_PS_DEC h_ps_d)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
getScaleFactorPsStatesBuffer(HANDLE_PS_DEC h_ps_d)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
scalePsStatesBuffer(HANDLE_PS_DEC h_ps_d,int scale)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  
scalFilterBankValues(HANDLE_PS_DEC h_ps_d,FIXP_DBL ** fixpQmfReal,FIXP_DBL ** fixpQmfImag,int lsb,int scaleFactorLowBandSplitLow,int scaleFactorLowBandSplitHigh,SCHAR * scaleFactorLowBand_lb,SCHAR * scaleFactorLowBand_hb,int scaleFactorHighBands,INT * scaleFactorHighBand,INT noCols)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  
rescalFilterBankValues(HANDLE_PS_DEC h_ps_d,FIXP_DBL ** QmfBufferReal,FIXP_DBL ** QmfBufferImag,int lsb,INT noCols)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
deCorrelateSlotBased(HANDLE_PS_DEC h_ps_d,FIXP_DBL * mHybridRealLeft,FIXP_DBL * mHybridImagLeft,SCHAR sf_mHybridLeft,FIXP_DBL * rIntBufferLeft,FIXP_DBL * iIntBufferLeft,SCHAR sf_IntBuffer,FIXP_DBL * mHybridRealRight,FIXP_DBL * mHybridImagRight,FIXP_DBL * rIntBufferRight,FIXP_DBL * iIntBufferRight)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  
initSlotBasedRotation(HANDLE_PS_DEC h_ps_d,int env,int usb)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  
applySlotBasedRotation(HANDLE_PS_DEC h_ps_d,FIXP_DBL * mHybridRealLeft,FIXP_DBL * mHybridImagLeft,FIXP_DBL * QmfLeftReal,FIXP_DBL * QmfLeftImag,FIXP_DBL * mHybridRealRight,FIXP_DBL * mHybridImagRight,FIXP_DBL * QmfRightReal,FIXP_DBL * QmfRightImag)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
ApplyPsSlot(HANDLE_PS_DEC h_ps_d,FIXP_DBL ** rIntBufferLeft,FIXP_DBL ** iIntBufferLeft,FIXP_DBL * rIntBufferRight,FIXP_DBL * iIntBufferRight)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  
assignTimeSlotsPS(FIXP_DBL * bufAdr,FIXP_DBL ** bufPtr,const int numSlots,const int numChan)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