xref: /aosp_15_r20/external/aac/libSBRdec/src/sbrdec_freq_sca.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 - 2021 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  Frequency scale calculation
106*e5436536SAndroid Build Coastguard Worker */
107*e5436536SAndroid Build Coastguard Worker 
108*e5436536SAndroid Build Coastguard Worker #include "sbrdec_freq_sca.h"
109*e5436536SAndroid Build Coastguard Worker 
110*e5436536SAndroid Build Coastguard Worker #include "transcendent.h"
111*e5436536SAndroid Build Coastguard Worker #include "sbr_rom.h"
112*e5436536SAndroid Build Coastguard Worker #include "env_extr.h"
113*e5436536SAndroid Build Coastguard Worker 
114*e5436536SAndroid Build Coastguard Worker #include "genericStds.h" /* need log() for debug-code only */
115*e5436536SAndroid Build Coastguard Worker 
116*e5436536SAndroid Build Coastguard Worker #define MAX_OCTAVE 29
117*e5436536SAndroid Build Coastguard Worker #define MAX_SECOND_REGION 50
118*e5436536SAndroid Build Coastguard Worker 
119*e5436536SAndroid Build Coastguard Worker static int numberOfBands(FIXP_SGL bpo_div16, int start, int stop, int warpFlag);
120*e5436536SAndroid Build Coastguard Worker static void CalcBands(UCHAR *diff, UCHAR start, UCHAR stop, UCHAR num_bands);
121*e5436536SAndroid Build Coastguard Worker static SBR_ERROR modifyBands(UCHAR max_band, UCHAR *diff, UCHAR length);
122*e5436536SAndroid Build Coastguard Worker static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length,
123*e5436536SAndroid Build Coastguard Worker                    UCHAR *start_adress);
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker /*!
126*e5436536SAndroid Build Coastguard Worker   \brief     Retrieve QMF-band where the SBR range starts
127*e5436536SAndroid Build Coastguard Worker 
128*e5436536SAndroid Build Coastguard Worker   Convert startFreq which was read from the bitstream into a
129*e5436536SAndroid Build Coastguard Worker   QMF-channel number.
130*e5436536SAndroid Build Coastguard Worker 
131*e5436536SAndroid Build Coastguard Worker   \return  Number of start band
132*e5436536SAndroid Build Coastguard Worker */
getStartBand(UINT fs,UCHAR startFreq,UINT headerDataFlags)133*e5436536SAndroid Build Coastguard Worker static UCHAR getStartBand(
134*e5436536SAndroid Build Coastguard Worker     UINT fs,              /*!< Output sampling frequency */
135*e5436536SAndroid Build Coastguard Worker     UCHAR startFreq,      /*!< Index to table of possible start bands */
136*e5436536SAndroid Build Coastguard Worker     UINT headerDataFlags) /*!< Info to SBR mode */
137*e5436536SAndroid Build Coastguard Worker {
138*e5436536SAndroid Build Coastguard Worker   INT band;
139*e5436536SAndroid Build Coastguard Worker   UINT fsMapped = fs;
140*e5436536SAndroid Build Coastguard Worker   SBR_RATE rate = DUAL;
141*e5436536SAndroid Build Coastguard Worker 
142*e5436536SAndroid Build Coastguard Worker   if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
143*e5436536SAndroid Build Coastguard Worker     if (headerDataFlags & SBRDEC_QUAD_RATE) {
144*e5436536SAndroid Build Coastguard Worker       rate = QUAD;
145*e5436536SAndroid Build Coastguard Worker     }
146*e5436536SAndroid Build Coastguard Worker     fsMapped = sbrdec_mapToStdSampleRate(fs, 1);
147*e5436536SAndroid Build Coastguard Worker   }
148*e5436536SAndroid Build Coastguard Worker 
149*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(2 * (rate + 1) <= (4));
150*e5436536SAndroid Build Coastguard Worker 
151*e5436536SAndroid Build Coastguard Worker   switch (fsMapped) {
152*e5436536SAndroid Build Coastguard Worker     case 192000:
153*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_192[startFreq];
154*e5436536SAndroid Build Coastguard Worker       break;
155*e5436536SAndroid Build Coastguard Worker     case 176400:
156*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_176[startFreq];
157*e5436536SAndroid Build Coastguard Worker       break;
158*e5436536SAndroid Build Coastguard Worker     case 128000:
159*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_128[startFreq];
160*e5436536SAndroid Build Coastguard Worker       break;
161*e5436536SAndroid Build Coastguard Worker     case 96000:
162*e5436536SAndroid Build Coastguard Worker     case 88200:
163*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_88[rate][startFreq];
164*e5436536SAndroid Build Coastguard Worker       break;
165*e5436536SAndroid Build Coastguard Worker     case 64000:
166*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_64[rate][startFreq];
167*e5436536SAndroid Build Coastguard Worker       break;
168*e5436536SAndroid Build Coastguard Worker     case 48000:
169*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_48[rate][startFreq];
170*e5436536SAndroid Build Coastguard Worker       break;
171*e5436536SAndroid Build Coastguard Worker     case 44100:
172*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_44[rate][startFreq];
173*e5436536SAndroid Build Coastguard Worker       break;
174*e5436536SAndroid Build Coastguard Worker     case 40000:
175*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_40[rate][startFreq];
176*e5436536SAndroid Build Coastguard Worker       break;
177*e5436536SAndroid Build Coastguard Worker     case 32000:
178*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_32[rate][startFreq];
179*e5436536SAndroid Build Coastguard Worker       break;
180*e5436536SAndroid Build Coastguard Worker     case 24000:
181*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_24[rate][startFreq];
182*e5436536SAndroid Build Coastguard Worker       break;
183*e5436536SAndroid Build Coastguard Worker     case 22050:
184*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_22[rate][startFreq];
185*e5436536SAndroid Build Coastguard Worker       break;
186*e5436536SAndroid Build Coastguard Worker     case 16000:
187*e5436536SAndroid Build Coastguard Worker       band = FDK_sbrDecoder_sbr_start_freq_16[rate][startFreq];
188*e5436536SAndroid Build Coastguard Worker       break;
189*e5436536SAndroid Build Coastguard Worker     default:
190*e5436536SAndroid Build Coastguard Worker       band = 255;
191*e5436536SAndroid Build Coastguard Worker   }
192*e5436536SAndroid Build Coastguard Worker 
193*e5436536SAndroid Build Coastguard Worker   return band;
194*e5436536SAndroid Build Coastguard Worker }
195*e5436536SAndroid Build Coastguard Worker 
196*e5436536SAndroid Build Coastguard Worker /*!
197*e5436536SAndroid Build Coastguard Worker   \brief     Retrieve QMF-band where the SBR range starts
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker   Convert startFreq which was read from the bitstream into a
200*e5436536SAndroid Build Coastguard Worker   QMF-channel number.
201*e5436536SAndroid Build Coastguard Worker 
202*e5436536SAndroid Build Coastguard Worker   \return  Number of start band
203*e5436536SAndroid Build Coastguard Worker */
getStopBand(UINT fs,UCHAR stopFreq,UINT headerDataFlags,UCHAR k0)204*e5436536SAndroid Build Coastguard Worker static UCHAR getStopBand(
205*e5436536SAndroid Build Coastguard Worker     UINT fs,              /*!< Output sampling frequency */
206*e5436536SAndroid Build Coastguard Worker     UCHAR stopFreq,       /*!< Index to table of possible start bands */
207*e5436536SAndroid Build Coastguard Worker     UINT headerDataFlags, /*!< Info to SBR mode */
208*e5436536SAndroid Build Coastguard Worker     UCHAR k0)             /*!< Start freq index */
209*e5436536SAndroid Build Coastguard Worker {
210*e5436536SAndroid Build Coastguard Worker   UCHAR k2;
211*e5436536SAndroid Build Coastguard Worker 
212*e5436536SAndroid Build Coastguard Worker   if (stopFreq < 14) {
213*e5436536SAndroid Build Coastguard Worker     INT stopMin;
214*e5436536SAndroid Build Coastguard Worker     INT num = 2 * (64);
215*e5436536SAndroid Build Coastguard Worker     UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
216*e5436536SAndroid Build Coastguard Worker     UCHAR *diff0 = diff_tot;
217*e5436536SAndroid Build Coastguard Worker     UCHAR *diff1 = diff_tot + MAX_OCTAVE;
218*e5436536SAndroid Build Coastguard Worker 
219*e5436536SAndroid Build Coastguard Worker     if (headerDataFlags & SBRDEC_QUAD_RATE) {
220*e5436536SAndroid Build Coastguard Worker       num >>= 1;
221*e5436536SAndroid Build Coastguard Worker     }
222*e5436536SAndroid Build Coastguard Worker 
223*e5436536SAndroid Build Coastguard Worker     if (fs < 32000) {
224*e5436536SAndroid Build Coastguard Worker       stopMin = (((2 * 6000 * num) / fs) + 1) >> 1;
225*e5436536SAndroid Build Coastguard Worker     } else {
226*e5436536SAndroid Build Coastguard Worker       if (fs < 64000) {
227*e5436536SAndroid Build Coastguard Worker         stopMin = (((2 * 8000 * num) / fs) + 1) >> 1;
228*e5436536SAndroid Build Coastguard Worker       } else {
229*e5436536SAndroid Build Coastguard Worker         stopMin = (((2 * 10000 * num) / fs) + 1) >> 1;
230*e5436536SAndroid Build Coastguard Worker       }
231*e5436536SAndroid Build Coastguard Worker     }
232*e5436536SAndroid Build Coastguard Worker 
233*e5436536SAndroid Build Coastguard Worker     stopMin = fMin(stopMin, 64);
234*e5436536SAndroid Build Coastguard Worker 
235*e5436536SAndroid Build Coastguard Worker     /*
236*e5436536SAndroid Build Coastguard Worker       Choose a stop band between k1 and 64 depending on stopFreq (0..13),
237*e5436536SAndroid Build Coastguard Worker       based on a logarithmic scale.
238*e5436536SAndroid Build Coastguard Worker       The vectors diff0 and diff1 are used temporarily here.
239*e5436536SAndroid Build Coastguard Worker     */
240*e5436536SAndroid Build Coastguard Worker     CalcBands(diff0, stopMin, 64, 13);
241*e5436536SAndroid Build Coastguard Worker     shellsort(diff0, 13);
242*e5436536SAndroid Build Coastguard Worker     cumSum(stopMin, diff0, 13, diff1);
243*e5436536SAndroid Build Coastguard Worker     k2 = diff1[stopFreq];
244*e5436536SAndroid Build Coastguard Worker   } else if (stopFreq == 14)
245*e5436536SAndroid Build Coastguard Worker     k2 = 2 * k0;
246*e5436536SAndroid Build Coastguard Worker   else
247*e5436536SAndroid Build Coastguard Worker     k2 = 3 * k0;
248*e5436536SAndroid Build Coastguard Worker 
249*e5436536SAndroid Build Coastguard Worker   /* Limit to Nyquist */
250*e5436536SAndroid Build Coastguard Worker   if (k2 > (64)) k2 = (64);
251*e5436536SAndroid Build Coastguard Worker 
252*e5436536SAndroid Build Coastguard Worker   /* Range checks */
253*e5436536SAndroid Build Coastguard Worker   /* 1 <= difference <= 48; 1 <= fs <= 96000 */
254*e5436536SAndroid Build Coastguard Worker   {
255*e5436536SAndroid Build Coastguard Worker     UCHAR max_freq_coeffs = (headerDataFlags & SBRDEC_QUAD_RATE)
256*e5436536SAndroid Build Coastguard Worker                                 ? MAX_FREQ_COEFFS_QUAD_RATE
257*e5436536SAndroid Build Coastguard Worker                                 : MAX_FREQ_COEFFS;
258*e5436536SAndroid Build Coastguard Worker     if (((k2 - k0) > max_freq_coeffs) || (k2 <= k0)) {
259*e5436536SAndroid Build Coastguard Worker       return 255;
260*e5436536SAndroid Build Coastguard Worker     }
261*e5436536SAndroid Build Coastguard Worker   }
262*e5436536SAndroid Build Coastguard Worker 
263*e5436536SAndroid Build Coastguard Worker   if (headerDataFlags & SBRDEC_QUAD_RATE) {
264*e5436536SAndroid Build Coastguard Worker     return k2; /* skip other checks: (k2 - k0) must be <=
265*e5436536SAndroid Build Coastguard Worker                   MAX_FREQ_COEFFS_QUAD_RATE for all fs */
266*e5436536SAndroid Build Coastguard Worker   }
267*e5436536SAndroid Build Coastguard Worker   if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) {
268*e5436536SAndroid Build Coastguard Worker     /* 1 <= difference <= 35; 42000 <= fs <= 96000 */
269*e5436536SAndroid Build Coastguard Worker     if ((fs >= 42000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) {
270*e5436536SAndroid Build Coastguard Worker       return 255;
271*e5436536SAndroid Build Coastguard Worker     }
272*e5436536SAndroid Build Coastguard Worker     /* 1 <= difference <= 32; 46009 <= fs <= 96000 */
273*e5436536SAndroid Build Coastguard Worker     if ((fs >= 46009) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) {
274*e5436536SAndroid Build Coastguard Worker       return 255;
275*e5436536SAndroid Build Coastguard Worker     }
276*e5436536SAndroid Build Coastguard Worker   } else {
277*e5436536SAndroid Build Coastguard Worker     /* 1 <= difference <= 35; fs == 44100 */
278*e5436536SAndroid Build Coastguard Worker     if ((fs == 44100) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) {
279*e5436536SAndroid Build Coastguard Worker       return 255;
280*e5436536SAndroid Build Coastguard Worker     }
281*e5436536SAndroid Build Coastguard Worker     /* 1 <= difference <= 32; 48000 <= fs <= 96000 */
282*e5436536SAndroid Build Coastguard Worker     if ((fs >= 48000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) {
283*e5436536SAndroid Build Coastguard Worker       return 255;
284*e5436536SAndroid Build Coastguard Worker     }
285*e5436536SAndroid Build Coastguard Worker   }
286*e5436536SAndroid Build Coastguard Worker 
287*e5436536SAndroid Build Coastguard Worker   return k2;
288*e5436536SAndroid Build Coastguard Worker }
289*e5436536SAndroid Build Coastguard Worker 
290*e5436536SAndroid Build Coastguard Worker /*!
291*e5436536SAndroid Build Coastguard Worker   \brief     Generates master frequency tables
292*e5436536SAndroid Build Coastguard Worker 
293*e5436536SAndroid Build Coastguard Worker   Frequency tables are calculated according to the selected domain
294*e5436536SAndroid Build Coastguard Worker   (linear/logarithmic) and granularity.
295*e5436536SAndroid Build Coastguard Worker   IEC 14496-3 4.6.18.3.2.1
296*e5436536SAndroid Build Coastguard Worker 
297*e5436536SAndroid Build Coastguard Worker   \return  errorCode, 0 if successful
298*e5436536SAndroid Build Coastguard Worker */
299*e5436536SAndroid Build Coastguard Worker SBR_ERROR
sbrdecUpdateFreqScale(UCHAR * v_k_master,UCHAR * numMaster,UINT fs,HANDLE_SBR_HEADER_DATA hHeaderData,UINT flags)300*e5436536SAndroid Build Coastguard Worker sbrdecUpdateFreqScale(
301*e5436536SAndroid Build Coastguard Worker     UCHAR *v_k_master, /*!< Master table to be created */
302*e5436536SAndroid Build Coastguard Worker     UCHAR *numMaster,  /*!< Number of entries in master table */
303*e5436536SAndroid Build Coastguard Worker     UINT fs,           /*!< SBR working sampling rate */
304*e5436536SAndroid Build Coastguard Worker     HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Control data from bitstream */
305*e5436536SAndroid Build Coastguard Worker     UINT flags) {
306*e5436536SAndroid Build Coastguard Worker   FIXP_SGL bpo_div16; /* bands_per_octave divided by 16 */
307*e5436536SAndroid Build Coastguard Worker   INT dk = 0;
308*e5436536SAndroid Build Coastguard Worker 
309*e5436536SAndroid Build Coastguard Worker   /* Internal variables */
310*e5436536SAndroid Build Coastguard Worker   UCHAR k0, k2, i;
311*e5436536SAndroid Build Coastguard Worker   UCHAR num_bands0 = 0;
312*e5436536SAndroid Build Coastguard Worker   UCHAR num_bands1 = 0;
313*e5436536SAndroid Build Coastguard Worker   UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
314*e5436536SAndroid Build Coastguard Worker   UCHAR *diff0 = diff_tot;
315*e5436536SAndroid Build Coastguard Worker   UCHAR *diff1 = diff_tot + MAX_OCTAVE;
316*e5436536SAndroid Build Coastguard Worker   INT k2_achived;
317*e5436536SAndroid Build Coastguard Worker   INT k2_diff;
318*e5436536SAndroid Build Coastguard Worker   INT incr = 0;
319*e5436536SAndroid Build Coastguard Worker 
320*e5436536SAndroid Build Coastguard Worker   /*
321*e5436536SAndroid Build Coastguard Worker     Determine start band
322*e5436536SAndroid Build Coastguard Worker   */
323*e5436536SAndroid Build Coastguard Worker   if (flags & SBRDEC_QUAD_RATE) {
324*e5436536SAndroid Build Coastguard Worker     fs >>= 1;
325*e5436536SAndroid Build Coastguard Worker   }
326*e5436536SAndroid Build Coastguard Worker 
327*e5436536SAndroid Build Coastguard Worker   k0 = getStartBand(fs, hHeaderData->bs_data.startFreq, flags);
328*e5436536SAndroid Build Coastguard Worker   if (k0 == 255) {
329*e5436536SAndroid Build Coastguard Worker     return SBRDEC_UNSUPPORTED_CONFIG;
330*e5436536SAndroid Build Coastguard Worker   }
331*e5436536SAndroid Build Coastguard Worker 
332*e5436536SAndroid Build Coastguard Worker   /*
333*e5436536SAndroid Build Coastguard Worker     Determine stop band
334*e5436536SAndroid Build Coastguard Worker   */
335*e5436536SAndroid Build Coastguard Worker   k2 = getStopBand(fs, hHeaderData->bs_data.stopFreq, flags, k0);
336*e5436536SAndroid Build Coastguard Worker   if (k2 == 255) {
337*e5436536SAndroid Build Coastguard Worker     return SBRDEC_UNSUPPORTED_CONFIG;
338*e5436536SAndroid Build Coastguard Worker   }
339*e5436536SAndroid Build Coastguard Worker 
340*e5436536SAndroid Build Coastguard Worker   if (hHeaderData->bs_data.freqScale > 0) { /* Bark */
341*e5436536SAndroid Build Coastguard Worker     INT k1;
342*e5436536SAndroid Build Coastguard Worker 
343*e5436536SAndroid Build Coastguard Worker     if (hHeaderData->bs_data.freqScale == 1) {
344*e5436536SAndroid Build Coastguard Worker       bpo_div16 = FL2FXCONST_SGL(12.0f / 16.0f);
345*e5436536SAndroid Build Coastguard Worker     } else if (hHeaderData->bs_data.freqScale == 2) {
346*e5436536SAndroid Build Coastguard Worker       bpo_div16 = FL2FXCONST_SGL(10.0f / 16.0f);
347*e5436536SAndroid Build Coastguard Worker     } else {
348*e5436536SAndroid Build Coastguard Worker       bpo_div16 = FL2FXCONST_SGL(8.0f / 16.0f);
349*e5436536SAndroid Build Coastguard Worker     }
350*e5436536SAndroid Build Coastguard Worker 
351*e5436536SAndroid Build Coastguard Worker     /* Ref: ISO/IEC 23003-3, Figure 12 - Flowchart calculation of fMaster for
352*e5436536SAndroid Build Coastguard Worker      * 4:1 system when bs_freq_scale > 0 */
353*e5436536SAndroid Build Coastguard Worker     if (flags & SBRDEC_QUAD_RATE) {
354*e5436536SAndroid Build Coastguard Worker       if ((SHORT)k0 < (SHORT)(bpo_div16 >> ((FRACT_BITS - 1) - 4))) {
355*e5436536SAndroid Build Coastguard Worker         bpo_div16 = (FIXP_SGL)(k0 & (UCHAR)0xfe)
356*e5436536SAndroid Build Coastguard Worker                     << ((FRACT_BITS - 1) - 4); /* bpo_div16 = floor(k0/2)*2 */
357*e5436536SAndroid Build Coastguard Worker       }
358*e5436536SAndroid Build Coastguard Worker     }
359*e5436536SAndroid Build Coastguard Worker 
360*e5436536SAndroid Build Coastguard Worker     if (1000 * k2 > 2245 * k0) { /* Two or more regions */
361*e5436536SAndroid Build Coastguard Worker       k1 = 2 * k0;
362*e5436536SAndroid Build Coastguard Worker 
363*e5436536SAndroid Build Coastguard Worker       num_bands0 = numberOfBands(bpo_div16, k0, k1, 0);
364*e5436536SAndroid Build Coastguard Worker       num_bands1 =
365*e5436536SAndroid Build Coastguard Worker           numberOfBands(bpo_div16, k1, k2, hHeaderData->bs_data.alterScale);
366*e5436536SAndroid Build Coastguard Worker       if (num_bands0 < 1) {
367*e5436536SAndroid Build Coastguard Worker         return SBRDEC_UNSUPPORTED_CONFIG;
368*e5436536SAndroid Build Coastguard Worker       }
369*e5436536SAndroid Build Coastguard Worker       if (num_bands1 < 1) {
370*e5436536SAndroid Build Coastguard Worker         return SBRDEC_UNSUPPORTED_CONFIG;
371*e5436536SAndroid Build Coastguard Worker       }
372*e5436536SAndroid Build Coastguard Worker 
373*e5436536SAndroid Build Coastguard Worker       CalcBands(diff0, k0, k1, num_bands0);
374*e5436536SAndroid Build Coastguard Worker       shellsort(diff0, num_bands0);
375*e5436536SAndroid Build Coastguard Worker       if (diff0[0] == 0) {
376*e5436536SAndroid Build Coastguard Worker         return SBRDEC_UNSUPPORTED_CONFIG;
377*e5436536SAndroid Build Coastguard Worker       }
378*e5436536SAndroid Build Coastguard Worker 
379*e5436536SAndroid Build Coastguard Worker       cumSum(k0, diff0, num_bands0, v_k_master);
380*e5436536SAndroid Build Coastguard Worker 
381*e5436536SAndroid Build Coastguard Worker       CalcBands(diff1, k1, k2, num_bands1);
382*e5436536SAndroid Build Coastguard Worker       shellsort(diff1, num_bands1);
383*e5436536SAndroid Build Coastguard Worker       if (diff0[num_bands0 - 1] > diff1[0]) {
384*e5436536SAndroid Build Coastguard Worker         SBR_ERROR err;
385*e5436536SAndroid Build Coastguard Worker 
386*e5436536SAndroid Build Coastguard Worker         err = modifyBands(diff0[num_bands0 - 1], diff1, num_bands1);
387*e5436536SAndroid Build Coastguard Worker         if (err) return SBRDEC_UNSUPPORTED_CONFIG;
388*e5436536SAndroid Build Coastguard Worker       }
389*e5436536SAndroid Build Coastguard Worker 
390*e5436536SAndroid Build Coastguard Worker       /* Add 2nd region */
391*e5436536SAndroid Build Coastguard Worker       cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]);
392*e5436536SAndroid Build Coastguard Worker       *numMaster = num_bands0 + num_bands1; /* Output nr of bands */
393*e5436536SAndroid Build Coastguard Worker 
394*e5436536SAndroid Build Coastguard Worker     } else { /* Only one region */
395*e5436536SAndroid Build Coastguard Worker       k1 = k2;
396*e5436536SAndroid Build Coastguard Worker 
397*e5436536SAndroid Build Coastguard Worker       num_bands0 = numberOfBands(bpo_div16, k0, k1, 0);
398*e5436536SAndroid Build Coastguard Worker       if (num_bands0 < 1) {
399*e5436536SAndroid Build Coastguard Worker         return SBRDEC_UNSUPPORTED_CONFIG;
400*e5436536SAndroid Build Coastguard Worker       }
401*e5436536SAndroid Build Coastguard Worker       CalcBands(diff0, k0, k1, num_bands0);
402*e5436536SAndroid Build Coastguard Worker       shellsort(diff0, num_bands0);
403*e5436536SAndroid Build Coastguard Worker       if (diff0[0] == 0) {
404*e5436536SAndroid Build Coastguard Worker         return SBRDEC_UNSUPPORTED_CONFIG;
405*e5436536SAndroid Build Coastguard Worker       }
406*e5436536SAndroid Build Coastguard Worker 
407*e5436536SAndroid Build Coastguard Worker       cumSum(k0, diff0, num_bands0, v_k_master);
408*e5436536SAndroid Build Coastguard Worker       *numMaster = num_bands0; /* Output nr of bands */
409*e5436536SAndroid Build Coastguard Worker     }
410*e5436536SAndroid Build Coastguard Worker   } else { /* Linear mode */
411*e5436536SAndroid Build Coastguard Worker     if (hHeaderData->bs_data.alterScale == 0) {
412*e5436536SAndroid Build Coastguard Worker       dk = 1;
413*e5436536SAndroid Build Coastguard Worker       /* FLOOR to get to few number of bands (next lower even number) */
414*e5436536SAndroid Build Coastguard Worker       num_bands0 = (k2 - k0) & 254;
415*e5436536SAndroid Build Coastguard Worker     } else {
416*e5436536SAndroid Build Coastguard Worker       dk = 2;
417*e5436536SAndroid Build Coastguard Worker       num_bands0 = (((k2 - k0) >> 1) + 1) & 254; /* ROUND to the closest fit */
418*e5436536SAndroid Build Coastguard Worker     }
419*e5436536SAndroid Build Coastguard Worker 
420*e5436536SAndroid Build Coastguard Worker     if (num_bands0 < 1) {
421*e5436536SAndroid Build Coastguard Worker       return SBRDEC_UNSUPPORTED_CONFIG;
422*e5436536SAndroid Build Coastguard Worker       /* We must return already here because 'i' can become negative below. */
423*e5436536SAndroid Build Coastguard Worker     }
424*e5436536SAndroid Build Coastguard Worker 
425*e5436536SAndroid Build Coastguard Worker     k2_achived = k0 + num_bands0 * dk;
426*e5436536SAndroid Build Coastguard Worker     k2_diff = k2 - k2_achived;
427*e5436536SAndroid Build Coastguard Worker 
428*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < num_bands0; i++) diff_tot[i] = dk;
429*e5436536SAndroid Build Coastguard Worker 
430*e5436536SAndroid Build Coastguard Worker     /* If linear scale wasn't achieved */
431*e5436536SAndroid Build Coastguard Worker     /* and we got too wide SBR area */
432*e5436536SAndroid Build Coastguard Worker     if (k2_diff < 0) {
433*e5436536SAndroid Build Coastguard Worker       incr = 1;
434*e5436536SAndroid Build Coastguard Worker       i = 0;
435*e5436536SAndroid Build Coastguard Worker     }
436*e5436536SAndroid Build Coastguard Worker 
437*e5436536SAndroid Build Coastguard Worker     /* If linear scale wasn't achieved */
438*e5436536SAndroid Build Coastguard Worker     /* and we got too small SBR area */
439*e5436536SAndroid Build Coastguard Worker     if (k2_diff > 0) {
440*e5436536SAndroid Build Coastguard Worker       incr = -1;
441*e5436536SAndroid Build Coastguard Worker       i = num_bands0 - 1;
442*e5436536SAndroid Build Coastguard Worker     }
443*e5436536SAndroid Build Coastguard Worker 
444*e5436536SAndroid Build Coastguard Worker     /* Adjust diff vector to get sepc. SBR range */
445*e5436536SAndroid Build Coastguard Worker     while (k2_diff != 0) {
446*e5436536SAndroid Build Coastguard Worker       diff_tot[i] = diff_tot[i] - incr;
447*e5436536SAndroid Build Coastguard Worker       i = i + incr;
448*e5436536SAndroid Build Coastguard Worker       k2_diff = k2_diff + incr;
449*e5436536SAndroid Build Coastguard Worker     }
450*e5436536SAndroid Build Coastguard Worker 
451*e5436536SAndroid Build Coastguard Worker     cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */
452*e5436536SAndroid Build Coastguard Worker     *numMaster = num_bands0;                      /* Output nr of bands */
453*e5436536SAndroid Build Coastguard Worker   }
454*e5436536SAndroid Build Coastguard Worker 
455*e5436536SAndroid Build Coastguard Worker   if (*numMaster < 1) {
456*e5436536SAndroid Build Coastguard Worker     return SBRDEC_UNSUPPORTED_CONFIG;
457*e5436536SAndroid Build Coastguard Worker   }
458*e5436536SAndroid Build Coastguard Worker 
459*e5436536SAndroid Build Coastguard Worker   /* Ref: ISO/IEC 23003-3 Cor.3, "In 7.5.5.2, add to the requirements:"*/
460*e5436536SAndroid Build Coastguard Worker   if (flags & SBRDEC_QUAD_RATE) {
461*e5436536SAndroid Build Coastguard Worker     int k;
462*e5436536SAndroid Build Coastguard Worker     for (k = 1; k < *numMaster; k++) {
463*e5436536SAndroid Build Coastguard Worker       if (!(v_k_master[k] - v_k_master[k - 1] <= k0 - 2)) {
464*e5436536SAndroid Build Coastguard Worker         return SBRDEC_UNSUPPORTED_CONFIG;
465*e5436536SAndroid Build Coastguard Worker       }
466*e5436536SAndroid Build Coastguard Worker     }
467*e5436536SAndroid Build Coastguard Worker   }
468*e5436536SAndroid Build Coastguard Worker 
469*e5436536SAndroid Build Coastguard Worker   /*
470*e5436536SAndroid Build Coastguard Worker     Print out the calculated table
471*e5436536SAndroid Build Coastguard Worker   */
472*e5436536SAndroid Build Coastguard Worker 
473*e5436536SAndroid Build Coastguard Worker   return SBRDEC_OK;
474*e5436536SAndroid Build Coastguard Worker }
475*e5436536SAndroid Build Coastguard Worker 
476*e5436536SAndroid Build Coastguard Worker /*!
477*e5436536SAndroid Build Coastguard Worker   \brief     Calculate frequency ratio of one SBR band
478*e5436536SAndroid Build Coastguard Worker 
479*e5436536SAndroid Build Coastguard Worker   All SBR bands should span a constant frequency range in the logarithmic
480*e5436536SAndroid Build Coastguard Worker   domain. This function calculates the ratio of any SBR band's upper and lower
481*e5436536SAndroid Build Coastguard Worker   frequency.
482*e5436536SAndroid Build Coastguard Worker 
483*e5436536SAndroid Build Coastguard Worker  \return    num_band-th root of k_start/k_stop
484*e5436536SAndroid Build Coastguard Worker */
calcFactorPerBand(int k_start,int k_stop,int num_bands)485*e5436536SAndroid Build Coastguard Worker static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) {
486*e5436536SAndroid Build Coastguard Worker   /* Scaled bandfactor and step 1 bit right to avoid overflow
487*e5436536SAndroid Build Coastguard Worker    * use double data type */
488*e5436536SAndroid Build Coastguard Worker   FIXP_DBL bandfactor = FL2FXCONST_DBL(0.25f); /* Start value */
489*e5436536SAndroid Build Coastguard Worker   FIXP_DBL step = FL2FXCONST_DBL(0.125f); /* Initial increment for factor */
490*e5436536SAndroid Build Coastguard Worker 
491*e5436536SAndroid Build Coastguard Worker   int direction = 1;
492*e5436536SAndroid Build Coastguard Worker 
493*e5436536SAndroid Build Coastguard Worker   /* Because saturation can't be done in INT IIS,
494*e5436536SAndroid Build Coastguard Worker    * changed start and stop data type from FIXP_SGL to FIXP_DBL */
495*e5436536SAndroid Build Coastguard Worker   FIXP_DBL start = k_start << (DFRACT_BITS - 8);
496*e5436536SAndroid Build Coastguard Worker   FIXP_DBL stop = k_stop << (DFRACT_BITS - 8);
497*e5436536SAndroid Build Coastguard Worker 
498*e5436536SAndroid Build Coastguard Worker   FIXP_DBL temp;
499*e5436536SAndroid Build Coastguard Worker 
500*e5436536SAndroid Build Coastguard Worker   int j, i = 0;
501*e5436536SAndroid Build Coastguard Worker 
502*e5436536SAndroid Build Coastguard Worker   while (step > FL2FXCONST_DBL(0.0f)) {
503*e5436536SAndroid Build Coastguard Worker     i++;
504*e5436536SAndroid Build Coastguard Worker     temp = stop;
505*e5436536SAndroid Build Coastguard Worker 
506*e5436536SAndroid Build Coastguard Worker     /* Calculate temp^num_bands: */
507*e5436536SAndroid Build Coastguard Worker     for (j = 0; j < num_bands; j++)
508*e5436536SAndroid Build Coastguard Worker       // temp = fMult(temp,bandfactor);
509*e5436536SAndroid Build Coastguard Worker       temp = fMultDiv2(temp, bandfactor) << 2;
510*e5436536SAndroid Build Coastguard Worker 
511*e5436536SAndroid Build Coastguard Worker     if (temp < start) { /* Factor too strong, make it weaker */
512*e5436536SAndroid Build Coastguard Worker       if (direction == 0)
513*e5436536SAndroid Build Coastguard Worker         /* Halfen step. Right shift is not done as fract because otherwise the
514*e5436536SAndroid Build Coastguard Worker            lowest bit cannot be cleared due to rounding */
515*e5436536SAndroid Build Coastguard Worker         step = (FIXP_DBL)((LONG)step >> 1);
516*e5436536SAndroid Build Coastguard Worker       direction = 1;
517*e5436536SAndroid Build Coastguard Worker       bandfactor = bandfactor + step;
518*e5436536SAndroid Build Coastguard Worker     } else { /* Factor is too weak: make it stronger */
519*e5436536SAndroid Build Coastguard Worker       if (direction == 1) step = (FIXP_DBL)((LONG)step >> 1);
520*e5436536SAndroid Build Coastguard Worker       direction = 0;
521*e5436536SAndroid Build Coastguard Worker       bandfactor = bandfactor - step;
522*e5436536SAndroid Build Coastguard Worker     }
523*e5436536SAndroid Build Coastguard Worker 
524*e5436536SAndroid Build Coastguard Worker     if (i > 100) {
525*e5436536SAndroid Build Coastguard Worker       step = FL2FXCONST_DBL(0.0f);
526*e5436536SAndroid Build Coastguard Worker     }
527*e5436536SAndroid Build Coastguard Worker   }
528*e5436536SAndroid Build Coastguard Worker   return (bandfactor >= FL2FXCONST_DBL(0.5)) ? (FIXP_SGL)MAXVAL_SGL
529*e5436536SAndroid Build Coastguard Worker                                              : FX_DBL2FX_SGL(bandfactor << 1);
530*e5436536SAndroid Build Coastguard Worker }
531*e5436536SAndroid Build Coastguard Worker 
532*e5436536SAndroid Build Coastguard Worker /*!
533*e5436536SAndroid Build Coastguard Worker   \brief     Calculate number of SBR bands between start and stop band
534*e5436536SAndroid Build Coastguard Worker 
535*e5436536SAndroid Build Coastguard Worker   Given the number of bands per octave, this function calculates how many
536*e5436536SAndroid Build Coastguard Worker   bands fit in the given frequency range.
537*e5436536SAndroid Build Coastguard Worker   When the warpFlag is set, the 'band density' is decreased by a factor
538*e5436536SAndroid Build Coastguard Worker   of 1/1.3
539*e5436536SAndroid Build Coastguard Worker 
540*e5436536SAndroid Build Coastguard Worker   \return    number of bands
541*e5436536SAndroid Build Coastguard Worker */
numberOfBands(FIXP_SGL bpo_div16,int start,int stop,int warpFlag)542*e5436536SAndroid Build Coastguard Worker static int numberOfBands(
543*e5436536SAndroid Build Coastguard Worker     FIXP_SGL bpo_div16, /*!< Input: number of bands per octave divided by 16 */
544*e5436536SAndroid Build Coastguard Worker     int start,          /*!< First QMF band of SBR frequency range */
545*e5436536SAndroid Build Coastguard Worker     int stop,           /*!< Last QMF band of SBR frequency range + 1 */
546*e5436536SAndroid Build Coastguard Worker     int warpFlag)       /*!< Stretching flag */
547*e5436536SAndroid Build Coastguard Worker {
548*e5436536SAndroid Build Coastguard Worker   FIXP_SGL num_bands_div128;
549*e5436536SAndroid Build Coastguard Worker   int num_bands;
550*e5436536SAndroid Build Coastguard Worker 
551*e5436536SAndroid Build Coastguard Worker   num_bands_div128 =
552*e5436536SAndroid Build Coastguard Worker       FX_DBL2FX_SGL(fMult(FDK_getNumOctavesDiv8(start, stop), bpo_div16));
553*e5436536SAndroid Build Coastguard Worker 
554*e5436536SAndroid Build Coastguard Worker   if (warpFlag) {
555*e5436536SAndroid Build Coastguard Worker     /* Apply the warp factor of 1.3 to get wider bands.  We use a value
556*e5436536SAndroid Build Coastguard Worker        of 32768/25200 instead of the exact value to avoid critical cases
557*e5436536SAndroid Build Coastguard Worker        of rounding.
558*e5436536SAndroid Build Coastguard Worker     */
559*e5436536SAndroid Build Coastguard Worker     num_bands_div128 = FX_DBL2FX_SGL(
560*e5436536SAndroid Build Coastguard Worker         fMult(num_bands_div128, FL2FXCONST_SGL(25200.0 / 32768.0)));
561*e5436536SAndroid Build Coastguard Worker   }
562*e5436536SAndroid Build Coastguard Worker 
563*e5436536SAndroid Build Coastguard Worker   /* add scaled 1 for rounding to even numbers: */
564*e5436536SAndroid Build Coastguard Worker   num_bands_div128 = num_bands_div128 + FL2FXCONST_SGL(1.0f / 128.0f);
565*e5436536SAndroid Build Coastguard Worker   /* scale back to right aligned integer and double the value: */
566*e5436536SAndroid Build Coastguard Worker   num_bands = 2 * ((LONG)num_bands_div128 >> (FRACT_BITS - 7));
567*e5436536SAndroid Build Coastguard Worker 
568*e5436536SAndroid Build Coastguard Worker   return (num_bands);
569*e5436536SAndroid Build Coastguard Worker }
570*e5436536SAndroid Build Coastguard Worker 
571*e5436536SAndroid Build Coastguard Worker /*!
572*e5436536SAndroid Build Coastguard Worker   \brief     Calculate width of SBR bands
573*e5436536SAndroid Build Coastguard Worker 
574*e5436536SAndroid Build Coastguard Worker   Given the desired number of bands within the SBR frequency range,
575*e5436536SAndroid Build Coastguard Worker   this function calculates the width of each SBR band in QMF channels.
576*e5436536SAndroid Build Coastguard Worker   The bands get wider from start to stop (bark scale).
577*e5436536SAndroid Build Coastguard Worker */
CalcBands(UCHAR * diff,UCHAR start,UCHAR stop,UCHAR num_bands)578*e5436536SAndroid Build Coastguard Worker static void CalcBands(UCHAR *diff,     /*!< Vector of widths to be calculated */
579*e5436536SAndroid Build Coastguard Worker                       UCHAR start,     /*!< Lower end of subband range */
580*e5436536SAndroid Build Coastguard Worker                       UCHAR stop,      /*!< Upper end of subband range */
581*e5436536SAndroid Build Coastguard Worker                       UCHAR num_bands) /*!< Desired number of bands */
582*e5436536SAndroid Build Coastguard Worker {
583*e5436536SAndroid Build Coastguard Worker   int i;
584*e5436536SAndroid Build Coastguard Worker   int previous;
585*e5436536SAndroid Build Coastguard Worker   int current;
586*e5436536SAndroid Build Coastguard Worker   FIXP_SGL exact, temp;
587*e5436536SAndroid Build Coastguard Worker   FIXP_SGL bandfactor = calcFactorPerBand(start, stop, num_bands);
588*e5436536SAndroid Build Coastguard Worker 
589*e5436536SAndroid Build Coastguard Worker   previous = stop; /* Start with highest QMF channel */
590*e5436536SAndroid Build Coastguard Worker   exact = (FIXP_SGL)(
591*e5436536SAndroid Build Coastguard Worker       stop << (FRACT_BITS - 8)); /* Shift left to gain some accuracy */
592*e5436536SAndroid Build Coastguard Worker 
593*e5436536SAndroid Build Coastguard Worker   for (i = num_bands - 1; i >= 0; i--) {
594*e5436536SAndroid Build Coastguard Worker     /* Calculate border of next lower sbr band */
595*e5436536SAndroid Build Coastguard Worker     exact = FX_DBL2FX_SGL(fMult(exact, bandfactor));
596*e5436536SAndroid Build Coastguard Worker 
597*e5436536SAndroid Build Coastguard Worker     /* Add scaled 0.5 for rounding:
598*e5436536SAndroid Build Coastguard Worker        We use a value 128/256 instead of 0.5 to avoid some critical cases of
599*e5436536SAndroid Build Coastguard Worker        rounding. */
600*e5436536SAndroid Build Coastguard Worker     temp = exact + FL2FXCONST_SGL(128.0 / 32768.0);
601*e5436536SAndroid Build Coastguard Worker 
602*e5436536SAndroid Build Coastguard Worker     /* scale back to right alinged integer: */
603*e5436536SAndroid Build Coastguard Worker     current = (LONG)temp >> (FRACT_BITS - 8);
604*e5436536SAndroid Build Coastguard Worker 
605*e5436536SAndroid Build Coastguard Worker     /* Save width of band i */
606*e5436536SAndroid Build Coastguard Worker     diff[i] = previous - current;
607*e5436536SAndroid Build Coastguard Worker     previous = current;
608*e5436536SAndroid Build Coastguard Worker   }
609*e5436536SAndroid Build Coastguard Worker }
610*e5436536SAndroid Build Coastguard Worker 
611*e5436536SAndroid Build Coastguard Worker /*!
612*e5436536SAndroid Build Coastguard Worker   \brief     Calculate cumulated sum vector from delta vector
613*e5436536SAndroid Build Coastguard Worker */
cumSum(UCHAR start_value,UCHAR * diff,UCHAR length,UCHAR * start_adress)614*e5436536SAndroid Build Coastguard Worker static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length,
615*e5436536SAndroid Build Coastguard Worker                    UCHAR *start_adress) {
616*e5436536SAndroid Build Coastguard Worker   int i;
617*e5436536SAndroid Build Coastguard Worker   start_adress[0] = start_value;
618*e5436536SAndroid Build Coastguard Worker   for (i = 1; i <= length; i++)
619*e5436536SAndroid Build Coastguard Worker     start_adress[i] = start_adress[i - 1] + diff[i - 1];
620*e5436536SAndroid Build Coastguard Worker }
621*e5436536SAndroid Build Coastguard Worker 
622*e5436536SAndroid Build Coastguard Worker /*!
623*e5436536SAndroid Build Coastguard Worker   \brief     Adapt width of frequency bands in the second region
624*e5436536SAndroid Build Coastguard Worker 
625*e5436536SAndroid Build Coastguard Worker   If SBR spans more than 2 octaves, the upper part of a bark-frequency-scale
626*e5436536SAndroid Build Coastguard Worker   is calculated separately. This function tries to avoid that the second region
627*e5436536SAndroid Build Coastguard Worker   starts with a band smaller than the highest band of the first region.
628*e5436536SAndroid Build Coastguard Worker */
modifyBands(UCHAR max_band_previous,UCHAR * diff,UCHAR length)629*e5436536SAndroid Build Coastguard Worker static SBR_ERROR modifyBands(UCHAR max_band_previous, UCHAR *diff,
630*e5436536SAndroid Build Coastguard Worker                              UCHAR length) {
631*e5436536SAndroid Build Coastguard Worker   int change = max_band_previous - diff[0];
632*e5436536SAndroid Build Coastguard Worker 
633*e5436536SAndroid Build Coastguard Worker   /* Limit the change so that the last band cannot get narrower than the first
634*e5436536SAndroid Build Coastguard Worker    * one */
635*e5436536SAndroid Build Coastguard Worker   if (change > (diff[length - 1] - diff[0]) >> 1)
636*e5436536SAndroid Build Coastguard Worker     change = (diff[length - 1] - diff[0]) >> 1;
637*e5436536SAndroid Build Coastguard Worker 
638*e5436536SAndroid Build Coastguard Worker   diff[0] += change;
639*e5436536SAndroid Build Coastguard Worker   diff[length - 1] -= change;
640*e5436536SAndroid Build Coastguard Worker   shellsort(diff, length);
641*e5436536SAndroid Build Coastguard Worker 
642*e5436536SAndroid Build Coastguard Worker   return SBRDEC_OK;
643*e5436536SAndroid Build Coastguard Worker }
644*e5436536SAndroid Build Coastguard Worker 
645*e5436536SAndroid Build Coastguard Worker /*!
646*e5436536SAndroid Build Coastguard Worker   \brief   Update high resolution frequency band table
647*e5436536SAndroid Build Coastguard Worker */
sbrdecUpdateHiRes(UCHAR * h_hires,UCHAR * num_hires,UCHAR * v_k_master,UCHAR num_bands,UCHAR xover_band)648*e5436536SAndroid Build Coastguard Worker static void sbrdecUpdateHiRes(UCHAR *h_hires, UCHAR *num_hires,
649*e5436536SAndroid Build Coastguard Worker                               UCHAR *v_k_master, UCHAR num_bands,
650*e5436536SAndroid Build Coastguard Worker                               UCHAR xover_band) {
651*e5436536SAndroid Build Coastguard Worker   UCHAR i;
652*e5436536SAndroid Build Coastguard Worker 
653*e5436536SAndroid Build Coastguard Worker   *num_hires = num_bands - xover_band;
654*e5436536SAndroid Build Coastguard Worker 
655*e5436536SAndroid Build Coastguard Worker   for (i = xover_band; i <= num_bands; i++) {
656*e5436536SAndroid Build Coastguard Worker     h_hires[i - xover_band] = v_k_master[i];
657*e5436536SAndroid Build Coastguard Worker   }
658*e5436536SAndroid Build Coastguard Worker }
659*e5436536SAndroid Build Coastguard Worker 
660*e5436536SAndroid Build Coastguard Worker /*!
661*e5436536SAndroid Build Coastguard Worker   \brief  Build low resolution table out of high resolution table
662*e5436536SAndroid Build Coastguard Worker */
sbrdecUpdateLoRes(UCHAR * h_lores,UCHAR * num_lores,UCHAR * h_hires,UCHAR num_hires)663*e5436536SAndroid Build Coastguard Worker static void sbrdecUpdateLoRes(UCHAR *h_lores, UCHAR *num_lores, UCHAR *h_hires,
664*e5436536SAndroid Build Coastguard Worker                               UCHAR num_hires) {
665*e5436536SAndroid Build Coastguard Worker   UCHAR i;
666*e5436536SAndroid Build Coastguard Worker 
667*e5436536SAndroid Build Coastguard Worker   if ((num_hires & 1) == 0) {
668*e5436536SAndroid Build Coastguard Worker     /* If even number of hires bands */
669*e5436536SAndroid Build Coastguard Worker     *num_lores = num_hires >> 1;
670*e5436536SAndroid Build Coastguard Worker     /* Use every second lores=hires[0,2,4...] */
671*e5436536SAndroid Build Coastguard Worker     for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2];
672*e5436536SAndroid Build Coastguard Worker   } else {
673*e5436536SAndroid Build Coastguard Worker     /* Odd number of hires, which means xover is odd */
674*e5436536SAndroid Build Coastguard Worker     *num_lores = (num_hires + 1) >> 1;
675*e5436536SAndroid Build Coastguard Worker     /* Use lores=hires[0,1,3,5 ...] */
676*e5436536SAndroid Build Coastguard Worker     h_lores[0] = h_hires[0];
677*e5436536SAndroid Build Coastguard Worker     for (i = 1; i <= *num_lores; i++) {
678*e5436536SAndroid Build Coastguard Worker       h_lores[i] = h_hires[i * 2 - 1];
679*e5436536SAndroid Build Coastguard Worker     }
680*e5436536SAndroid Build Coastguard Worker   }
681*e5436536SAndroid Build Coastguard Worker }
682*e5436536SAndroid Build Coastguard Worker 
683*e5436536SAndroid Build Coastguard Worker /*!
684*e5436536SAndroid Build Coastguard Worker   \brief   Derive a low-resolution frequency-table from the master frequency
685*e5436536SAndroid Build Coastguard Worker   table
686*e5436536SAndroid Build Coastguard Worker */
sbrdecDownSampleLoRes(UCHAR * v_result,UCHAR num_result,UCHAR * freqBandTableRef,UCHAR num_Ref)687*e5436536SAndroid Build Coastguard Worker void sbrdecDownSampleLoRes(UCHAR *v_result, UCHAR num_result,
688*e5436536SAndroid Build Coastguard Worker                            UCHAR *freqBandTableRef, UCHAR num_Ref) {
689*e5436536SAndroid Build Coastguard Worker   int step;
690*e5436536SAndroid Build Coastguard Worker   int i, j;
691*e5436536SAndroid Build Coastguard Worker   int org_length, result_length;
692*e5436536SAndroid Build Coastguard Worker   int v_index[MAX_FREQ_COEFFS >> 1];
693*e5436536SAndroid Build Coastguard Worker 
694*e5436536SAndroid Build Coastguard Worker   /* init */
695*e5436536SAndroid Build Coastguard Worker   org_length = num_Ref;
696*e5436536SAndroid Build Coastguard Worker   result_length = num_result;
697*e5436536SAndroid Build Coastguard Worker 
698*e5436536SAndroid Build Coastguard Worker   v_index[0] = 0; /* Always use left border */
699*e5436536SAndroid Build Coastguard Worker   i = 0;
700*e5436536SAndroid Build Coastguard Worker   while (org_length > 0) {
701*e5436536SAndroid Build Coastguard Worker     /* Create downsample vector */
702*e5436536SAndroid Build Coastguard Worker     i++;
703*e5436536SAndroid Build Coastguard Worker     step = org_length / result_length;
704*e5436536SAndroid Build Coastguard Worker     org_length = org_length - step;
705*e5436536SAndroid Build Coastguard Worker     result_length--;
706*e5436536SAndroid Build Coastguard Worker     v_index[i] = v_index[i - 1] + step;
707*e5436536SAndroid Build Coastguard Worker   }
708*e5436536SAndroid Build Coastguard Worker 
709*e5436536SAndroid Build Coastguard Worker   for (j = 0; j <= i; j++) {
710*e5436536SAndroid Build Coastguard Worker     /* Use downsample vector to index LoResolution vector */
711*e5436536SAndroid Build Coastguard Worker     v_result[j] = freqBandTableRef[v_index[j]];
712*e5436536SAndroid Build Coastguard Worker   }
713*e5436536SAndroid Build Coastguard Worker }
714*e5436536SAndroid Build Coastguard Worker 
715*e5436536SAndroid Build Coastguard Worker /*!
716*e5436536SAndroid Build Coastguard Worker   \brief   Sorting routine
717*e5436536SAndroid Build Coastguard Worker */
shellsort(UCHAR * in,UCHAR n)718*e5436536SAndroid Build Coastguard Worker void shellsort(UCHAR *in, UCHAR n) {
719*e5436536SAndroid Build Coastguard Worker   int i, j, v, w;
720*e5436536SAndroid Build Coastguard Worker   int inc = 1;
721*e5436536SAndroid Build Coastguard Worker 
722*e5436536SAndroid Build Coastguard Worker   do
723*e5436536SAndroid Build Coastguard Worker     inc = 3 * inc + 1;
724*e5436536SAndroid Build Coastguard Worker   while (inc <= n);
725*e5436536SAndroid Build Coastguard Worker 
726*e5436536SAndroid Build Coastguard Worker   do {
727*e5436536SAndroid Build Coastguard Worker     inc = inc / 3;
728*e5436536SAndroid Build Coastguard Worker     for (i = inc; i < n; i++) {
729*e5436536SAndroid Build Coastguard Worker       v = in[i];
730*e5436536SAndroid Build Coastguard Worker       j = i;
731*e5436536SAndroid Build Coastguard Worker       while ((w = in[j - inc]) > v) {
732*e5436536SAndroid Build Coastguard Worker         in[j] = w;
733*e5436536SAndroid Build Coastguard Worker         j -= inc;
734*e5436536SAndroid Build Coastguard Worker         if (j < inc) break;
735*e5436536SAndroid Build Coastguard Worker       }
736*e5436536SAndroid Build Coastguard Worker       in[j] = v;
737*e5436536SAndroid Build Coastguard Worker     }
738*e5436536SAndroid Build Coastguard Worker   } while (inc > 1);
739*e5436536SAndroid Build Coastguard Worker }
740*e5436536SAndroid Build Coastguard Worker 
741*e5436536SAndroid Build Coastguard Worker /*!
742*e5436536SAndroid Build Coastguard Worker   \brief   Reset frequency band tables
743*e5436536SAndroid Build Coastguard Worker   \return  errorCode, 0 if successful
744*e5436536SAndroid Build Coastguard Worker */
745*e5436536SAndroid Build Coastguard Worker SBR_ERROR
resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData,const UINT flags)746*e5436536SAndroid Build Coastguard Worker resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) {
747*e5436536SAndroid Build Coastguard Worker   SBR_ERROR err = SBRDEC_OK;
748*e5436536SAndroid Build Coastguard Worker   int k2, kx, lsb, usb;
749*e5436536SAndroid Build Coastguard Worker   int intTemp;
750*e5436536SAndroid Build Coastguard Worker   UCHAR nBandsLo, nBandsHi;
751*e5436536SAndroid Build Coastguard Worker   HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
752*e5436536SAndroid Build Coastguard Worker 
753*e5436536SAndroid Build Coastguard Worker   /* Calculate master frequency function */
754*e5436536SAndroid Build Coastguard Worker   err = sbrdecUpdateFreqScale(hFreq->v_k_master, &hFreq->numMaster,
755*e5436536SAndroid Build Coastguard Worker                               hHeaderData->sbrProcSmplRate, hHeaderData, flags);
756*e5436536SAndroid Build Coastguard Worker 
757*e5436536SAndroid Build Coastguard Worker   if (err || (hHeaderData->bs_info.xover_band > hFreq->numMaster)) {
758*e5436536SAndroid Build Coastguard Worker     return SBRDEC_UNSUPPORTED_CONFIG;
759*e5436536SAndroid Build Coastguard Worker   }
760*e5436536SAndroid Build Coastguard Worker 
761*e5436536SAndroid Build Coastguard Worker   /* Derive Hiresolution from master frequency function */
762*e5436536SAndroid Build Coastguard Worker   sbrdecUpdateHiRes(hFreq->freqBandTable[1], &nBandsHi, hFreq->v_k_master,
763*e5436536SAndroid Build Coastguard Worker                     hFreq->numMaster, hHeaderData->bs_info.xover_band);
764*e5436536SAndroid Build Coastguard Worker   /* Derive Loresolution from Hiresolution */
765*e5436536SAndroid Build Coastguard Worker   sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1],
766*e5436536SAndroid Build Coastguard Worker                     nBandsHi);
767*e5436536SAndroid Build Coastguard Worker 
768*e5436536SAndroid Build Coastguard Worker   /* Check index to freqBandTable[0] */
769*e5436536SAndroid Build Coastguard Worker   if (!(nBandsLo > 0) ||
770*e5436536SAndroid Build Coastguard Worker       (nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16)
771*e5436536SAndroid Build Coastguard Worker                         ? MAX_FREQ_COEFFS_QUAD_RATE
772*e5436536SAndroid Build Coastguard Worker                         : MAX_FREQ_COEFFS_DUAL_RATE) >>
773*e5436536SAndroid Build Coastguard Worker                    1))) {
774*e5436536SAndroid Build Coastguard Worker     return SBRDEC_UNSUPPORTED_CONFIG;
775*e5436536SAndroid Build Coastguard Worker   }
776*e5436536SAndroid Build Coastguard Worker 
777*e5436536SAndroid Build Coastguard Worker   hFreq->nSfb[0] = nBandsLo;
778*e5436536SAndroid Build Coastguard Worker   hFreq->nSfb[1] = nBandsHi;
779*e5436536SAndroid Build Coastguard Worker 
780*e5436536SAndroid Build Coastguard Worker   lsb = hFreq->freqBandTable[0][0];
781*e5436536SAndroid Build Coastguard Worker   usb = hFreq->freqBandTable[0][nBandsLo];
782*e5436536SAndroid Build Coastguard Worker 
783*e5436536SAndroid Build Coastguard Worker   /* Check for start frequency border k_x:
784*e5436536SAndroid Build Coastguard Worker      - ISO/IEC 14496-3 4.6.18.3.6 Requirements
785*e5436536SAndroid Build Coastguard Worker      - ISO/IEC 23003-3 7.5.5.2    Modifications and additions to the MPEG-4 SBR
786*e5436536SAndroid Build Coastguard Worker      tool
787*e5436536SAndroid Build Coastguard Worker   */
788*e5436536SAndroid Build Coastguard Worker   /* Note that lsb > as hHeaderData->numberOfAnalysisBands is a valid SBR config
789*e5436536SAndroid Build Coastguard Worker    * for 24 band QMF analysis. */
790*e5436536SAndroid Build Coastguard Worker   if ((lsb > ((flags & SBRDEC_QUAD_RATE) ? 16 : (32))) || (lsb >= usb)) {
791*e5436536SAndroid Build Coastguard Worker     return SBRDEC_UNSUPPORTED_CONFIG;
792*e5436536SAndroid Build Coastguard Worker   }
793*e5436536SAndroid Build Coastguard Worker 
794*e5436536SAndroid Build Coastguard Worker   /* Calculate number of noise bands */
795*e5436536SAndroid Build Coastguard Worker 
796*e5436536SAndroid Build Coastguard Worker   k2 = hFreq->freqBandTable[1][nBandsHi];
797*e5436536SAndroid Build Coastguard Worker   kx = hFreq->freqBandTable[1][0];
798*e5436536SAndroid Build Coastguard Worker 
799*e5436536SAndroid Build Coastguard Worker   if (hHeaderData->bs_data.noise_bands == 0) {
800*e5436536SAndroid Build Coastguard Worker     hFreq->nNfb = 1;
801*e5436536SAndroid Build Coastguard Worker   } else /* Calculate no of noise bands 1,2 or 3 bands/octave */
802*e5436536SAndroid Build Coastguard Worker   {
803*e5436536SAndroid Build Coastguard Worker     /* Fetch number of octaves divided by 32 */
804*e5436536SAndroid Build Coastguard Worker     intTemp = (LONG)FDK_getNumOctavesDiv8(kx, k2) >> 2;
805*e5436536SAndroid Build Coastguard Worker 
806*e5436536SAndroid Build Coastguard Worker     /* Integer-Multiplication with number of bands: */
807*e5436536SAndroid Build Coastguard Worker     intTemp = intTemp * hHeaderData->bs_data.noise_bands;
808*e5436536SAndroid Build Coastguard Worker 
809*e5436536SAndroid Build Coastguard Worker     /* Add scaled 0.5 for rounding: */
810*e5436536SAndroid Build Coastguard Worker     intTemp = intTemp + (LONG)FL2FXCONST_SGL(0.5f / 32.0f);
811*e5436536SAndroid Build Coastguard Worker 
812*e5436536SAndroid Build Coastguard Worker     /* Convert to right-aligned integer: */
813*e5436536SAndroid Build Coastguard Worker     intTemp = intTemp >> (FRACT_BITS - 1 /*sign*/ - 5 /* rescale */);
814*e5436536SAndroid Build Coastguard Worker 
815*e5436536SAndroid Build Coastguard Worker     if (intTemp == 0) intTemp = 1;
816*e5436536SAndroid Build Coastguard Worker 
817*e5436536SAndroid Build Coastguard Worker     if (intTemp > MAX_NOISE_COEFFS) {
818*e5436536SAndroid Build Coastguard Worker       return SBRDEC_UNSUPPORTED_CONFIG;
819*e5436536SAndroid Build Coastguard Worker     }
820*e5436536SAndroid Build Coastguard Worker 
821*e5436536SAndroid Build Coastguard Worker     hFreq->nNfb = intTemp;
822*e5436536SAndroid Build Coastguard Worker   }
823*e5436536SAndroid Build Coastguard Worker 
824*e5436536SAndroid Build Coastguard Worker   hFreq->nInvfBands = hFreq->nNfb;
825*e5436536SAndroid Build Coastguard Worker 
826*e5436536SAndroid Build Coastguard Worker   /* Get noise bands */
827*e5436536SAndroid Build Coastguard Worker   sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb,
828*e5436536SAndroid Build Coastguard Worker                         hFreq->freqBandTable[0], nBandsLo);
829*e5436536SAndroid Build Coastguard Worker 
830*e5436536SAndroid Build Coastguard Worker   /* save old highband; required for overlap in usac
831*e5436536SAndroid Build Coastguard Worker      when headerchange occurs at XVAR and VARX frame; */
832*e5436536SAndroid Build Coastguard Worker   hFreq->ov_highSubband = hFreq->highSubband;
833*e5436536SAndroid Build Coastguard Worker 
834*e5436536SAndroid Build Coastguard Worker   hFreq->lowSubband = lsb;
835*e5436536SAndroid Build Coastguard Worker   hFreq->highSubband = usb;
836*e5436536SAndroid Build Coastguard Worker 
837*e5436536SAndroid Build Coastguard Worker   return SBRDEC_OK;
838*e5436536SAndroid Build Coastguard Worker }
839