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