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