xref: /aosp_15_r20/external/aac/libSBRenc/src/sbrenc_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 - 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 encoder 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 $Revision: 95225 $
106*e5436536SAndroid Build Coastguard Worker */
107*e5436536SAndroid Build Coastguard Worker 
108*e5436536SAndroid Build Coastguard Worker #include "sbrenc_freq_sca.h"
109*e5436536SAndroid Build Coastguard Worker #include "sbr_misc.h"
110*e5436536SAndroid Build Coastguard Worker 
111*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
112*e5436536SAndroid Build Coastguard Worker 
113*e5436536SAndroid Build Coastguard Worker /*  StartFreq */
114*e5436536SAndroid Build Coastguard Worker static INT getStartFreq(INT fsCore, const INT start_freq);
115*e5436536SAndroid Build Coastguard Worker 
116*e5436536SAndroid Build Coastguard Worker /* StopFreq */
117*e5436536SAndroid Build Coastguard Worker static INT getStopFreq(INT fsCore, const INT stop_freq);
118*e5436536SAndroid Build Coastguard Worker 
119*e5436536SAndroid Build Coastguard Worker static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor);
120*e5436536SAndroid Build Coastguard Worker static void CalcBands(INT *diff, INT start, INT stop, INT num_bands);
121*e5436536SAndroid Build Coastguard Worker static INT modifyBands(INT max_band, INT *diff, INT length);
122*e5436536SAndroid Build Coastguard Worker static void cumSum(INT start_value, INT *diff, INT length, UCHAR *start_adress);
123*e5436536SAndroid Build Coastguard Worker 
124*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
125*e5436536SAndroid Build Coastguard Worker  Functionname:  FDKsbrEnc_getSbrStartFreqRAW
126*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
127*e5436536SAndroid Build Coastguard Worker  Description:
128*e5436536SAndroid Build Coastguard Worker 
129*e5436536SAndroid Build Coastguard Worker  Arguments:
130*e5436536SAndroid Build Coastguard Worker 
131*e5436536SAndroid Build Coastguard Worker  Return:
132*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
133*e5436536SAndroid Build Coastguard Worker 
FDKsbrEnc_getSbrStartFreqRAW(INT startFreq,INT fsCore)134*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_getSbrStartFreqRAW(INT startFreq, INT fsCore) {
135*e5436536SAndroid Build Coastguard Worker   INT result;
136*e5436536SAndroid Build Coastguard Worker 
137*e5436536SAndroid Build Coastguard Worker   if (startFreq < 0 || startFreq > 15) {
138*e5436536SAndroid Build Coastguard Worker     return -1;
139*e5436536SAndroid Build Coastguard Worker   }
140*e5436536SAndroid Build Coastguard Worker   /* Update startFreq struct */
141*e5436536SAndroid Build Coastguard Worker   result = getStartFreq(fsCore, startFreq);
142*e5436536SAndroid Build Coastguard Worker 
143*e5436536SAndroid Build Coastguard Worker   result =
144*e5436536SAndroid Build Coastguard Worker       (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */
145*e5436536SAndroid Build Coastguard Worker 
146*e5436536SAndroid Build Coastguard Worker   return (result);
147*e5436536SAndroid Build Coastguard Worker 
148*e5436536SAndroid Build Coastguard Worker } /* End FDKsbrEnc_getSbrStartFreqRAW */
149*e5436536SAndroid Build Coastguard Worker 
150*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
151*e5436536SAndroid Build Coastguard Worker  Functionname:  getSbrStopFreq
152*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
153*e5436536SAndroid Build Coastguard Worker  Description:
154*e5436536SAndroid Build Coastguard Worker 
155*e5436536SAndroid Build Coastguard Worker  Arguments:
156*e5436536SAndroid Build Coastguard Worker 
157*e5436536SAndroid Build Coastguard Worker  Return:
158*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq,INT fsCore)159*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq, INT fsCore) {
160*e5436536SAndroid Build Coastguard Worker   INT result;
161*e5436536SAndroid Build Coastguard Worker 
162*e5436536SAndroid Build Coastguard Worker   if (stopFreq < 0 || stopFreq > 13) return -1;
163*e5436536SAndroid Build Coastguard Worker 
164*e5436536SAndroid Build Coastguard Worker   /* Uppdate stopFreq struct */
165*e5436536SAndroid Build Coastguard Worker   result = getStopFreq(fsCore, stopFreq);
166*e5436536SAndroid Build Coastguard Worker   result =
167*e5436536SAndroid Build Coastguard Worker       (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */
168*e5436536SAndroid Build Coastguard Worker 
169*e5436536SAndroid Build Coastguard Worker   return (result);
170*e5436536SAndroid Build Coastguard Worker } /* End getSbrStopFreq */
171*e5436536SAndroid Build Coastguard Worker 
172*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
173*e5436536SAndroid Build Coastguard Worker  Functionname:  getStartFreq
174*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
175*e5436536SAndroid Build Coastguard Worker  Description:
176*e5436536SAndroid Build Coastguard Worker 
177*e5436536SAndroid Build Coastguard Worker  Arguments:  fsCore - core sampling rate
178*e5436536SAndroid Build Coastguard Worker 
179*e5436536SAndroid Build Coastguard Worker 
180*e5436536SAndroid Build Coastguard Worker  Return:
181*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
getStartFreq(INT fsCore,const INT start_freq)182*e5436536SAndroid Build Coastguard Worker static INT getStartFreq(INT fsCore, const INT start_freq) {
183*e5436536SAndroid Build Coastguard Worker   INT k0_min;
184*e5436536SAndroid Build Coastguard Worker 
185*e5436536SAndroid Build Coastguard Worker   switch (fsCore) {
186*e5436536SAndroid Build Coastguard Worker     case 8000:
187*e5436536SAndroid Build Coastguard Worker       k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
188*e5436536SAndroid Build Coastguard Worker       break;
189*e5436536SAndroid Build Coastguard Worker     case 11025:
190*e5436536SAndroid Build Coastguard Worker       k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
191*e5436536SAndroid Build Coastguard Worker       break;
192*e5436536SAndroid Build Coastguard Worker     case 12000:
193*e5436536SAndroid Build Coastguard Worker       k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
194*e5436536SAndroid Build Coastguard Worker       break;
195*e5436536SAndroid Build Coastguard Worker     case 16000:
196*e5436536SAndroid Build Coastguard Worker       k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
197*e5436536SAndroid Build Coastguard Worker       break;
198*e5436536SAndroid Build Coastguard Worker     case 22050:
199*e5436536SAndroid Build Coastguard Worker       k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
200*e5436536SAndroid Build Coastguard Worker       break;
201*e5436536SAndroid Build Coastguard Worker     case 24000:
202*e5436536SAndroid Build Coastguard Worker       k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
203*e5436536SAndroid Build Coastguard Worker       break;
204*e5436536SAndroid Build Coastguard Worker     case 32000:
205*e5436536SAndroid Build Coastguard Worker       k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
206*e5436536SAndroid Build Coastguard Worker       break;
207*e5436536SAndroid Build Coastguard Worker     case 44100:
208*e5436536SAndroid Build Coastguard Worker       k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
209*e5436536SAndroid Build Coastguard Worker       break;
210*e5436536SAndroid Build Coastguard Worker     case 48000:
211*e5436536SAndroid Build Coastguard Worker       k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
212*e5436536SAndroid Build Coastguard Worker       break;
213*e5436536SAndroid Build Coastguard Worker     case 96000:
214*e5436536SAndroid Build Coastguard Worker       k0_min = 3; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
215*e5436536SAndroid Build Coastguard Worker       break;
216*e5436536SAndroid Build Coastguard Worker     default:
217*e5436536SAndroid Build Coastguard Worker       k0_min = 11; /* illegal fs */
218*e5436536SAndroid Build Coastguard Worker   }
219*e5436536SAndroid Build Coastguard Worker 
220*e5436536SAndroid Build Coastguard Worker   switch (fsCore) {
221*e5436536SAndroid Build Coastguard Worker     case 8000: {
222*e5436536SAndroid Build Coastguard Worker       INT v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
223*e5436536SAndroid Build Coastguard Worker       return (k0_min + v_offset[start_freq]);
224*e5436536SAndroid Build Coastguard Worker     }
225*e5436536SAndroid Build Coastguard Worker     case 11025: {
226*e5436536SAndroid Build Coastguard Worker       INT v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13};
227*e5436536SAndroid Build Coastguard Worker       return (k0_min + v_offset[start_freq]);
228*e5436536SAndroid Build Coastguard Worker     }
229*e5436536SAndroid Build Coastguard Worker     case 12000: {
230*e5436536SAndroid Build Coastguard Worker       INT v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
231*e5436536SAndroid Build Coastguard Worker       return (k0_min + v_offset[start_freq]);
232*e5436536SAndroid Build Coastguard Worker     }
233*e5436536SAndroid Build Coastguard Worker     case 16000: {
234*e5436536SAndroid Build Coastguard Worker       INT v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
235*e5436536SAndroid Build Coastguard Worker       return (k0_min + v_offset[start_freq]);
236*e5436536SAndroid Build Coastguard Worker     }
237*e5436536SAndroid Build Coastguard Worker     case 22050:
238*e5436536SAndroid Build Coastguard Worker     case 24000:
239*e5436536SAndroid Build Coastguard Worker     case 32000: {
240*e5436536SAndroid Build Coastguard Worker       INT v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20};
241*e5436536SAndroid Build Coastguard Worker       return (k0_min + v_offset[start_freq]);
242*e5436536SAndroid Build Coastguard Worker     }
243*e5436536SAndroid Build Coastguard Worker     case 44100:
244*e5436536SAndroid Build Coastguard Worker     case 48000:
245*e5436536SAndroid Build Coastguard Worker     case 96000: {
246*e5436536SAndroid Build Coastguard Worker       INT v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24};
247*e5436536SAndroid Build Coastguard Worker       return (k0_min + v_offset[start_freq]);
248*e5436536SAndroid Build Coastguard Worker     }
249*e5436536SAndroid Build Coastguard Worker     default: {
250*e5436536SAndroid Build Coastguard Worker       INT v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33};
251*e5436536SAndroid Build Coastguard Worker       return (k0_min + v_offset[start_freq]);
252*e5436536SAndroid Build Coastguard Worker     }
253*e5436536SAndroid Build Coastguard Worker   }
254*e5436536SAndroid Build Coastguard Worker } /* End getStartFreq */
255*e5436536SAndroid Build Coastguard Worker 
256*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
257*e5436536SAndroid Build Coastguard Worker  Functionname:  getStopFreq
258*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
259*e5436536SAndroid Build Coastguard Worker  Description:
260*e5436536SAndroid Build Coastguard Worker 
261*e5436536SAndroid Build Coastguard Worker  Arguments:
262*e5436536SAndroid Build Coastguard Worker 
263*e5436536SAndroid Build Coastguard Worker  Return:
264*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
getStopFreq(INT fsCore,const INT stop_freq)265*e5436536SAndroid Build Coastguard Worker static INT getStopFreq(INT fsCore, const INT stop_freq) {
266*e5436536SAndroid Build Coastguard Worker   INT result, i;
267*e5436536SAndroid Build Coastguard Worker   INT k1_min;
268*e5436536SAndroid Build Coastguard Worker   INT v_dstop[13];
269*e5436536SAndroid Build Coastguard Worker 
270*e5436536SAndroid Build Coastguard Worker   INT *v_stop_freq = NULL;
271*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_16[14] = {48, 49, 50, 51, 52, 54, 55,
272*e5436536SAndroid Build Coastguard Worker                             56, 57, 59, 60, 61, 63, 64};
273*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_22[14] = {35, 37, 38, 40, 42, 44, 46,
274*e5436536SAndroid Build Coastguard Worker                             48, 51, 53, 56, 58, 61, 64};
275*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_24[14] = {32, 34, 36, 38, 40, 42, 44,
276*e5436536SAndroid Build Coastguard Worker                             46, 49, 52, 55, 58, 61, 64};
277*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_32[14] = {32, 34, 36, 38, 40, 42, 44,
278*e5436536SAndroid Build Coastguard Worker                             46, 49, 52, 55, 58, 61, 64};
279*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_44[14] = {23, 25, 27, 29, 32, 34, 37,
280*e5436536SAndroid Build Coastguard Worker                             40, 43, 47, 51, 55, 59, 64};
281*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_48[14] = {21, 23, 25, 27, 30, 32, 35,
282*e5436536SAndroid Build Coastguard Worker                             38, 42, 45, 49, 54, 59, 64};
283*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_64[14] = {20, 22, 24, 26, 29, 31, 34,
284*e5436536SAndroid Build Coastguard Worker                             37, 41, 45, 49, 54, 59, 64};
285*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_88[14] = {15, 17, 19, 21, 23, 26, 29,
286*e5436536SAndroid Build Coastguard Worker                             33, 37, 41, 46, 51, 57, 64};
287*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_96[14] = {13, 15, 17, 19, 21, 24, 27,
288*e5436536SAndroid Build Coastguard Worker                             31, 35, 39, 44, 50, 57, 64};
289*e5436536SAndroid Build Coastguard Worker   INT v_stop_freq_192[14] = {7,  8,  10, 12, 14, 16, 19,
290*e5436536SAndroid Build Coastguard Worker                              23, 27, 32, 38, 46, 54, 64};
291*e5436536SAndroid Build Coastguard Worker 
292*e5436536SAndroid Build Coastguard Worker   switch (fsCore) {
293*e5436536SAndroid Build Coastguard Worker     case 8000:
294*e5436536SAndroid Build Coastguard Worker       k1_min = 48;
295*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_16;
296*e5436536SAndroid Build Coastguard Worker       break;
297*e5436536SAndroid Build Coastguard Worker     case 11025:
298*e5436536SAndroid Build Coastguard Worker       k1_min = 35;
299*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_22;
300*e5436536SAndroid Build Coastguard Worker       break;
301*e5436536SAndroid Build Coastguard Worker     case 12000:
302*e5436536SAndroid Build Coastguard Worker       k1_min = 32;
303*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_24;
304*e5436536SAndroid Build Coastguard Worker       break;
305*e5436536SAndroid Build Coastguard Worker     case 16000:
306*e5436536SAndroid Build Coastguard Worker       k1_min = 32;
307*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_32;
308*e5436536SAndroid Build Coastguard Worker       break;
309*e5436536SAndroid Build Coastguard Worker     case 22050:
310*e5436536SAndroid Build Coastguard Worker       k1_min = 23;
311*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_44;
312*e5436536SAndroid Build Coastguard Worker       break;
313*e5436536SAndroid Build Coastguard Worker     case 24000:
314*e5436536SAndroid Build Coastguard Worker       k1_min = 21;
315*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_48;
316*e5436536SAndroid Build Coastguard Worker       break;
317*e5436536SAndroid Build Coastguard Worker     case 32000:
318*e5436536SAndroid Build Coastguard Worker       k1_min = 20;
319*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_64;
320*e5436536SAndroid Build Coastguard Worker       break;
321*e5436536SAndroid Build Coastguard Worker     case 44100:
322*e5436536SAndroid Build Coastguard Worker       k1_min = 15;
323*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_88;
324*e5436536SAndroid Build Coastguard Worker       break;
325*e5436536SAndroid Build Coastguard Worker     case 48000:
326*e5436536SAndroid Build Coastguard Worker       k1_min = 13;
327*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_96;
328*e5436536SAndroid Build Coastguard Worker       break;
329*e5436536SAndroid Build Coastguard Worker     case 96000:
330*e5436536SAndroid Build Coastguard Worker       k1_min = 7;
331*e5436536SAndroid Build Coastguard Worker       v_stop_freq = v_stop_freq_192;
332*e5436536SAndroid Build Coastguard Worker       break;
333*e5436536SAndroid Build Coastguard Worker     default:
334*e5436536SAndroid Build Coastguard Worker       k1_min = 21; /* illegal fs  */
335*e5436536SAndroid Build Coastguard Worker   }
336*e5436536SAndroid Build Coastguard Worker 
337*e5436536SAndroid Build Coastguard Worker   /* Ensure increasing bandwidth */
338*e5436536SAndroid Build Coastguard Worker   for (i = 0; i <= 12; i++) {
339*e5436536SAndroid Build Coastguard Worker     v_dstop[i] = v_stop_freq[i + 1] - v_stop_freq[i];
340*e5436536SAndroid Build Coastguard Worker   }
341*e5436536SAndroid Build Coastguard Worker 
342*e5436536SAndroid Build Coastguard Worker   FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */
343*e5436536SAndroid Build Coastguard Worker 
344*e5436536SAndroid Build Coastguard Worker   result = k1_min;
345*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < stop_freq; i++) {
346*e5436536SAndroid Build Coastguard Worker     result = result + v_dstop[i];
347*e5436536SAndroid Build Coastguard Worker   }
348*e5436536SAndroid Build Coastguard Worker 
349*e5436536SAndroid Build Coastguard Worker   return (result);
350*e5436536SAndroid Build Coastguard Worker 
351*e5436536SAndroid Build Coastguard Worker } /* End getStopFreq */
352*e5436536SAndroid Build Coastguard Worker 
353*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
354*e5436536SAndroid Build Coastguard Worker  Functionname:  FDKsbrEnc_FindStartAndStopBand
355*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
356*e5436536SAndroid Build Coastguard Worker  Description:
357*e5436536SAndroid Build Coastguard Worker 
358*e5436536SAndroid Build Coastguard Worker  Arguments:     srSbr            SBR sampling freqency
359*e5436536SAndroid Build Coastguard Worker                 srCore           AAC core sampling freqency
360*e5436536SAndroid Build Coastguard Worker                 noChannels       Number of QMF channels
361*e5436536SAndroid Build Coastguard Worker                 startFreq        SBR start frequency in QMF bands
362*e5436536SAndroid Build Coastguard Worker                 stopFreq         SBR start frequency in QMF bands
363*e5436536SAndroid Build Coastguard Worker 
364*e5436536SAndroid Build Coastguard Worker                *k0               Output parameter
365*e5436536SAndroid Build Coastguard Worker                *k2               Output parameter
366*e5436536SAndroid Build Coastguard Worker 
367*e5436536SAndroid Build Coastguard Worker  Return:       Error code (0 is OK)
368*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
FDKsbrEnc_FindStartAndStopBand(const INT srSbr,const INT srCore,const INT noChannels,const INT startFreq,const INT stopFreq,INT * k0,INT * k2)369*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_FindStartAndStopBand(const INT srSbr, const INT srCore,
370*e5436536SAndroid Build Coastguard Worker                                    const INT noChannels, const INT startFreq,
371*e5436536SAndroid Build Coastguard Worker                                    const INT stopFreq, INT *k0, INT *k2) {
372*e5436536SAndroid Build Coastguard Worker   /* Update startFreq struct */
373*e5436536SAndroid Build Coastguard Worker   *k0 = getStartFreq(srCore, startFreq);
374*e5436536SAndroid Build Coastguard Worker 
375*e5436536SAndroid Build Coastguard Worker   /* Test if start freq is outside corecoder range */
376*e5436536SAndroid Build Coastguard Worker   if (srSbr * noChannels < *k0 * srCore) {
377*e5436536SAndroid Build Coastguard Worker     return (
378*e5436536SAndroid Build Coastguard Worker         1); /* raise the cross-over frequency and/or lower the number
379*e5436536SAndroid Build Coastguard Worker                of target bands per octave (or lower the sampling frequency) */
380*e5436536SAndroid Build Coastguard Worker   }
381*e5436536SAndroid Build Coastguard Worker 
382*e5436536SAndroid Build Coastguard Worker   /*Update stopFreq struct */
383*e5436536SAndroid Build Coastguard Worker   if (stopFreq < 14) {
384*e5436536SAndroid Build Coastguard Worker     *k2 = getStopFreq(srCore, stopFreq);
385*e5436536SAndroid Build Coastguard Worker   } else if (stopFreq == 14) {
386*e5436536SAndroid Build Coastguard Worker     *k2 = 2 * *k0;
387*e5436536SAndroid Build Coastguard Worker   } else {
388*e5436536SAndroid Build Coastguard Worker     *k2 = 3 * *k0;
389*e5436536SAndroid Build Coastguard Worker   }
390*e5436536SAndroid Build Coastguard Worker 
391*e5436536SAndroid Build Coastguard Worker   /* limit to Nyqvist */
392*e5436536SAndroid Build Coastguard Worker   if (*k2 > noChannels) {
393*e5436536SAndroid Build Coastguard Worker     *k2 = noChannels;
394*e5436536SAndroid Build Coastguard Worker   }
395*e5436536SAndroid Build Coastguard Worker 
396*e5436536SAndroid Build Coastguard Worker   /* Test for invalid  k0 k2 combinations */
397*e5436536SAndroid Build Coastguard Worker   if ((srCore == 22050) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS44100))
398*e5436536SAndroid Build Coastguard Worker     return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for
399*e5436536SAndroid Build Coastguard Worker                    fs=44.1kHz */
400*e5436536SAndroid Build Coastguard Worker 
401*e5436536SAndroid Build Coastguard Worker   if ((srCore >= 24000) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS48000))
402*e5436536SAndroid Build Coastguard Worker     return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for
403*e5436536SAndroid Build Coastguard Worker                    fs>=48kHz */
404*e5436536SAndroid Build Coastguard Worker 
405*e5436536SAndroid Build Coastguard Worker   if ((*k2 - *k0) > MAX_FREQ_COEFFS)
406*e5436536SAndroid Build Coastguard Worker     return (1); /*Number of bands exceeds valid range of MAX_FREQ_COEFFS */
407*e5436536SAndroid Build Coastguard Worker 
408*e5436536SAndroid Build Coastguard Worker   if ((*k2 - *k0) < 0) return (1); /* Number of bands is negative */
409*e5436536SAndroid Build Coastguard Worker 
410*e5436536SAndroid Build Coastguard Worker   return (0);
411*e5436536SAndroid Build Coastguard Worker }
412*e5436536SAndroid Build Coastguard Worker 
413*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
414*e5436536SAndroid Build Coastguard Worker  Functionname:  FDKsbrEnc_UpdateFreqScale
415*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
416*e5436536SAndroid Build Coastguard Worker  Description:
417*e5436536SAndroid Build Coastguard Worker 
418*e5436536SAndroid Build Coastguard Worker  Arguments:
419*e5436536SAndroid Build Coastguard Worker 
420*e5436536SAndroid Build Coastguard Worker  Return:
421*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
FDKsbrEnc_UpdateFreqScale(UCHAR * v_k_master,INT * h_num_bands,const INT k0,const INT k2,const INT freqScale,const INT alterScale)422*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, const INT k0,
423*e5436536SAndroid Build Coastguard Worker                               const INT k2, const INT freqScale,
424*e5436536SAndroid Build Coastguard Worker                               const INT alterScale)
425*e5436536SAndroid Build Coastguard Worker 
426*e5436536SAndroid Build Coastguard Worker {
427*e5436536SAndroid Build Coastguard Worker   INT b_p_o = 0; /* bands_per_octave */
428*e5436536SAndroid Build Coastguard Worker   FIXP_DBL warp = FL2FXCONST_DBL(0.0f);
429*e5436536SAndroid Build Coastguard Worker   INT dk = 0;
430*e5436536SAndroid Build Coastguard Worker 
431*e5436536SAndroid Build Coastguard Worker   /* Internal variables */
432*e5436536SAndroid Build Coastguard Worker   INT k1 = 0, i;
433*e5436536SAndroid Build Coastguard Worker   INT num_bands0;
434*e5436536SAndroid Build Coastguard Worker   INT num_bands1;
435*e5436536SAndroid Build Coastguard Worker   INT diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
436*e5436536SAndroid Build Coastguard Worker   INT *diff0 = diff_tot;
437*e5436536SAndroid Build Coastguard Worker   INT *diff1 = diff_tot + MAX_OCTAVE;
438*e5436536SAndroid Build Coastguard Worker   INT k2_achived;
439*e5436536SAndroid Build Coastguard Worker   INT k2_diff;
440*e5436536SAndroid Build Coastguard Worker   INT incr = 0;
441*e5436536SAndroid Build Coastguard Worker 
442*e5436536SAndroid Build Coastguard Worker   /* Init */
443*e5436536SAndroid Build Coastguard Worker   if (freqScale == 1) b_p_o = 12;
444*e5436536SAndroid Build Coastguard Worker   if (freqScale == 2) b_p_o = 10;
445*e5436536SAndroid Build Coastguard Worker   if (freqScale == 3) b_p_o = 8;
446*e5436536SAndroid Build Coastguard Worker 
447*e5436536SAndroid Build Coastguard Worker   if (freqScale > 0) /*Bark*/
448*e5436536SAndroid Build Coastguard Worker   {
449*e5436536SAndroid Build Coastguard Worker     if (alterScale == 0)
450*e5436536SAndroid Build Coastguard Worker       warp = FL2FXCONST_DBL(0.5f); /* 1.0/(1.0*2.0) */
451*e5436536SAndroid Build Coastguard Worker     else
452*e5436536SAndroid Build Coastguard Worker       warp = FL2FXCONST_DBL(1.0f / 2.6f); /* 1.0/(1.3*2.0); */
453*e5436536SAndroid Build Coastguard Worker 
454*e5436536SAndroid Build Coastguard Worker     if (4 * k2 >= 9 * k0) /*two or more regions (how many times the basis band
455*e5436536SAndroid Build Coastguard Worker                              is copied)*/
456*e5436536SAndroid Build Coastguard Worker     {
457*e5436536SAndroid Build Coastguard Worker       k1 = 2 * k0;
458*e5436536SAndroid Build Coastguard Worker 
459*e5436536SAndroid Build Coastguard Worker       num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
460*e5436536SAndroid Build Coastguard Worker       num_bands1 = numberOfBands(b_p_o, k1, k2, warp);
461*e5436536SAndroid Build Coastguard Worker 
462*e5436536SAndroid Build Coastguard Worker       CalcBands(diff0, k0, k1, num_bands0);       /*CalcBands1 => diff0 */
463*e5436536SAndroid Build Coastguard Worker       FDKsbrEnc_Shellsort_int(diff0, num_bands0); /*SortBands sort diff0 */
464*e5436536SAndroid Build Coastguard Worker 
465*e5436536SAndroid Build Coastguard Worker       if (diff0[0] == 0) /* too wide FB bands for target tuning */
466*e5436536SAndroid Build Coastguard Worker       {
467*e5436536SAndroid Build Coastguard Worker         return (1); /* raise the cross-over frequency and/or lower the number
468*e5436536SAndroid Build Coastguard Worker                        of target bands per octave (or lower the sampling
469*e5436536SAndroid Build Coastguard Worker                        frequency */
470*e5436536SAndroid Build Coastguard Worker       }
471*e5436536SAndroid Build Coastguard Worker 
472*e5436536SAndroid Build Coastguard Worker       cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */
473*e5436536SAndroid Build Coastguard Worker 
474*e5436536SAndroid Build Coastguard Worker       CalcBands(diff1, k1, k2, num_bands1);       /* CalcBands2 => diff1 */
475*e5436536SAndroid Build Coastguard Worker       FDKsbrEnc_Shellsort_int(diff1, num_bands1); /* SortBands sort diff1 */
476*e5436536SAndroid Build Coastguard Worker       if (diff0[num_bands0 - 1] > diff1[0])       /* max(1) > min(2) */
477*e5436536SAndroid Build Coastguard Worker       {
478*e5436536SAndroid Build Coastguard Worker         if (modifyBands(diff0[num_bands0 - 1], diff1, num_bands1)) return (1);
479*e5436536SAndroid Build Coastguard Worker       }
480*e5436536SAndroid Build Coastguard Worker 
481*e5436536SAndroid Build Coastguard Worker       /* Add 2'nd region */
482*e5436536SAndroid Build Coastguard Worker       cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]);
483*e5436536SAndroid Build Coastguard Worker       *h_num_bands = num_bands0 + num_bands1; /* Output nr of bands */
484*e5436536SAndroid Build Coastguard Worker 
485*e5436536SAndroid Build Coastguard Worker     } else /* one region */
486*e5436536SAndroid Build Coastguard Worker     {
487*e5436536SAndroid Build Coastguard Worker       k1 = k2;
488*e5436536SAndroid Build Coastguard Worker 
489*e5436536SAndroid Build Coastguard Worker       num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f));
490*e5436536SAndroid Build Coastguard Worker       CalcBands(diff0, k0, k1, num_bands0);       /* CalcBands1 => diff0 */
491*e5436536SAndroid Build Coastguard Worker       FDKsbrEnc_Shellsort_int(diff0, num_bands0); /* SortBands sort diff0 */
492*e5436536SAndroid Build Coastguard Worker 
493*e5436536SAndroid Build Coastguard Worker       if (diff0[0] == 0) /* too wide FB bands for target tuning */
494*e5436536SAndroid Build Coastguard Worker       {
495*e5436536SAndroid Build Coastguard Worker         return (1); /* raise the cross-over frequency and/or lower the number
496*e5436536SAndroid Build Coastguard Worker                        of target bands per octave (or lower the sampling
497*e5436536SAndroid Build Coastguard Worker                        frequency */
498*e5436536SAndroid Build Coastguard Worker       }
499*e5436536SAndroid Build Coastguard Worker 
500*e5436536SAndroid Build Coastguard Worker       cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */
501*e5436536SAndroid Build Coastguard Worker       *h_num_bands = num_bands0;                 /* Output nr of bands */
502*e5436536SAndroid Build Coastguard Worker     }
503*e5436536SAndroid Build Coastguard Worker   } else /* Linear mode */
504*e5436536SAndroid Build Coastguard Worker   {
505*e5436536SAndroid Build Coastguard Worker     if (alterScale == 0) {
506*e5436536SAndroid Build Coastguard Worker       dk = 1;
507*e5436536SAndroid Build Coastguard Worker       num_bands0 = 2 * ((k2 - k0) / 2); /* FLOOR to get to few number of bands*/
508*e5436536SAndroid Build Coastguard Worker     } else {
509*e5436536SAndroid Build Coastguard Worker       dk = 2;
510*e5436536SAndroid Build Coastguard Worker       num_bands0 =
511*e5436536SAndroid Build Coastguard Worker           2 * (((k2 - k0) / dk + 1) / 2); /* ROUND to get closest fit */
512*e5436536SAndroid Build Coastguard Worker     }
513*e5436536SAndroid Build Coastguard Worker 
514*e5436536SAndroid Build Coastguard Worker     k2_achived = k0 + num_bands0 * dk;
515*e5436536SAndroid Build Coastguard Worker     k2_diff = k2 - k2_achived;
516*e5436536SAndroid Build Coastguard Worker 
517*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < num_bands0; i++) diff_tot[i] = dk;
518*e5436536SAndroid Build Coastguard Worker 
519*e5436536SAndroid Build Coastguard Worker     /* If linear scale wasn't achived */
520*e5436536SAndroid Build Coastguard Worker     /* and we got wide SBR are */
521*e5436536SAndroid Build Coastguard Worker     if (k2_diff < 0) {
522*e5436536SAndroid Build Coastguard Worker       incr = 1;
523*e5436536SAndroid Build Coastguard Worker       i = 0;
524*e5436536SAndroid Build Coastguard Worker     }
525*e5436536SAndroid Build Coastguard Worker 
526*e5436536SAndroid Build Coastguard Worker     /* If linear scale wasn't achived */
527*e5436536SAndroid Build Coastguard Worker     /* and we got small SBR are */
528*e5436536SAndroid Build Coastguard Worker     if (k2_diff > 0) {
529*e5436536SAndroid Build Coastguard Worker       incr = -1;
530*e5436536SAndroid Build Coastguard Worker       i = num_bands0 - 1;
531*e5436536SAndroid Build Coastguard Worker     }
532*e5436536SAndroid Build Coastguard Worker 
533*e5436536SAndroid Build Coastguard Worker     /* Adjust diff vector to get sepc. SBR range */
534*e5436536SAndroid Build Coastguard Worker     while (k2_diff != 0) {
535*e5436536SAndroid Build Coastguard Worker       diff_tot[i] = diff_tot[i] - incr;
536*e5436536SAndroid Build Coastguard Worker       i = i + incr;
537*e5436536SAndroid Build Coastguard Worker       k2_diff = k2_diff + incr;
538*e5436536SAndroid Build Coastguard Worker     }
539*e5436536SAndroid Build Coastguard Worker 
540*e5436536SAndroid Build Coastguard Worker     cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */
541*e5436536SAndroid Build Coastguard Worker     *h_num_bands = num_bands0;                    /* Output nr of bands */
542*e5436536SAndroid Build Coastguard Worker   }
543*e5436536SAndroid Build Coastguard Worker 
544*e5436536SAndroid Build Coastguard Worker   if (*h_num_bands < 1) return (1); /*To small sbr area */
545*e5436536SAndroid Build Coastguard Worker 
546*e5436536SAndroid Build Coastguard Worker   return (0);
547*e5436536SAndroid Build Coastguard Worker } /* End FDKsbrEnc_UpdateFreqScale */
548*e5436536SAndroid Build Coastguard Worker 
numberOfBands(INT b_p_o,INT start,INT stop,FIXP_DBL warp_factor)549*e5436536SAndroid Build Coastguard Worker static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor) {
550*e5436536SAndroid Build Coastguard Worker   INT result = 0;
551*e5436536SAndroid Build Coastguard Worker   /* result = 2* (INT) ( (double)b_p_o *
552*e5436536SAndroid Build Coastguard Worker    * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) *
553*e5436536SAndroid Build Coastguard Worker    * (double)FX_DBL2FL(warp_factor) + 0.5); */
554*e5436536SAndroid Build Coastguard Worker   result = ((b_p_o * fMult((CalcLdInt(stop) - CalcLdInt(start)), warp_factor) +
555*e5436536SAndroid Build Coastguard Worker              (FL2FX_DBL(0.5f) >> LD_DATA_SHIFT)) >>
556*e5436536SAndroid Build Coastguard Worker             ((DFRACT_BITS - 1) - LD_DATA_SHIFT))
557*e5436536SAndroid Build Coastguard Worker            << 1; /* do not optimize anymore (rounding!!) */
558*e5436536SAndroid Build Coastguard Worker 
559*e5436536SAndroid Build Coastguard Worker   return (result);
560*e5436536SAndroid Build Coastguard Worker }
561*e5436536SAndroid Build Coastguard Worker 
CalcBands(INT * diff,INT start,INT stop,INT num_bands)562*e5436536SAndroid Build Coastguard Worker static void CalcBands(INT *diff, INT start, INT stop, INT num_bands) {
563*e5436536SAndroid Build Coastguard Worker   INT i, qb, qe, qtmp;
564*e5436536SAndroid Build Coastguard Worker   INT previous;
565*e5436536SAndroid Build Coastguard Worker   INT current;
566*e5436536SAndroid Build Coastguard Worker   FIXP_DBL base, exp, tmp;
567*e5436536SAndroid Build Coastguard Worker 
568*e5436536SAndroid Build Coastguard Worker   previous = start;
569*e5436536SAndroid Build Coastguard Worker   for (i = 1; i <= num_bands; i++) {
570*e5436536SAndroid Build Coastguard Worker     base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb);
571*e5436536SAndroid Build Coastguard Worker     exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe);
572*e5436536SAndroid Build Coastguard Worker     tmp = fPow(base, qb, exp, qe, &qtmp);
573*e5436536SAndroid Build Coastguard Worker     tmp = fMult(tmp, (FIXP_DBL)(start << 24));
574*e5436536SAndroid Build Coastguard Worker     current = (INT)scaleValue(tmp, qtmp - 23);
575*e5436536SAndroid Build Coastguard Worker     current = (current + 1) >> 1; /* rounding*/
576*e5436536SAndroid Build Coastguard Worker     diff[i - 1] = current - previous;
577*e5436536SAndroid Build Coastguard Worker     previous = current;
578*e5436536SAndroid Build Coastguard Worker   }
579*e5436536SAndroid Build Coastguard Worker 
580*e5436536SAndroid Build Coastguard Worker } /* End CalcBands */
581*e5436536SAndroid Build Coastguard Worker 
cumSum(INT start_value,INT * diff,INT length,UCHAR * start_adress)582*e5436536SAndroid Build Coastguard Worker static void cumSum(INT start_value, INT *diff, INT length,
583*e5436536SAndroid Build Coastguard Worker                    UCHAR *start_adress) {
584*e5436536SAndroid Build Coastguard Worker   INT i;
585*e5436536SAndroid Build Coastguard Worker   start_adress[0] = start_value;
586*e5436536SAndroid Build Coastguard Worker   for (i = 1; i <= length; i++)
587*e5436536SAndroid Build Coastguard Worker     start_adress[i] = start_adress[i - 1] + diff[i - 1];
588*e5436536SAndroid Build Coastguard Worker } /* End cumSum */
589*e5436536SAndroid Build Coastguard Worker 
modifyBands(INT max_band_previous,INT * diff,INT length)590*e5436536SAndroid Build Coastguard Worker static INT modifyBands(INT max_band_previous, INT *diff, INT length) {
591*e5436536SAndroid Build Coastguard Worker   INT change = max_band_previous - diff[0];
592*e5436536SAndroid Build Coastguard Worker 
593*e5436536SAndroid Build Coastguard Worker   /* Limit the change so that the last band cannot get narrower than the first
594*e5436536SAndroid Build Coastguard Worker    * one */
595*e5436536SAndroid Build Coastguard Worker   if (change > (diff[length - 1] - diff[0]) / 2)
596*e5436536SAndroid Build Coastguard Worker     change = (diff[length - 1] - diff[0]) / 2;
597*e5436536SAndroid Build Coastguard Worker 
598*e5436536SAndroid Build Coastguard Worker   diff[0] += change;
599*e5436536SAndroid Build Coastguard Worker   diff[length - 1] -= change;
600*e5436536SAndroid Build Coastguard Worker   FDKsbrEnc_Shellsort_int(diff, length);
601*e5436536SAndroid Build Coastguard Worker 
602*e5436536SAndroid Build Coastguard Worker   return (0);
603*e5436536SAndroid Build Coastguard Worker } /* End modifyBands */
604*e5436536SAndroid Build Coastguard Worker 
605*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
606*e5436536SAndroid Build Coastguard Worker  Functionname:  FDKsbrEnc_UpdateHiRes
607*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
608*e5436536SAndroid Build Coastguard Worker  Description:
609*e5436536SAndroid Build Coastguard Worker 
610*e5436536SAndroid Build Coastguard Worker 
611*e5436536SAndroid Build Coastguard Worker  Arguments:
612*e5436536SAndroid Build Coastguard Worker 
613*e5436536SAndroid Build Coastguard Worker  Return:
614*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
FDKsbrEnc_UpdateHiRes(UCHAR * h_hires,INT * num_hires,UCHAR * v_k_master,INT num_master,INT * xover_band)615*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires, UCHAR *v_k_master,
616*e5436536SAndroid Build Coastguard Worker                           INT num_master, INT *xover_band) {
617*e5436536SAndroid Build Coastguard Worker   INT i;
618*e5436536SAndroid Build Coastguard Worker   INT max1, max2;
619*e5436536SAndroid Build Coastguard Worker 
620*e5436536SAndroid Build Coastguard Worker   if ((v_k_master[*xover_band] >
621*e5436536SAndroid Build Coastguard Worker        32) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */
622*e5436536SAndroid Build Coastguard Worker       (*xover_band > num_master)) {
623*e5436536SAndroid Build Coastguard Worker     /* xover_band error, too big for this startFreq. Will be clipped */
624*e5436536SAndroid Build Coastguard Worker 
625*e5436536SAndroid Build Coastguard Worker     /* Calculate maximum value for xover_band */
626*e5436536SAndroid Build Coastguard Worker     max1 = 0;
627*e5436536SAndroid Build Coastguard Worker     max2 = num_master;
628*e5436536SAndroid Build Coastguard Worker     while ((v_k_master[max1 + 1] < 32) && /* noQMFChannels(dualRate)/divider */
629*e5436536SAndroid Build Coastguard Worker            ((max1 + 1) < max2)) {
630*e5436536SAndroid Build Coastguard Worker       max1++;
631*e5436536SAndroid Build Coastguard Worker     }
632*e5436536SAndroid Build Coastguard Worker 
633*e5436536SAndroid Build Coastguard Worker     *xover_band = max1;
634*e5436536SAndroid Build Coastguard Worker   }
635*e5436536SAndroid Build Coastguard Worker 
636*e5436536SAndroid Build Coastguard Worker   *num_hires = num_master - *xover_band;
637*e5436536SAndroid Build Coastguard Worker   for (i = *xover_band; i <= num_master; i++) {
638*e5436536SAndroid Build Coastguard Worker     h_hires[i - *xover_band] = v_k_master[i];
639*e5436536SAndroid Build Coastguard Worker   }
640*e5436536SAndroid Build Coastguard Worker 
641*e5436536SAndroid Build Coastguard Worker   return (0);
642*e5436536SAndroid Build Coastguard Worker } /* End FDKsbrEnc_UpdateHiRes */
643*e5436536SAndroid Build Coastguard Worker 
644*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
645*e5436536SAndroid Build Coastguard Worker  Functionname:  FDKsbrEnc_UpdateLoRes
646*e5436536SAndroid Build Coastguard Worker  *******************************************************************************
647*e5436536SAndroid Build Coastguard Worker  Description:
648*e5436536SAndroid Build Coastguard Worker 
649*e5436536SAndroid Build Coastguard Worker  Arguments:
650*e5436536SAndroid Build Coastguard Worker 
651*e5436536SAndroid Build Coastguard Worker  Return:
652*e5436536SAndroid Build Coastguard Worker  *******************************************************************************/
FDKsbrEnc_UpdateLoRes(UCHAR * h_lores,INT * num_lores,UCHAR * h_hires,INT num_hires)653*e5436536SAndroid Build Coastguard Worker void FDKsbrEnc_UpdateLoRes(UCHAR *h_lores, INT *num_lores, UCHAR *h_hires,
654*e5436536SAndroid Build Coastguard Worker                            INT num_hires) {
655*e5436536SAndroid Build Coastguard Worker   INT i;
656*e5436536SAndroid Build Coastguard Worker 
657*e5436536SAndroid Build Coastguard Worker   if (num_hires % 2 == 0) /* if even number of hires bands */
658*e5436536SAndroid Build Coastguard Worker   {
659*e5436536SAndroid Build Coastguard Worker     *num_lores = num_hires / 2;
660*e5436536SAndroid Build Coastguard Worker     /* Use every second lores=hires[0,2,4...] */
661*e5436536SAndroid Build Coastguard Worker     for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2];
662*e5436536SAndroid Build Coastguard Worker 
663*e5436536SAndroid Build Coastguard Worker   } else /* odd number of hires which means xover is odd */
664*e5436536SAndroid Build Coastguard Worker   {
665*e5436536SAndroid Build Coastguard Worker     *num_lores = (num_hires + 1) / 2;
666*e5436536SAndroid Build Coastguard Worker 
667*e5436536SAndroid Build Coastguard Worker     /* Use lores=hires[0,1,3,5 ...] */
668*e5436536SAndroid Build Coastguard Worker     h_lores[0] = h_hires[0];
669*e5436536SAndroid Build Coastguard Worker     for (i = 1; i <= *num_lores; i++) {
670*e5436536SAndroid Build Coastguard Worker       h_lores[i] = h_hires[i * 2 - 1];
671*e5436536SAndroid Build Coastguard Worker     }
672*e5436536SAndroid Build Coastguard Worker   }
673*e5436536SAndroid Build Coastguard Worker 
674*e5436536SAndroid Build Coastguard Worker } /* End FDKsbrEnc_UpdateLoRes */
675