xref: /aosp_15_r20/external/aac/libSBRdec/src/psdec.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** SBR decoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description:
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker /*!
104*e5436536SAndroid Build Coastguard Worker   \file
105*e5436536SAndroid Build Coastguard Worker   \brief  parametric stereo decoder
106*e5436536SAndroid Build Coastguard Worker */
107*e5436536SAndroid Build Coastguard Worker 
108*e5436536SAndroid Build Coastguard Worker #include "psdec.h"
109*e5436536SAndroid Build Coastguard Worker 
110*e5436536SAndroid Build Coastguard Worker #include "FDK_bitbuffer.h"
111*e5436536SAndroid Build Coastguard Worker 
112*e5436536SAndroid Build Coastguard Worker #include "sbr_rom.h"
113*e5436536SAndroid Build Coastguard Worker #include "sbr_ram.h"
114*e5436536SAndroid Build Coastguard Worker 
115*e5436536SAndroid Build Coastguard Worker #include "FDK_tools_rom.h"
116*e5436536SAndroid Build Coastguard Worker 
117*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
118*e5436536SAndroid Build Coastguard Worker 
119*e5436536SAndroid Build Coastguard Worker #include "FDK_trigFcts.h"
120*e5436536SAndroid Build Coastguard Worker 
121*e5436536SAndroid Build Coastguard Worker /********************************************************************/
122*e5436536SAndroid Build Coastguard Worker /*                       MLQUAL DEFINES                             */
123*e5436536SAndroid Build Coastguard Worker /********************************************************************/
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker #define FRACT_ZERO FRACT_BITS - 1
126*e5436536SAndroid Build Coastguard Worker /********************************************************************/
127*e5436536SAndroid Build Coastguard Worker 
128*e5436536SAndroid Build Coastguard Worker SBR_ERROR ResetPsDec(HANDLE_PS_DEC h_ps_d);
129*e5436536SAndroid Build Coastguard Worker 
130*e5436536SAndroid Build Coastguard Worker /***** HELPERS *****/
131*e5436536SAndroid Build Coastguard Worker 
132*e5436536SAndroid Build Coastguard Worker /***************************************************************************/
133*e5436536SAndroid Build Coastguard Worker /*!
134*e5436536SAndroid Build Coastguard Worker   \brief  Creates one instance of the PS_DEC struct
135*e5436536SAndroid Build Coastguard Worker 
136*e5436536SAndroid Build Coastguard Worker   \return Error info
137*e5436536SAndroid Build Coastguard Worker 
138*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
CreatePsDec(HANDLE_PS_DEC * h_PS_DEC,int aacSamplesPerFrame)139*e5436536SAndroid Build Coastguard Worker int CreatePsDec(HANDLE_PS_DEC *h_PS_DEC, /*!< pointer to the module state */
140*e5436536SAndroid Build Coastguard Worker                 int aacSamplesPerFrame) {
141*e5436536SAndroid Build Coastguard Worker   SBR_ERROR errorInfo = SBRDEC_OK;
142*e5436536SAndroid Build Coastguard Worker   HANDLE_PS_DEC h_ps_d;
143*e5436536SAndroid Build Coastguard Worker   int i;
144*e5436536SAndroid Build Coastguard Worker 
145*e5436536SAndroid Build Coastguard Worker   if (*h_PS_DEC == NULL) {
146*e5436536SAndroid Build Coastguard Worker     /* Get ps dec ram */
147*e5436536SAndroid Build Coastguard Worker     h_ps_d = GetRam_ps_dec();
148*e5436536SAndroid Build Coastguard Worker     if (h_ps_d == NULL) {
149*e5436536SAndroid Build Coastguard Worker       goto bail;
150*e5436536SAndroid Build Coastguard Worker     }
151*e5436536SAndroid Build Coastguard Worker   } else {
152*e5436536SAndroid Build Coastguard Worker     /* Reset an open instance */
153*e5436536SAndroid Build Coastguard Worker     h_ps_d = *h_PS_DEC;
154*e5436536SAndroid Build Coastguard Worker   }
155*e5436536SAndroid Build Coastguard Worker 
156*e5436536SAndroid Build Coastguard Worker   /*
157*e5436536SAndroid Build Coastguard Worker    * Create Analysis Hybrid filterbank.
158*e5436536SAndroid Build Coastguard Worker    */
159*e5436536SAndroid Build Coastguard Worker   FDKhybridAnalysisOpen(&h_ps_d->specificTo.mpeg.hybridAnalysis,
160*e5436536SAndroid Build Coastguard Worker                         h_ps_d->specificTo.mpeg.pHybridAnaStatesLFdmx,
161*e5436536SAndroid Build Coastguard Worker                         sizeof(h_ps_d->specificTo.mpeg.pHybridAnaStatesLFdmx),
162*e5436536SAndroid Build Coastguard Worker                         NULL, 0);
163*e5436536SAndroid Build Coastguard Worker 
164*e5436536SAndroid Build Coastguard Worker   /* initialisation */
165*e5436536SAndroid Build Coastguard Worker   switch (aacSamplesPerFrame) {
166*e5436536SAndroid Build Coastguard Worker     case 960:
167*e5436536SAndroid Build Coastguard Worker       h_ps_d->noSubSamples = 30; /* col */
168*e5436536SAndroid Build Coastguard Worker       break;
169*e5436536SAndroid Build Coastguard Worker     case 1024:
170*e5436536SAndroid Build Coastguard Worker       h_ps_d->noSubSamples = 32; /* col */
171*e5436536SAndroid Build Coastguard Worker       break;
172*e5436536SAndroid Build Coastguard Worker     default:
173*e5436536SAndroid Build Coastguard Worker       h_ps_d->noSubSamples = -1;
174*e5436536SAndroid Build Coastguard Worker       break;
175*e5436536SAndroid Build Coastguard Worker   }
176*e5436536SAndroid Build Coastguard Worker 
177*e5436536SAndroid Build Coastguard Worker   if (h_ps_d->noSubSamples > MAX_NUM_COL || h_ps_d->noSubSamples <= 0) {
178*e5436536SAndroid Build Coastguard Worker     goto bail;
179*e5436536SAndroid Build Coastguard Worker   }
180*e5436536SAndroid Build Coastguard Worker   h_ps_d->noChannels = NO_QMF_CHANNELS; /* row */
181*e5436536SAndroid Build Coastguard Worker 
182*e5436536SAndroid Build Coastguard Worker   h_ps_d->psDecodedPrv = 0;
183*e5436536SAndroid Build Coastguard Worker   h_ps_d->procFrameBased = -1;
184*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < (1) + 1; i++) {
185*e5436536SAndroid Build Coastguard Worker     h_ps_d->bPsDataAvail[i] = ppt_none;
186*e5436536SAndroid Build Coastguard Worker   }
187*e5436536SAndroid Build Coastguard Worker   {
188*e5436536SAndroid Build Coastguard Worker     int error;
189*e5436536SAndroid Build Coastguard Worker     error = FDKdecorrelateOpen(&(h_ps_d->specificTo.mpeg.apDecor),
190*e5436536SAndroid Build Coastguard Worker                                h_ps_d->specificTo.mpeg.decorrBufferCplx,
191*e5436536SAndroid Build Coastguard Worker                                (2 * ((825) + (373))));
192*e5436536SAndroid Build Coastguard Worker     if (error) goto bail;
193*e5436536SAndroid Build Coastguard Worker   }
194*e5436536SAndroid Build Coastguard Worker 
195*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < (1) + 1; i++) {
196*e5436536SAndroid Build Coastguard Worker     FDKmemclear(&h_ps_d->bsData[i].mpeg, sizeof(MPEG_PS_BS_DATA));
197*e5436536SAndroid Build Coastguard Worker   }
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker   errorInfo = ResetPsDec(h_ps_d);
200*e5436536SAndroid Build Coastguard Worker 
201*e5436536SAndroid Build Coastguard Worker   if (errorInfo != SBRDEC_OK) goto bail;
202*e5436536SAndroid Build Coastguard Worker 
203*e5436536SAndroid Build Coastguard Worker   *h_PS_DEC = h_ps_d;
204*e5436536SAndroid Build Coastguard Worker 
205*e5436536SAndroid Build Coastguard Worker   return 0;
206*e5436536SAndroid Build Coastguard Worker 
207*e5436536SAndroid Build Coastguard Worker bail:
208*e5436536SAndroid Build Coastguard Worker   if (h_ps_d != NULL) {
209*e5436536SAndroid Build Coastguard Worker     DeletePsDec(&h_ps_d);
210*e5436536SAndroid Build Coastguard Worker   }
211*e5436536SAndroid Build Coastguard Worker 
212*e5436536SAndroid Build Coastguard Worker   return -1;
213*e5436536SAndroid Build Coastguard Worker } /*END CreatePsDec */
214*e5436536SAndroid Build Coastguard Worker 
215*e5436536SAndroid Build Coastguard Worker /***************************************************************************/
216*e5436536SAndroid Build Coastguard Worker /*!
217*e5436536SAndroid Build Coastguard Worker   \brief  Delete one instance of the PS_DEC struct
218*e5436536SAndroid Build Coastguard Worker 
219*e5436536SAndroid Build Coastguard Worker   \return Error info
220*e5436536SAndroid Build Coastguard Worker 
221*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
DeletePsDec(HANDLE_PS_DEC * h_PS_DEC)222*e5436536SAndroid Build Coastguard Worker int DeletePsDec(HANDLE_PS_DEC *h_PS_DEC) /*!< pointer to the module state */
223*e5436536SAndroid Build Coastguard Worker {
224*e5436536SAndroid Build Coastguard Worker   if (*h_PS_DEC == NULL) {
225*e5436536SAndroid Build Coastguard Worker     return -1;
226*e5436536SAndroid Build Coastguard Worker   }
227*e5436536SAndroid Build Coastguard Worker 
228*e5436536SAndroid Build Coastguard Worker   {
229*e5436536SAndroid Build Coastguard Worker     HANDLE_PS_DEC h_ps_d = *h_PS_DEC;
230*e5436536SAndroid Build Coastguard Worker     FDKdecorrelateClose(&(h_ps_d->specificTo.mpeg.apDecor));
231*e5436536SAndroid Build Coastguard Worker   }
232*e5436536SAndroid Build Coastguard Worker 
233*e5436536SAndroid Build Coastguard Worker   FreeRam_ps_dec(h_PS_DEC);
234*e5436536SAndroid Build Coastguard Worker 
235*e5436536SAndroid Build Coastguard Worker   return 0;
236*e5436536SAndroid Build Coastguard Worker } /*END DeletePsDec */
237*e5436536SAndroid Build Coastguard Worker 
238*e5436536SAndroid Build Coastguard Worker /***************************************************************************/
239*e5436536SAndroid Build Coastguard Worker /*!
240*e5436536SAndroid Build Coastguard Worker   \brief resets some values of the PS handle to default states
241*e5436536SAndroid Build Coastguard Worker 
242*e5436536SAndroid Build Coastguard Worker   \return
243*e5436536SAndroid Build Coastguard Worker 
244*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
ResetPsDec(HANDLE_PS_DEC h_ps_d)245*e5436536SAndroid Build Coastguard Worker SBR_ERROR ResetPsDec(HANDLE_PS_DEC h_ps_d) /*!< pointer to the module state */
246*e5436536SAndroid Build Coastguard Worker {
247*e5436536SAndroid Build Coastguard Worker   SBR_ERROR errorInfo = SBRDEC_OK;
248*e5436536SAndroid Build Coastguard Worker   INT i;
249*e5436536SAndroid Build Coastguard Worker 
250*e5436536SAndroid Build Coastguard Worker   /* explicitly init state variables to safe values (until first ps header
251*e5436536SAndroid Build Coastguard Worker    * arrives) */
252*e5436536SAndroid Build Coastguard Worker 
253*e5436536SAndroid Build Coastguard Worker   h_ps_d->specificTo.mpeg.lastUsb = 0;
254*e5436536SAndroid Build Coastguard Worker 
255*e5436536SAndroid Build Coastguard Worker   /*
256*e5436536SAndroid Build Coastguard Worker    * Initialize Analysis Hybrid filterbank.
257*e5436536SAndroid Build Coastguard Worker    */
258*e5436536SAndroid Build Coastguard Worker   FDKhybridAnalysisInit(&h_ps_d->specificTo.mpeg.hybridAnalysis, THREE_TO_TEN,
259*e5436536SAndroid Build Coastguard Worker                         NO_QMF_BANDS_HYBRID20, NO_QMF_BANDS_HYBRID20, 1);
260*e5436536SAndroid Build Coastguard Worker 
261*e5436536SAndroid Build Coastguard Worker   /*
262*e5436536SAndroid Build Coastguard Worker    * Initialize Synthesis Hybrid filterbank.
263*e5436536SAndroid Build Coastguard Worker    */
264*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < 2; i++) {
265*e5436536SAndroid Build Coastguard Worker     FDKhybridSynthesisInit(&h_ps_d->specificTo.mpeg.hybridSynthesis[i],
266*e5436536SAndroid Build Coastguard Worker                            THREE_TO_TEN, NO_QMF_CHANNELS, NO_QMF_CHANNELS);
267*e5436536SAndroid Build Coastguard Worker   }
268*e5436536SAndroid Build Coastguard Worker   {
269*e5436536SAndroid Build Coastguard Worker     INT error;
270*e5436536SAndroid Build Coastguard Worker     error = FDKdecorrelateInit(&h_ps_d->specificTo.mpeg.apDecor, 71, DECORR_PS,
271*e5436536SAndroid Build Coastguard Worker                                DUCKER_AUTOMATIC, 0, 0, 0, 0, 1, /* isLegacyPS */
272*e5436536SAndroid Build Coastguard Worker                                1);
273*e5436536SAndroid Build Coastguard Worker     if (error) return SBRDEC_NOT_INITIALIZED;
274*e5436536SAndroid Build Coastguard Worker   }
275*e5436536SAndroid Build Coastguard Worker 
276*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < NO_IID_GROUPS; i++) {
277*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.h11rPrev[i] = FL2FXCONST_DBL(0.5f);
278*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.h12rPrev[i] = FL2FXCONST_DBL(0.5f);
279*e5436536SAndroid Build Coastguard Worker   }
280*e5436536SAndroid Build Coastguard Worker 
281*e5436536SAndroid Build Coastguard Worker   FDKmemclear(h_ps_d->specificTo.mpeg.h21rPrev,
282*e5436536SAndroid Build Coastguard Worker               sizeof(h_ps_d->specificTo.mpeg.h21rPrev));
283*e5436536SAndroid Build Coastguard Worker   FDKmemclear(h_ps_d->specificTo.mpeg.h22rPrev,
284*e5436536SAndroid Build Coastguard Worker               sizeof(h_ps_d->specificTo.mpeg.h22rPrev));
285*e5436536SAndroid Build Coastguard Worker 
286*e5436536SAndroid Build Coastguard Worker   return errorInfo;
287*e5436536SAndroid Build Coastguard Worker }
288*e5436536SAndroid Build Coastguard Worker 
289*e5436536SAndroid Build Coastguard Worker /***************************************************************************/
290*e5436536SAndroid Build Coastguard Worker /*!
291*e5436536SAndroid Build Coastguard Worker   \brief  Feed delaylines when parametric stereo is switched on.
292*e5436536SAndroid Build Coastguard Worker   \return
293*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
PreparePsProcessing(HANDLE_PS_DEC h_ps_d,const FIXP_DBL * const * const rIntBufferLeft,const FIXP_DBL * const * const iIntBufferLeft,const int scaleFactorLowBand)294*e5436536SAndroid Build Coastguard Worker void PreparePsProcessing(HANDLE_PS_DEC h_ps_d,
295*e5436536SAndroid Build Coastguard Worker                          const FIXP_DBL *const *const rIntBufferLeft,
296*e5436536SAndroid Build Coastguard Worker                          const FIXP_DBL *const *const iIntBufferLeft,
297*e5436536SAndroid Build Coastguard Worker                          const int scaleFactorLowBand) {
298*e5436536SAndroid Build Coastguard Worker   if (h_ps_d->procFrameBased ==
299*e5436536SAndroid Build Coastguard Worker       1) /* If we have switched from frame to slot based processing  */
300*e5436536SAndroid Build Coastguard Worker   {      /* fill hybrid delay buffer.                                */
301*e5436536SAndroid Build Coastguard Worker     int i, j;
302*e5436536SAndroid Build Coastguard Worker 
303*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < HYBRID_FILTER_DELAY; i++) {
304*e5436536SAndroid Build Coastguard Worker       FIXP_DBL qmfInputData[2][NO_QMF_BANDS_HYBRID20];
305*e5436536SAndroid Build Coastguard Worker       FIXP_DBL hybridOutputData[2][NO_SUB_QMF_CHANNELS];
306*e5436536SAndroid Build Coastguard Worker 
307*e5436536SAndroid Build Coastguard Worker       for (j = 0; j < NO_QMF_BANDS_HYBRID20; j++) {
308*e5436536SAndroid Build Coastguard Worker         qmfInputData[0][j] =
309*e5436536SAndroid Build Coastguard Worker             scaleValue(rIntBufferLeft[i][j], scaleFactorLowBand);
310*e5436536SAndroid Build Coastguard Worker         qmfInputData[1][j] =
311*e5436536SAndroid Build Coastguard Worker             scaleValue(iIntBufferLeft[i][j], scaleFactorLowBand);
312*e5436536SAndroid Build Coastguard Worker       }
313*e5436536SAndroid Build Coastguard Worker 
314*e5436536SAndroid Build Coastguard Worker       FDKhybridAnalysisApply(&h_ps_d->specificTo.mpeg.hybridAnalysis,
315*e5436536SAndroid Build Coastguard Worker                              qmfInputData[0], qmfInputData[1],
316*e5436536SAndroid Build Coastguard Worker                              hybridOutputData[0], hybridOutputData[1]);
317*e5436536SAndroid Build Coastguard Worker     }
318*e5436536SAndroid Build Coastguard Worker     h_ps_d->procFrameBased = 0; /* switch to slot based processing. */
319*e5436536SAndroid Build Coastguard Worker 
320*e5436536SAndroid Build Coastguard Worker   } /* procFrameBased==1 */
321*e5436536SAndroid Build Coastguard Worker }
322*e5436536SAndroid Build Coastguard Worker 
initSlotBasedRotation(HANDLE_PS_DEC h_ps_d,int env,int usb)323*e5436536SAndroid Build Coastguard Worker void initSlotBasedRotation(
324*e5436536SAndroid Build Coastguard Worker     HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */
325*e5436536SAndroid Build Coastguard Worker     int env, int usb) {
326*e5436536SAndroid Build Coastguard Worker   INT group = 0;
327*e5436536SAndroid Build Coastguard Worker   INT bin = 0;
328*e5436536SAndroid Build Coastguard Worker   INT noIidSteps;
329*e5436536SAndroid Build Coastguard Worker 
330*e5436536SAndroid Build Coastguard Worker   FIXP_SGL invL;
331*e5436536SAndroid Build Coastguard Worker   FIXP_DBL ScaleL, ScaleR;
332*e5436536SAndroid Build Coastguard Worker   FIXP_DBL Alpha, Beta;
333*e5436536SAndroid Build Coastguard Worker   FIXP_DBL h11r, h12r, h21r, h22r;
334*e5436536SAndroid Build Coastguard Worker 
335*e5436536SAndroid Build Coastguard Worker   const FIXP_DBL *PScaleFactors;
336*e5436536SAndroid Build Coastguard Worker 
337*e5436536SAndroid Build Coastguard Worker   if (h_ps_d->bsData[h_ps_d->processSlot].mpeg.bFineIidQ) {
338*e5436536SAndroid Build Coastguard Worker     PScaleFactors = ScaleFactorsFine; /* values are shiftet right by one */
339*e5436536SAndroid Build Coastguard Worker     noIidSteps = NO_IID_STEPS_FINE;
340*e5436536SAndroid Build Coastguard Worker   } else {
341*e5436536SAndroid Build Coastguard Worker     PScaleFactors = ScaleFactors; /* values are shiftet right by one */
342*e5436536SAndroid Build Coastguard Worker     noIidSteps = NO_IID_STEPS;
343*e5436536SAndroid Build Coastguard Worker   }
344*e5436536SAndroid Build Coastguard Worker 
345*e5436536SAndroid Build Coastguard Worker   /* dequantize and decode */
346*e5436536SAndroid Build Coastguard Worker   for (group = 0; group < NO_IID_GROUPS; group++) {
347*e5436536SAndroid Build Coastguard Worker     bin = bins2groupMap20[group];
348*e5436536SAndroid Build Coastguard Worker 
349*e5436536SAndroid Build Coastguard Worker     /*!
350*e5436536SAndroid Build Coastguard Worker     <h3> type 'A' rotation </h3>
351*e5436536SAndroid Build Coastguard Worker     mixing procedure R_a, used in baseline version<br>
352*e5436536SAndroid Build Coastguard Worker 
353*e5436536SAndroid Build Coastguard Worker      Scale-factor vectors c1 and c2 are precalculated in initPsTables () and
354*e5436536SAndroid Build Coastguard Worker     stored in scaleFactors[] and scaleFactorsFine[] = pScaleFactors []. From the
355*e5436536SAndroid Build Coastguard Worker     linearized IID parameters (intensity differences), two scale factors are
356*e5436536SAndroid Build Coastguard Worker      calculated. They are used to obtain the coefficients h11... h22.
357*e5436536SAndroid Build Coastguard Worker     */
358*e5436536SAndroid Build Coastguard Worker 
359*e5436536SAndroid Build Coastguard Worker     /* ScaleR and ScaleL are scaled by 1 shift right */
360*e5436536SAndroid Build Coastguard Worker 
361*e5436536SAndroid Build Coastguard Worker     ScaleR = PScaleFactors[noIidSteps + h_ps_d->specificTo.mpeg.pCoef
362*e5436536SAndroid Build Coastguard Worker                                             ->aaIidIndexMapped[env][bin]];
363*e5436536SAndroid Build Coastguard Worker     ScaleL = PScaleFactors[noIidSteps - h_ps_d->specificTo.mpeg.pCoef
364*e5436536SAndroid Build Coastguard Worker                                             ->aaIidIndexMapped[env][bin]];
365*e5436536SAndroid Build Coastguard Worker 
366*e5436536SAndroid Build Coastguard Worker     Beta = fMult(
367*e5436536SAndroid Build Coastguard Worker         fMult(Alphas[h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][bin]],
368*e5436536SAndroid Build Coastguard Worker               (ScaleR - ScaleL)),
369*e5436536SAndroid Build Coastguard Worker         FIXP_SQRT05);
370*e5436536SAndroid Build Coastguard Worker     Alpha =
371*e5436536SAndroid Build Coastguard Worker         Alphas[h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][bin]] >> 1;
372*e5436536SAndroid Build Coastguard Worker 
373*e5436536SAndroid Build Coastguard Worker     /* Alpha and Beta are now both scaled by 2 shifts right */
374*e5436536SAndroid Build Coastguard Worker 
375*e5436536SAndroid Build Coastguard Worker     /* calculate the coefficients h11... h22 from scale-factors and ICC
376*e5436536SAndroid Build Coastguard Worker      * parameters */
377*e5436536SAndroid Build Coastguard Worker 
378*e5436536SAndroid Build Coastguard Worker     /* h values are scaled by 1 shift right */
379*e5436536SAndroid Build Coastguard Worker     {
380*e5436536SAndroid Build Coastguard Worker       FIXP_DBL trigData[4];
381*e5436536SAndroid Build Coastguard Worker 
382*e5436536SAndroid Build Coastguard Worker       inline_fixp_cos_sin(Beta + Alpha, Beta - Alpha, 2, trigData);
383*e5436536SAndroid Build Coastguard Worker       h11r = fMult(ScaleL, trigData[0]);
384*e5436536SAndroid Build Coastguard Worker       h12r = fMult(ScaleR, trigData[2]);
385*e5436536SAndroid Build Coastguard Worker       h21r = fMult(ScaleL, trigData[1]);
386*e5436536SAndroid Build Coastguard Worker       h22r = fMult(ScaleR, trigData[3]);
387*e5436536SAndroid Build Coastguard Worker     }
388*e5436536SAndroid Build Coastguard Worker     /*****************************************************************************************/
389*e5436536SAndroid Build Coastguard Worker     /* Interpolation of the matrices H11... H22: */
390*e5436536SAndroid Build Coastguard Worker     /*                                                                                       */
391*e5436536SAndroid Build Coastguard Worker     /* H11(k,n) = H11(k,n[e]) + (n-n[e]) * (H11(k,n[e+1] - H11(k,n[e])) /
392*e5436536SAndroid Build Coastguard Worker      * (n[e+1] - n[e])    */
393*e5436536SAndroid Build Coastguard Worker     /* ... */
394*e5436536SAndroid Build Coastguard Worker     /*****************************************************************************************/
395*e5436536SAndroid Build Coastguard Worker 
396*e5436536SAndroid Build Coastguard Worker     /* invL = 1/(length of envelope) */
397*e5436536SAndroid Build Coastguard Worker     invL = FX_DBL2FX_SGL(GetInvInt(
398*e5436536SAndroid Build Coastguard Worker         h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env + 1] -
399*e5436536SAndroid Build Coastguard Worker         h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env]));
400*e5436536SAndroid Build Coastguard Worker 
401*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->H11r[group] =
402*e5436536SAndroid Build Coastguard Worker         h_ps_d->specificTo.mpeg.h11rPrev[group];
403*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->H12r[group] =
404*e5436536SAndroid Build Coastguard Worker         h_ps_d->specificTo.mpeg.h12rPrev[group];
405*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->H21r[group] =
406*e5436536SAndroid Build Coastguard Worker         h_ps_d->specificTo.mpeg.h21rPrev[group];
407*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->H22r[group] =
408*e5436536SAndroid Build Coastguard Worker         h_ps_d->specificTo.mpeg.h22rPrev[group];
409*e5436536SAndroid Build Coastguard Worker 
410*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->DeltaH11r[group] =
411*e5436536SAndroid Build Coastguard Worker         fMult(h11r - h_ps_d->specificTo.mpeg.pCoef->H11r[group], invL);
412*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->DeltaH12r[group] =
413*e5436536SAndroid Build Coastguard Worker         fMult(h12r - h_ps_d->specificTo.mpeg.pCoef->H12r[group], invL);
414*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->DeltaH21r[group] =
415*e5436536SAndroid Build Coastguard Worker         fMult(h21r - h_ps_d->specificTo.mpeg.pCoef->H21r[group], invL);
416*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.pCoef->DeltaH22r[group] =
417*e5436536SAndroid Build Coastguard Worker         fMult(h22r - h_ps_d->specificTo.mpeg.pCoef->H22r[group], invL);
418*e5436536SAndroid Build Coastguard Worker 
419*e5436536SAndroid Build Coastguard Worker     /* update prev coefficients for interpolation in next envelope */
420*e5436536SAndroid Build Coastguard Worker 
421*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.h11rPrev[group] = h11r;
422*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.h12rPrev[group] = h12r;
423*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.h21rPrev[group] = h21r;
424*e5436536SAndroid Build Coastguard Worker     h_ps_d->specificTo.mpeg.h22rPrev[group] = h22r;
425*e5436536SAndroid Build Coastguard Worker 
426*e5436536SAndroid Build Coastguard Worker   } /* group loop */
427*e5436536SAndroid Build Coastguard Worker }
428*e5436536SAndroid Build Coastguard Worker 
429*e5436536SAndroid Build Coastguard Worker static const UCHAR groupTable[NO_IID_GROUPS + 1] = {
430*e5436536SAndroid Build Coastguard Worker     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
431*e5436536SAndroid Build Coastguard Worker     12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71};
432*e5436536SAndroid Build Coastguard Worker 
applySlotBasedRotation(HANDLE_PS_DEC h_ps_d,FIXP_DBL * mHybridRealLeft,FIXP_DBL * mHybridImagLeft,FIXP_DBL * mHybridRealRight,FIXP_DBL * mHybridImagRight)433*e5436536SAndroid Build Coastguard Worker static void applySlotBasedRotation(
434*e5436536SAndroid Build Coastguard Worker     HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */
435*e5436536SAndroid Build Coastguard Worker 
436*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *mHybridRealLeft, /*!< hybrid values real left  */
437*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *mHybridImagLeft, /*!< hybrid values imag left  */
438*e5436536SAndroid Build Coastguard Worker 
439*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *mHybridRealRight, /*!< hybrid values real right  */
440*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *mHybridImagRight  /*!< hybrid values imag right  */
441*e5436536SAndroid Build Coastguard Worker ) {
442*e5436536SAndroid Build Coastguard Worker   INT group;
443*e5436536SAndroid Build Coastguard Worker   INT subband;
444*e5436536SAndroid Build Coastguard Worker 
445*e5436536SAndroid Build Coastguard Worker   /**********************************************************************************************/
446*e5436536SAndroid Build Coastguard Worker   /*!
447*e5436536SAndroid Build Coastguard Worker   <h2> Mapping </h2>
448*e5436536SAndroid Build Coastguard Worker 
449*e5436536SAndroid Build Coastguard Worker   The number of stereo bands that is actually used depends on the number of
450*e5436536SAndroid Build Coastguard Worker   availble parameters for IID and ICC: <pre> nr. of IID para.| nr. of ICC para.
451*e5436536SAndroid Build Coastguard Worker   | nr. of Stereo bands
452*e5436536SAndroid Build Coastguard Worker    ----------------|------------------|-------------------
453*e5436536SAndroid Build Coastguard Worker      10,20         |     10,20        |        20
454*e5436536SAndroid Build Coastguard Worker      10,20         |     34           |        34
455*e5436536SAndroid Build Coastguard Worker      34            |     10,20        |        34
456*e5436536SAndroid Build Coastguard Worker      34            |     34           |        34
457*e5436536SAndroid Build Coastguard Worker   </pre>
458*e5436536SAndroid Build Coastguard Worker   In the case the number of parameters for IIS and ICC differs from the number
459*e5436536SAndroid Build Coastguard Worker   of stereo bands, a mapping from the lower number to the higher number of
460*e5436536SAndroid Build Coastguard Worker   parameters is applied. Index mapping of IID and ICC parameters is already done
461*e5436536SAndroid Build Coastguard Worker   in psbitdec.cpp. Further mapping is not needed here in baseline version.
462*e5436536SAndroid Build Coastguard Worker   **********************************************************************************************/
463*e5436536SAndroid Build Coastguard Worker 
464*e5436536SAndroid Build Coastguard Worker   /************************************************************************************************/
465*e5436536SAndroid Build Coastguard Worker   /*!
466*e5436536SAndroid Build Coastguard Worker   <h2> Mixing </h2>
467*e5436536SAndroid Build Coastguard Worker 
468*e5436536SAndroid Build Coastguard Worker   To generate the QMF subband signals for the subband samples n = n[e]+1 ,,,
469*e5436536SAndroid Build Coastguard Worker   n_[e+1] the parameters at position n[e] and n[e+1] are required as well as the
470*e5436536SAndroid Build Coastguard Worker   subband domain signals s_k(n) and d_k(n) for n = n[e]+1... n_[e+1]. n[e]
471*e5436536SAndroid Build Coastguard Worker   represents the start position for envelope e. The border positions n[e] are
472*e5436536SAndroid Build Coastguard Worker   handled in DecodePS().
473*e5436536SAndroid Build Coastguard Worker 
474*e5436536SAndroid Build Coastguard Worker   The stereo sub subband signals are constructed as:
475*e5436536SAndroid Build Coastguard Worker   <pre>
476*e5436536SAndroid Build Coastguard Worker   l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n)
477*e5436536SAndroid Build Coastguard Worker   r_k(n) = H21(k,n) s_k(n) + H22(k,n) d_k(n)
478*e5436536SAndroid Build Coastguard Worker   </pre>
479*e5436536SAndroid Build Coastguard Worker   In order to obtain the matrices H11(k,n)... H22 (k,n), the vectors h11(b)...
480*e5436536SAndroid Build Coastguard Worker   h22(b) need to be calculated first (b: parameter index). Depending on ICC mode
481*e5436536SAndroid Build Coastguard Worker   either mixing procedure R_a or R_b is used for that. For both procedures, the
482*e5436536SAndroid Build Coastguard Worker   parameters for parameter position n[e+1] is used.
483*e5436536SAndroid Build Coastguard Worker   ************************************************************************************************/
484*e5436536SAndroid Build Coastguard Worker 
485*e5436536SAndroid Build Coastguard Worker   /************************************************************************************************/
486*e5436536SAndroid Build Coastguard Worker   /*!
487*e5436536SAndroid Build Coastguard Worker   <h2>Phase parameters </h2>
488*e5436536SAndroid Build Coastguard Worker   With disabled phase parameters (which is the case in baseline version), the
489*e5436536SAndroid Build Coastguard Worker   H-matrices are just calculated by:
490*e5436536SAndroid Build Coastguard Worker 
491*e5436536SAndroid Build Coastguard Worker   <pre>
492*e5436536SAndroid Build Coastguard Worker   H11(k,n[e+1] = h11(b(k))
493*e5436536SAndroid Build Coastguard Worker   (...)
494*e5436536SAndroid Build Coastguard Worker   b(k): parameter index according to mapping table
495*e5436536SAndroid Build Coastguard Worker   </pre>
496*e5436536SAndroid Build Coastguard Worker 
497*e5436536SAndroid Build Coastguard Worker   <h2>Processing of the samples in the sub subbands </h2>
498*e5436536SAndroid Build Coastguard Worker   this loop includes the interpolation of the coefficients Hxx
499*e5436536SAndroid Build Coastguard Worker   ************************************************************************************************/
500*e5436536SAndroid Build Coastguard Worker 
501*e5436536SAndroid Build Coastguard Worker   /******************************************************/
502*e5436536SAndroid Build Coastguard Worker   /* construct stereo sub subband signals according to: */
503*e5436536SAndroid Build Coastguard Worker   /*                                                    */
504*e5436536SAndroid Build Coastguard Worker   /* l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n)         */
505*e5436536SAndroid Build Coastguard Worker   /* r_k(n) = H12(k,n) s_k(n) + H22(k,n) d_k(n)         */
506*e5436536SAndroid Build Coastguard Worker   /******************************************************/
507*e5436536SAndroid Build Coastguard Worker   PS_DEC_COEFFICIENTS *pCoef = h_ps_d->specificTo.mpeg.pCoef;
508*e5436536SAndroid Build Coastguard Worker 
509*e5436536SAndroid Build Coastguard Worker   for (group = 0; group < NO_IID_GROUPS; group++) {
510*e5436536SAndroid Build Coastguard Worker     pCoef->H11r[group] += pCoef->DeltaH11r[group];
511*e5436536SAndroid Build Coastguard Worker     pCoef->H12r[group] += pCoef->DeltaH12r[group];
512*e5436536SAndroid Build Coastguard Worker     pCoef->H21r[group] += pCoef->DeltaH21r[group];
513*e5436536SAndroid Build Coastguard Worker     pCoef->H22r[group] += pCoef->DeltaH22r[group];
514*e5436536SAndroid Build Coastguard Worker 
515*e5436536SAndroid Build Coastguard Worker     const int start = groupTable[group];
516*e5436536SAndroid Build Coastguard Worker     const int stop = groupTable[group + 1];
517*e5436536SAndroid Build Coastguard Worker     for (subband = start; subband < stop; subband++) {
518*e5436536SAndroid Build Coastguard Worker       FIXP_DBL tmpLeft =
519*e5436536SAndroid Build Coastguard Worker           fMultAdd(fMultDiv2(pCoef->H11r[group], mHybridRealLeft[subband]),
520*e5436536SAndroid Build Coastguard Worker                    pCoef->H21r[group], mHybridRealRight[subband]);
521*e5436536SAndroid Build Coastguard Worker       FIXP_DBL tmpRight =
522*e5436536SAndroid Build Coastguard Worker           fMultAdd(fMultDiv2(pCoef->H12r[group], mHybridRealLeft[subband]),
523*e5436536SAndroid Build Coastguard Worker                    pCoef->H22r[group], mHybridRealRight[subband]);
524*e5436536SAndroid Build Coastguard Worker       mHybridRealLeft[subband] = tmpLeft;
525*e5436536SAndroid Build Coastguard Worker       mHybridRealRight[subband] = tmpRight;
526*e5436536SAndroid Build Coastguard Worker 
527*e5436536SAndroid Build Coastguard Worker       tmpLeft =
528*e5436536SAndroid Build Coastguard Worker           fMultAdd(fMultDiv2(pCoef->H11r[group], mHybridImagLeft[subband]),
529*e5436536SAndroid Build Coastguard Worker                    pCoef->H21r[group], mHybridImagRight[subband]);
530*e5436536SAndroid Build Coastguard Worker       tmpRight =
531*e5436536SAndroid Build Coastguard Worker           fMultAdd(fMultDiv2(pCoef->H12r[group], mHybridImagLeft[subband]),
532*e5436536SAndroid Build Coastguard Worker                    pCoef->H22r[group], mHybridImagRight[subband]);
533*e5436536SAndroid Build Coastguard Worker       mHybridImagLeft[subband] = tmpLeft;
534*e5436536SAndroid Build Coastguard Worker       mHybridImagRight[subband] = tmpRight;
535*e5436536SAndroid Build Coastguard Worker     } /* subband */
536*e5436536SAndroid Build Coastguard Worker   }
537*e5436536SAndroid Build Coastguard Worker }
538*e5436536SAndroid Build Coastguard Worker 
539*e5436536SAndroid Build Coastguard Worker /***************************************************************************/
540*e5436536SAndroid Build Coastguard Worker /*!
541*e5436536SAndroid Build Coastguard Worker   \brief  Applies IID, ICC, IPD and OPD parameters to the current frame.
542*e5436536SAndroid Build Coastguard Worker 
543*e5436536SAndroid Build Coastguard Worker   \return none
544*e5436536SAndroid Build Coastguard Worker 
545*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
ApplyPsSlot(HANDLE_PS_DEC h_ps_d,FIXP_DBL ** rIntBufferLeft,FIXP_DBL ** iIntBufferLeft,FIXP_DBL * rIntBufferRight,FIXP_DBL * iIntBufferRight,const int scaleFactorLowBand_no_ov,const int scaleFactorLowBand,const int scaleFactorHighBand,const int lsb,const int usb)546*e5436536SAndroid Build Coastguard Worker void ApplyPsSlot(
547*e5436536SAndroid Build Coastguard Worker     HANDLE_PS_DEC h_ps_d,      /*!< handle PS_DEC*/
548*e5436536SAndroid Build Coastguard Worker     FIXP_DBL **rIntBufferLeft, /*!< real bands left qmf channel (38x64)  */
549*e5436536SAndroid Build Coastguard Worker     FIXP_DBL **iIntBufferLeft, /*!< imag bands left qmf channel (38x64)  */
550*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *rIntBufferRight, /*!< real bands right qmf channel (38x64) */
551*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *iIntBufferRight, /*!< imag bands right qmf channel (38x64) */
552*e5436536SAndroid Build Coastguard Worker     const int scaleFactorLowBand_no_ov, const int scaleFactorLowBand,
553*e5436536SAndroid Build Coastguard Worker     const int scaleFactorHighBand, const int lsb, const int usb) {
554*e5436536SAndroid Build Coastguard Worker /*!
555*e5436536SAndroid Build Coastguard Worker The 64-band QMF representation of the monaural signal generated by the SBR tool
556*e5436536SAndroid Build Coastguard Worker is used as input of the PS tool. After the PS processing, the outputs of the
557*e5436536SAndroid Build Coastguard Worker left and right hybrid synthesis filterbanks are used to generate the stereo
558*e5436536SAndroid Build Coastguard Worker output signal.
559*e5436536SAndroid Build Coastguard Worker 
560*e5436536SAndroid Build Coastguard Worker <pre>
561*e5436536SAndroid Build Coastguard Worker 
562*e5436536SAndroid Build Coastguard Worker            -------------            ----------            -------------
563*e5436536SAndroid Build Coastguard Worker           | Hybrid      | M_n[k,m] |          | L_n[k,m] | Hybrid      | l[n]
564*e5436536SAndroid Build Coastguard Worker  m[n] --->| analysis    |--------->|          |--------->| synthesis   |----->
565*e5436536SAndroid Build Coastguard Worker            -------------           | Stereo   |           -------------
566*e5436536SAndroid Build Coastguard Worker                  |                 | recon-   |
567*e5436536SAndroid Build Coastguard Worker                  |                 | stuction |
568*e5436536SAndroid Build Coastguard Worker                 \|/                |          |
569*e5436536SAndroid Build Coastguard Worker            -------------           |          |
570*e5436536SAndroid Build Coastguard Worker           | De-         | D_n[k,m] |          |
571*e5436536SAndroid Build Coastguard Worker           | correlation |--------->|          |
572*e5436536SAndroid Build Coastguard Worker            -------------           |          |           -------------
573*e5436536SAndroid Build Coastguard Worker                                    |          | R_n[k,m] | Hybrid      | r[n]
574*e5436536SAndroid Build Coastguard Worker                                    |          |--------->| synthesis   |----->
575*e5436536SAndroid Build Coastguard Worker  IID, ICC ------------------------>|          |          | filter bank |
576*e5436536SAndroid Build Coastguard Worker (IPD, OPD)                          ----------            -------------
577*e5436536SAndroid Build Coastguard Worker 
578*e5436536SAndroid Build Coastguard Worker m[n]:      QMF represantation of the mono input
579*e5436536SAndroid Build Coastguard Worker M_n[k,m]:  (sub-)sub-band domain signals of the mono input
580*e5436536SAndroid Build Coastguard Worker D_n[k,m]:  decorrelated (sub-)sub-band domain signals
581*e5436536SAndroid Build Coastguard Worker L_n[k,m]:  (sub-)sub-band domain signals of the left output
582*e5436536SAndroid Build Coastguard Worker R_n[k,m]:  (sub-)sub-band domain signals of the right output
583*e5436536SAndroid Build Coastguard Worker l[n],r[n]: left/right output signals
584*e5436536SAndroid Build Coastguard Worker 
585*e5436536SAndroid Build Coastguard Worker </pre>
586*e5436536SAndroid Build Coastguard Worker */
587*e5436536SAndroid Build Coastguard Worker #define NO_HYBRID_DATA_BANDS (71)
588*e5436536SAndroid Build Coastguard Worker 
589*e5436536SAndroid Build Coastguard Worker   int i;
590*e5436536SAndroid Build Coastguard Worker   FIXP_DBL qmfInputData[2][NO_QMF_BANDS_HYBRID20];
591*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *hybridData[2][2];
592*e5436536SAndroid Build Coastguard Worker   C_ALLOC_SCRATCH_START(pHybridData, FIXP_DBL, 4 * NO_HYBRID_DATA_BANDS);
593*e5436536SAndroid Build Coastguard Worker 
594*e5436536SAndroid Build Coastguard Worker   hybridData[0][0] =
595*e5436536SAndroid Build Coastguard Worker       pHybridData + 0 * NO_HYBRID_DATA_BANDS; /* left real hybrid data */
596*e5436536SAndroid Build Coastguard Worker   hybridData[0][1] =
597*e5436536SAndroid Build Coastguard Worker       pHybridData + 1 * NO_HYBRID_DATA_BANDS; /* left imag hybrid data */
598*e5436536SAndroid Build Coastguard Worker   hybridData[1][0] =
599*e5436536SAndroid Build Coastguard Worker       pHybridData + 2 * NO_HYBRID_DATA_BANDS; /* right real hybrid data */
600*e5436536SAndroid Build Coastguard Worker   hybridData[1][1] =
601*e5436536SAndroid Build Coastguard Worker       pHybridData + 3 * NO_HYBRID_DATA_BANDS; /* right imag hybrid data */
602*e5436536SAndroid Build Coastguard Worker 
603*e5436536SAndroid Build Coastguard Worker   /*!
604*e5436536SAndroid Build Coastguard Worker   Hybrid analysis filterbank:
605*e5436536SAndroid Build Coastguard Worker   The lower 3 (5) of the 64 QMF subbands are further split to provide better
606*e5436536SAndroid Build Coastguard Worker   frequency resolution. for PS processing. For the 10 and 20 stereo bands
607*e5436536SAndroid Build Coastguard Worker   configuration, the QMF band H_0(w) is split up into 8 (sub-) sub-bands and the
608*e5436536SAndroid Build Coastguard Worker   QMF bands H_1(w) and H_2(w) are spit into 2 (sub-) 4th. (See figures 8.20
609*e5436536SAndroid Build Coastguard Worker   and 8.22 of ISO/IEC 14496-3:2001/FDAM 2:2004(E) )
610*e5436536SAndroid Build Coastguard Worker   */
611*e5436536SAndroid Build Coastguard Worker 
612*e5436536SAndroid Build Coastguard Worker   /*
613*e5436536SAndroid Build Coastguard Worker    * Hybrid analysis.
614*e5436536SAndroid Build Coastguard Worker    */
615*e5436536SAndroid Build Coastguard Worker 
616*e5436536SAndroid Build Coastguard Worker   /* Get qmf input data and apply descaling */
617*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < NO_QMF_BANDS_HYBRID20; i++) {
618*e5436536SAndroid Build Coastguard Worker     qmfInputData[0][i] = scaleValue(rIntBufferLeft[HYBRID_FILTER_DELAY][i],
619*e5436536SAndroid Build Coastguard Worker                                     scaleFactorLowBand_no_ov);
620*e5436536SAndroid Build Coastguard Worker     qmfInputData[1][i] = scaleValue(iIntBufferLeft[HYBRID_FILTER_DELAY][i],
621*e5436536SAndroid Build Coastguard Worker                                     scaleFactorLowBand_no_ov);
622*e5436536SAndroid Build Coastguard Worker   }
623*e5436536SAndroid Build Coastguard Worker 
624*e5436536SAndroid Build Coastguard Worker   /* LF - part */
625*e5436536SAndroid Build Coastguard Worker   FDKhybridAnalysisApply(&h_ps_d->specificTo.mpeg.hybridAnalysis,
626*e5436536SAndroid Build Coastguard Worker                          qmfInputData[0], qmfInputData[1], hybridData[0][0],
627*e5436536SAndroid Build Coastguard Worker                          hybridData[0][1]);
628*e5436536SAndroid Build Coastguard Worker 
629*e5436536SAndroid Build Coastguard Worker   /* HF - part */
630*e5436536SAndroid Build Coastguard Worker   /* bands up to lsb */
631*e5436536SAndroid Build Coastguard Worker   scaleValues(&hybridData[0][0][NO_SUB_QMF_CHANNELS - 2],
632*e5436536SAndroid Build Coastguard Worker               &rIntBufferLeft[0][NO_QMF_BANDS_HYBRID20],
633*e5436536SAndroid Build Coastguard Worker               lsb - NO_QMF_BANDS_HYBRID20, scaleFactorLowBand);
634*e5436536SAndroid Build Coastguard Worker   scaleValues(&hybridData[0][1][NO_SUB_QMF_CHANNELS - 2],
635*e5436536SAndroid Build Coastguard Worker               &iIntBufferLeft[0][NO_QMF_BANDS_HYBRID20],
636*e5436536SAndroid Build Coastguard Worker               lsb - NO_QMF_BANDS_HYBRID20, scaleFactorLowBand);
637*e5436536SAndroid Build Coastguard Worker 
638*e5436536SAndroid Build Coastguard Worker   /* bands from lsb to usb */
639*e5436536SAndroid Build Coastguard Worker   scaleValues(&hybridData[0][0][lsb + (NO_SUB_QMF_CHANNELS - 2 -
640*e5436536SAndroid Build Coastguard Worker                                        NO_QMF_BANDS_HYBRID20)],
641*e5436536SAndroid Build Coastguard Worker               &rIntBufferLeft[0][lsb], usb - lsb, scaleFactorHighBand);
642*e5436536SAndroid Build Coastguard Worker   scaleValues(&hybridData[0][1][lsb + (NO_SUB_QMF_CHANNELS - 2 -
643*e5436536SAndroid Build Coastguard Worker                                        NO_QMF_BANDS_HYBRID20)],
644*e5436536SAndroid Build Coastguard Worker               &iIntBufferLeft[0][lsb], usb - lsb, scaleFactorHighBand);
645*e5436536SAndroid Build Coastguard Worker 
646*e5436536SAndroid Build Coastguard Worker   /* bands from usb to NO_SUB_QMF_CHANNELS which should be zero for non-overlap
647*e5436536SAndroid Build Coastguard Worker      slots but can be non-zero for overlap slots */
648*e5436536SAndroid Build Coastguard Worker   FDKmemcpy(
649*e5436536SAndroid Build Coastguard Worker       &hybridData[0][0]
650*e5436536SAndroid Build Coastguard Worker                  [usb + (NO_SUB_QMF_CHANNELS - 2 - NO_QMF_BANDS_HYBRID20)],
651*e5436536SAndroid Build Coastguard Worker       &rIntBufferLeft[0][usb], sizeof(FIXP_DBL) * (NO_QMF_CHANNELS - usb));
652*e5436536SAndroid Build Coastguard Worker   FDKmemcpy(
653*e5436536SAndroid Build Coastguard Worker       &hybridData[0][1]
654*e5436536SAndroid Build Coastguard Worker                  [usb + (NO_SUB_QMF_CHANNELS - 2 - NO_QMF_BANDS_HYBRID20)],
655*e5436536SAndroid Build Coastguard Worker       &iIntBufferLeft[0][usb], sizeof(FIXP_DBL) * (NO_QMF_CHANNELS - usb));
656*e5436536SAndroid Build Coastguard Worker 
657*e5436536SAndroid Build Coastguard Worker   /*!
658*e5436536SAndroid Build Coastguard Worker   Decorrelation:
659*e5436536SAndroid Build Coastguard Worker   By means of all-pass filtering and delaying, the (sub-)sub-band samples s_k(n)
660*e5436536SAndroid Build Coastguard Worker   are converted into de-correlated (sub-)sub-band samples d_k(n).
661*e5436536SAndroid Build Coastguard Worker   - k: frequency in hybrid spectrum
662*e5436536SAndroid Build Coastguard Worker   - n: time index
663*e5436536SAndroid Build Coastguard Worker   */
664*e5436536SAndroid Build Coastguard Worker 
665*e5436536SAndroid Build Coastguard Worker   FDKdecorrelateApply(&h_ps_d->specificTo.mpeg.apDecor,
666*e5436536SAndroid Build Coastguard Worker                       &hybridData[0][0][0], /* left real hybrid data */
667*e5436536SAndroid Build Coastguard Worker                       &hybridData[0][1][0], /* left imag hybrid data */
668*e5436536SAndroid Build Coastguard Worker                       &hybridData[1][0][0], /* right real hybrid data */
669*e5436536SAndroid Build Coastguard Worker                       &hybridData[1][1][0], /* right imag hybrid data */
670*e5436536SAndroid Build Coastguard Worker                       0                     /* startHybBand */
671*e5436536SAndroid Build Coastguard Worker   );
672*e5436536SAndroid Build Coastguard Worker 
673*e5436536SAndroid Build Coastguard Worker   /*!
674*e5436536SAndroid Build Coastguard Worker   Stereo Processing:
675*e5436536SAndroid Build Coastguard Worker   The sets of (sub-)sub-band samples s_k(n) and d_k(n) are processed according
676*e5436536SAndroid Build Coastguard Worker   to the stereo cues which are defined per stereo band.
677*e5436536SAndroid Build Coastguard Worker   */
678*e5436536SAndroid Build Coastguard Worker 
679*e5436536SAndroid Build Coastguard Worker   applySlotBasedRotation(h_ps_d,
680*e5436536SAndroid Build Coastguard Worker                          &hybridData[0][0][0], /* left real hybrid data */
681*e5436536SAndroid Build Coastguard Worker                          &hybridData[0][1][0], /* left imag hybrid data */
682*e5436536SAndroid Build Coastguard Worker                          &hybridData[1][0][0], /* right real hybrid data */
683*e5436536SAndroid Build Coastguard Worker                          &hybridData[1][1][0]  /* right imag hybrid data */
684*e5436536SAndroid Build Coastguard Worker   );
685*e5436536SAndroid Build Coastguard Worker 
686*e5436536SAndroid Build Coastguard Worker   /*!
687*e5436536SAndroid Build Coastguard Worker   Hybrid synthesis filterbank:
688*e5436536SAndroid Build Coastguard Worker   The stereo processed hybrid subband signals l_k(n) and r_k(n) are fed into the
689*e5436536SAndroid Build Coastguard Worker   hybrid synthesis filterbanks which are identical to the 64 complex synthesis
690*e5436536SAndroid Build Coastguard Worker   filterbank of the SBR tool. The input to the filterbank are slots of 64 QMF
691*e5436536SAndroid Build Coastguard Worker   samples. For each slot the filterbank outputs one block of 64 samples of one
692*e5436536SAndroid Build Coastguard Worker   reconstructed stereo channel. The hybrid synthesis filterbank is computed
693*e5436536SAndroid Build Coastguard Worker   seperatly for the left and right channel.
694*e5436536SAndroid Build Coastguard Worker   */
695*e5436536SAndroid Build Coastguard Worker 
696*e5436536SAndroid Build Coastguard Worker   /*
697*e5436536SAndroid Build Coastguard Worker    * Hybrid synthesis.
698*e5436536SAndroid Build Coastguard Worker    */
699*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < 2; i++) {
700*e5436536SAndroid Build Coastguard Worker     FDKhybridSynthesisApply(
701*e5436536SAndroid Build Coastguard Worker         &h_ps_d->specificTo.mpeg.hybridSynthesis[i],
702*e5436536SAndroid Build Coastguard Worker         hybridData[i][0], /* real hybrid data */
703*e5436536SAndroid Build Coastguard Worker         hybridData[i][1], /* imag hybrid data */
704*e5436536SAndroid Build Coastguard Worker         (i == 0) ? rIntBufferLeft[0]
705*e5436536SAndroid Build Coastguard Worker                  : rIntBufferRight, /* output real qmf buffer */
706*e5436536SAndroid Build Coastguard Worker         (i == 0) ? iIntBufferLeft[0]
707*e5436536SAndroid Build Coastguard Worker                  : iIntBufferRight /* output imag qmf buffer */
708*e5436536SAndroid Build Coastguard Worker     );
709*e5436536SAndroid Build Coastguard Worker   }
710*e5436536SAndroid Build Coastguard Worker 
711*e5436536SAndroid Build Coastguard Worker   /* free temporary hybrid qmf values of one timeslot */
712*e5436536SAndroid Build Coastguard Worker   C_ALLOC_SCRATCH_END(pHybridData, FIXP_DBL, 4 * NO_HYBRID_DATA_BANDS);
713*e5436536SAndroid Build Coastguard Worker 
714*e5436536SAndroid Build Coastguard Worker } /* END ApplyPsSlot */
715