/src/aac/libSBRenc/src/sbrenc_freq_sca.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* ----------------------------------------------------------------------------- |
2 | | Software License for The Fraunhofer FDK AAC Codec Library for Android |
3 | | |
4 | | © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten |
5 | | Forschung e.V. All rights reserved. |
6 | | |
7 | | 1. INTRODUCTION |
8 | | The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
9 | | that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
10 | | scheme for digital audio. This FDK AAC Codec software is intended to be used on |
11 | | a wide variety of Android devices. |
12 | | |
13 | | AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
14 | | general perceptual audio codecs. AAC-ELD is considered the best-performing |
15 | | full-bandwidth communications codec by independent studies and is widely |
16 | | deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
17 | | specifications. |
18 | | |
19 | | Patent licenses for necessary patent claims for the FDK AAC Codec (including |
20 | | those of Fraunhofer) may be obtained through Via Licensing |
21 | | (www.vialicensing.com) or through the respective patent owners individually for |
22 | | the purpose of encoding or decoding bit streams in products that are compliant |
23 | | with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
24 | | Android devices already license these patent claims through Via Licensing or |
25 | | directly from the patent owners, and therefore FDK AAC Codec software may |
26 | | already be covered under those patent licenses when it is used for those |
27 | | licensed purposes only. |
28 | | |
29 | | Commercially-licensed AAC software libraries, including floating-point versions |
30 | | with enhanced sound quality, are also available from Fraunhofer. Users are |
31 | | encouraged to check the Fraunhofer website for additional applications |
32 | | information and documentation. |
33 | | |
34 | | 2. COPYRIGHT LICENSE |
35 | | |
36 | | Redistribution and use in source and binary forms, with or without modification, |
37 | | are permitted without payment of copyright license fees provided that you |
38 | | satisfy the following conditions: |
39 | | |
40 | | You must retain the complete text of this software license in redistributions of |
41 | | the FDK AAC Codec or your modifications thereto in source code form. |
42 | | |
43 | | You must retain the complete text of this software license in the documentation |
44 | | and/or other materials provided with redistributions of the FDK AAC Codec or |
45 | | your modifications thereto in binary form. You must make available free of |
46 | | charge copies of the complete source code of the FDK AAC Codec and your |
47 | | modifications thereto to recipients of copies in binary form. |
48 | | |
49 | | The name of Fraunhofer may not be used to endorse or promote products derived |
50 | | from this library without prior written permission. |
51 | | |
52 | | You may not charge copyright license fees for anyone to use, copy or distribute |
53 | | the FDK AAC Codec software or your modifications thereto. |
54 | | |
55 | | Your modified versions of the FDK AAC Codec must carry prominent notices stating |
56 | | that you changed the software and the date of any change. For modified versions |
57 | | of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
58 | | must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
59 | | AAC Codec Library for Android." |
60 | | |
61 | | 3. NO PATENT LICENSE |
62 | | |
63 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
64 | | limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
65 | | Fraunhofer provides no warranty of patent non-infringement with respect to this |
66 | | software. |
67 | | |
68 | | You may use this FDK AAC Codec software or modifications thereto only for |
69 | | purposes that are authorized by appropriate patent licenses. |
70 | | |
71 | | 4. DISCLAIMER |
72 | | |
73 | | This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
74 | | holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
75 | | including but not limited to the implied warranties of merchantability and |
76 | | fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
77 | | CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
78 | | or consequential damages, including but not limited to procurement of substitute |
79 | | goods or services; loss of use, data, or profits, or business interruption, |
80 | | however caused and on any theory of liability, whether in contract, strict |
81 | | liability, or tort (including negligence), arising in any way out of the use of |
82 | | this software, even if advised of the possibility of such damage. |
83 | | |
84 | | 5. CONTACT INFORMATION |
85 | | |
86 | | Fraunhofer Institute for Integrated Circuits IIS |
87 | | Attention: Audio and Multimedia Departments - FDK AAC LL |
88 | | Am Wolfsmantel 33 |
89 | | 91058 Erlangen, Germany |
90 | | |
91 | | www.iis.fraunhofer.de/amm |
92 | | amm-info@iis.fraunhofer.de |
93 | | ----------------------------------------------------------------------------- */ |
94 | | |
95 | | /**************************** SBR encoder library ****************************** |
96 | | |
97 | | Author(s): |
98 | | |
99 | | Description: |
100 | | |
101 | | *******************************************************************************/ |
102 | | |
103 | | /*! |
104 | | \file |
105 | | \brief frequency scale $Revision: 95225 $ |
106 | | */ |
107 | | |
108 | | #include "sbrenc_freq_sca.h" |
109 | | #include "sbr_misc.h" |
110 | | |
111 | | #include "genericStds.h" |
112 | | |
113 | | /* StartFreq */ |
114 | | static INT getStartFreq(INT fsCore, const INT start_freq); |
115 | | |
116 | | /* StopFreq */ |
117 | | static INT getStopFreq(INT fsCore, const INT stop_freq); |
118 | | |
119 | | static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor); |
120 | | static void CalcBands(INT *diff, INT start, INT stop, INT num_bands); |
121 | | static INT modifyBands(INT max_band, INT *diff, INT length); |
122 | | static void cumSum(INT start_value, INT *diff, INT length, UCHAR *start_adress); |
123 | | |
124 | | /******************************************************************************* |
125 | | Functionname: FDKsbrEnc_getSbrStartFreqRAW |
126 | | ******************************************************************************* |
127 | | Description: |
128 | | |
129 | | Arguments: |
130 | | |
131 | | Return: |
132 | | *******************************************************************************/ |
133 | | |
134 | 0 | INT FDKsbrEnc_getSbrStartFreqRAW(INT startFreq, INT fsCore) { |
135 | 0 | INT result; |
136 | |
|
137 | 0 | if (startFreq < 0 || startFreq > 15) { |
138 | 0 | return -1; |
139 | 0 | } |
140 | | /* Update startFreq struct */ |
141 | 0 | result = getStartFreq(fsCore, startFreq); |
142 | |
|
143 | 0 | result = |
144 | 0 | (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */ |
145 | |
|
146 | 0 | return (result); |
147 | |
|
148 | 0 | } /* End FDKsbrEnc_getSbrStartFreqRAW */ |
149 | | |
150 | | /******************************************************************************* |
151 | | Functionname: getSbrStopFreq |
152 | | ******************************************************************************* |
153 | | Description: |
154 | | |
155 | | Arguments: |
156 | | |
157 | | Return: |
158 | | *******************************************************************************/ |
159 | 0 | INT FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq, INT fsCore) { |
160 | 0 | INT result; |
161 | |
|
162 | 0 | if (stopFreq < 0 || stopFreq > 13) return -1; |
163 | | |
164 | | /* Uppdate stopFreq struct */ |
165 | 0 | result = getStopFreq(fsCore, stopFreq); |
166 | 0 | result = |
167 | 0 | (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */ |
168 | |
|
169 | 0 | return (result); |
170 | 0 | } /* End getSbrStopFreq */ |
171 | | |
172 | | /******************************************************************************* |
173 | | Functionname: getStartFreq |
174 | | ******************************************************************************* |
175 | | Description: |
176 | | |
177 | | Arguments: fsCore - core sampling rate |
178 | | |
179 | | |
180 | | Return: |
181 | | *******************************************************************************/ |
182 | 0 | static INT getStartFreq(INT fsCore, const INT start_freq) { |
183 | 0 | INT k0_min; |
184 | |
|
185 | 0 | switch (fsCore) { |
186 | 0 | case 8000: |
187 | 0 | k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ |
188 | 0 | break; |
189 | 0 | case 11025: |
190 | 0 | k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ |
191 | 0 | break; |
192 | 0 | case 12000: |
193 | 0 | k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ |
194 | 0 | break; |
195 | 0 | case 16000: |
196 | 0 | k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ |
197 | 0 | break; |
198 | 0 | case 22050: |
199 | 0 | k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ |
200 | 0 | break; |
201 | 0 | case 24000: |
202 | 0 | k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ |
203 | 0 | break; |
204 | 0 | case 32000: |
205 | 0 | k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ |
206 | 0 | break; |
207 | 0 | case 44100: |
208 | 0 | k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ |
209 | 0 | break; |
210 | 0 | case 48000: |
211 | 0 | k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ |
212 | 0 | break; |
213 | 0 | case 96000: |
214 | 0 | k0_min = 3; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ |
215 | 0 | break; |
216 | 0 | default: |
217 | 0 | k0_min = 11; /* illegal fs */ |
218 | 0 | } |
219 | | |
220 | 0 | switch (fsCore) { |
221 | 0 | case 8000: { |
222 | 0 | INT v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; |
223 | 0 | return (k0_min + v_offset[start_freq]); |
224 | 0 | } |
225 | 0 | case 11025: { |
226 | 0 | INT v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}; |
227 | 0 | return (k0_min + v_offset[start_freq]); |
228 | 0 | } |
229 | 0 | case 12000: { |
230 | 0 | INT v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; |
231 | 0 | return (k0_min + v_offset[start_freq]); |
232 | 0 | } |
233 | 0 | case 16000: { |
234 | 0 | INT v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; |
235 | 0 | return (k0_min + v_offset[start_freq]); |
236 | 0 | } |
237 | 0 | case 22050: |
238 | 0 | case 24000: |
239 | 0 | case 32000: { |
240 | 0 | INT v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}; |
241 | 0 | return (k0_min + v_offset[start_freq]); |
242 | 0 | } |
243 | 0 | case 44100: |
244 | 0 | case 48000: |
245 | 0 | case 96000: { |
246 | 0 | INT v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}; |
247 | 0 | return (k0_min + v_offset[start_freq]); |
248 | 0 | } |
249 | 0 | default: { |
250 | 0 | INT v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33}; |
251 | 0 | return (k0_min + v_offset[start_freq]); |
252 | 0 | } |
253 | 0 | } |
254 | 0 | } /* End getStartFreq */ |
255 | | |
256 | | /******************************************************************************* |
257 | | Functionname: getStopFreq |
258 | | ******************************************************************************* |
259 | | Description: |
260 | | |
261 | | Arguments: |
262 | | |
263 | | Return: |
264 | | *******************************************************************************/ |
265 | 0 | static INT getStopFreq(INT fsCore, const INT stop_freq) { |
266 | 0 | INT result, i; |
267 | 0 | INT k1_min; |
268 | 0 | INT v_dstop[13]; |
269 | |
|
270 | 0 | INT *v_stop_freq = NULL; |
271 | 0 | INT v_stop_freq_16[14] = {48, 49, 50, 51, 52, 54, 55, |
272 | 0 | 56, 57, 59, 60, 61, 63, 64}; |
273 | 0 | INT v_stop_freq_22[14] = {35, 37, 38, 40, 42, 44, 46, |
274 | 0 | 48, 51, 53, 56, 58, 61, 64}; |
275 | 0 | INT v_stop_freq_24[14] = {32, 34, 36, 38, 40, 42, 44, |
276 | 0 | 46, 49, 52, 55, 58, 61, 64}; |
277 | 0 | INT v_stop_freq_32[14] = {32, 34, 36, 38, 40, 42, 44, |
278 | 0 | 46, 49, 52, 55, 58, 61, 64}; |
279 | 0 | INT v_stop_freq_44[14] = {23, 25, 27, 29, 32, 34, 37, |
280 | 0 | 40, 43, 47, 51, 55, 59, 64}; |
281 | 0 | INT v_stop_freq_48[14] = {21, 23, 25, 27, 30, 32, 35, |
282 | 0 | 38, 42, 45, 49, 54, 59, 64}; |
283 | 0 | INT v_stop_freq_64[14] = {20, 22, 24, 26, 29, 31, 34, |
284 | 0 | 37, 41, 45, 49, 54, 59, 64}; |
285 | 0 | INT v_stop_freq_88[14] = {15, 17, 19, 21, 23, 26, 29, |
286 | 0 | 33, 37, 41, 46, 51, 57, 64}; |
287 | 0 | INT v_stop_freq_96[14] = {13, 15, 17, 19, 21, 24, 27, |
288 | 0 | 31, 35, 39, 44, 50, 57, 64}; |
289 | 0 | INT v_stop_freq_192[14] = {7, 8, 10, 12, 14, 16, 19, |
290 | 0 | 23, 27, 32, 38, 46, 54, 64}; |
291 | |
|
292 | 0 | switch (fsCore) { |
293 | 0 | case 8000: |
294 | 0 | k1_min = 48; |
295 | 0 | v_stop_freq = v_stop_freq_16; |
296 | 0 | break; |
297 | 0 | case 11025: |
298 | 0 | k1_min = 35; |
299 | 0 | v_stop_freq = v_stop_freq_22; |
300 | 0 | break; |
301 | 0 | case 12000: |
302 | 0 | k1_min = 32; |
303 | 0 | v_stop_freq = v_stop_freq_24; |
304 | 0 | break; |
305 | 0 | case 16000: |
306 | 0 | k1_min = 32; |
307 | 0 | v_stop_freq = v_stop_freq_32; |
308 | 0 | break; |
309 | 0 | case 22050: |
310 | 0 | k1_min = 23; |
311 | 0 | v_stop_freq = v_stop_freq_44; |
312 | 0 | break; |
313 | 0 | case 24000: |
314 | 0 | k1_min = 21; |
315 | 0 | v_stop_freq = v_stop_freq_48; |
316 | 0 | break; |
317 | 0 | case 32000: |
318 | 0 | k1_min = 20; |
319 | 0 | v_stop_freq = v_stop_freq_64; |
320 | 0 | break; |
321 | 0 | case 44100: |
322 | 0 | k1_min = 15; |
323 | 0 | v_stop_freq = v_stop_freq_88; |
324 | 0 | break; |
325 | 0 | case 48000: |
326 | 0 | k1_min = 13; |
327 | 0 | v_stop_freq = v_stop_freq_96; |
328 | 0 | break; |
329 | 0 | case 96000: |
330 | 0 | k1_min = 7; |
331 | 0 | v_stop_freq = v_stop_freq_192; |
332 | 0 | break; |
333 | 0 | default: |
334 | 0 | k1_min = 21; /* illegal fs */ |
335 | 0 | } |
336 | | |
337 | | /* Ensure increasing bandwidth */ |
338 | 0 | for (i = 0; i <= 12; i++) { |
339 | 0 | v_dstop[i] = v_stop_freq[i + 1] - v_stop_freq[i]; |
340 | 0 | } |
341 | |
|
342 | 0 | FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */ |
343 | |
|
344 | 0 | result = k1_min; |
345 | 0 | for (i = 0; i < stop_freq; i++) { |
346 | 0 | result = result + v_dstop[i]; |
347 | 0 | } |
348 | |
|
349 | 0 | return (result); |
350 | |
|
351 | 0 | } /* End getStopFreq */ |
352 | | |
353 | | /******************************************************************************* |
354 | | Functionname: FDKsbrEnc_FindStartAndStopBand |
355 | | ******************************************************************************* |
356 | | Description: |
357 | | |
358 | | Arguments: srSbr SBR sampling freqency |
359 | | srCore AAC core sampling freqency |
360 | | noChannels Number of QMF channels |
361 | | startFreq SBR start frequency in QMF bands |
362 | | stopFreq SBR start frequency in QMF bands |
363 | | |
364 | | *k0 Output parameter |
365 | | *k2 Output parameter |
366 | | |
367 | | Return: Error code (0 is OK) |
368 | | *******************************************************************************/ |
369 | | INT FDKsbrEnc_FindStartAndStopBand(const INT srSbr, const INT srCore, |
370 | | const INT noChannels, const INT startFreq, |
371 | 0 | const INT stopFreq, INT *k0, INT *k2) { |
372 | | /* Update startFreq struct */ |
373 | 0 | *k0 = getStartFreq(srCore, startFreq); |
374 | | |
375 | | /* Test if start freq is outside corecoder range */ |
376 | 0 | if (srSbr * noChannels < *k0 * srCore) { |
377 | 0 | return ( |
378 | 0 | 1); /* raise the cross-over frequency and/or lower the number |
379 | | of target bands per octave (or lower the sampling frequency) */ |
380 | 0 | } |
381 | | |
382 | | /*Update stopFreq struct */ |
383 | 0 | if (stopFreq < 14) { |
384 | 0 | *k2 = getStopFreq(srCore, stopFreq); |
385 | 0 | } else if (stopFreq == 14) { |
386 | 0 | *k2 = 2 * *k0; |
387 | 0 | } else { |
388 | 0 | *k2 = 3 * *k0; |
389 | 0 | } |
390 | | |
391 | | /* limit to Nyqvist */ |
392 | 0 | if (*k2 > noChannels) { |
393 | 0 | *k2 = noChannels; |
394 | 0 | } |
395 | | |
396 | | /* Test for invalid k0 k2 combinations */ |
397 | 0 | if ((srCore == 22050) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS44100)) |
398 | 0 | return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for |
399 | | fs=44.1kHz */ |
400 | | |
401 | 0 | if ((srCore >= 24000) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS48000)) |
402 | 0 | return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for |
403 | | fs>=48kHz */ |
404 | | |
405 | 0 | if ((*k2 - *k0) > MAX_FREQ_COEFFS) |
406 | 0 | return (1); /*Number of bands exceeds valid range of MAX_FREQ_COEFFS */ |
407 | | |
408 | 0 | if ((*k2 - *k0) < 0) return (1); /* Number of bands is negative */ |
409 | | |
410 | 0 | return (0); |
411 | 0 | } |
412 | | |
413 | | /******************************************************************************* |
414 | | Functionname: FDKsbrEnc_UpdateFreqScale |
415 | | ******************************************************************************* |
416 | | Description: |
417 | | |
418 | | Arguments: |
419 | | |
420 | | Return: |
421 | | *******************************************************************************/ |
422 | | INT FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, const INT k0, |
423 | | const INT k2, const INT freqScale, |
424 | | const INT alterScale) |
425 | | |
426 | 0 | { |
427 | 0 | INT b_p_o = 0; /* bands_per_octave */ |
428 | 0 | FIXP_DBL warp = FL2FXCONST_DBL(0.0f); |
429 | 0 | INT dk = 0; |
430 | | |
431 | | /* Internal variables */ |
432 | 0 | INT k1 = 0, i; |
433 | 0 | INT num_bands0; |
434 | 0 | INT num_bands1; |
435 | 0 | INT diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; |
436 | 0 | INT *diff0 = diff_tot; |
437 | 0 | INT *diff1 = diff_tot + MAX_OCTAVE; |
438 | 0 | INT k2_achived; |
439 | 0 | INT k2_diff; |
440 | 0 | INT incr = 0; |
441 | | |
442 | | /* Init */ |
443 | 0 | if (freqScale == 1) b_p_o = 12; |
444 | 0 | if (freqScale == 2) b_p_o = 10; |
445 | 0 | if (freqScale == 3) b_p_o = 8; |
446 | |
|
447 | 0 | if (freqScale > 0) /*Bark*/ |
448 | 0 | { |
449 | 0 | if (alterScale == 0) |
450 | 0 | warp = FL2FXCONST_DBL(0.5f); /* 1.0/(1.0*2.0) */ |
451 | 0 | else |
452 | 0 | warp = FL2FXCONST_DBL(1.0f / 2.6f); /* 1.0/(1.3*2.0); */ |
453 | |
|
454 | 0 | if (4 * k2 >= 9 * k0) /*two or more regions (how many times the basis band |
455 | | is copied)*/ |
456 | 0 | { |
457 | 0 | k1 = 2 * k0; |
458 | |
|
459 | 0 | num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); |
460 | 0 | num_bands1 = numberOfBands(b_p_o, k1, k2, warp); |
461 | |
|
462 | 0 | CalcBands(diff0, k0, k1, num_bands0); /*CalcBands1 => diff0 */ |
463 | 0 | FDKsbrEnc_Shellsort_int(diff0, num_bands0); /*SortBands sort diff0 */ |
464 | |
|
465 | 0 | if (diff0[0] == 0) /* too wide FB bands for target tuning */ |
466 | 0 | { |
467 | 0 | return (1); /* raise the cross-over frequency and/or lower the number |
468 | | of target bands per octave (or lower the sampling |
469 | | frequency */ |
470 | 0 | } |
471 | | |
472 | 0 | cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */ |
473 | |
|
474 | 0 | CalcBands(diff1, k1, k2, num_bands1); /* CalcBands2 => diff1 */ |
475 | 0 | FDKsbrEnc_Shellsort_int(diff1, num_bands1); /* SortBands sort diff1 */ |
476 | 0 | if (diff0[num_bands0 - 1] > diff1[0]) /* max(1) > min(2) */ |
477 | 0 | { |
478 | 0 | if (modifyBands(diff0[num_bands0 - 1], diff1, num_bands1)) return (1); |
479 | 0 | } |
480 | | |
481 | | /* Add 2'nd region */ |
482 | 0 | cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]); |
483 | 0 | *h_num_bands = num_bands0 + num_bands1; /* Output nr of bands */ |
484 | |
|
485 | 0 | } else /* one region */ |
486 | 0 | { |
487 | 0 | k1 = k2; |
488 | |
|
489 | 0 | num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); |
490 | 0 | CalcBands(diff0, k0, k1, num_bands0); /* CalcBands1 => diff0 */ |
491 | 0 | FDKsbrEnc_Shellsort_int(diff0, num_bands0); /* SortBands sort diff0 */ |
492 | |
|
493 | 0 | if (diff0[0] == 0) /* too wide FB bands for target tuning */ |
494 | 0 | { |
495 | 0 | return (1); /* raise the cross-over frequency and/or lower the number |
496 | | of target bands per octave (or lower the sampling |
497 | | frequency */ |
498 | 0 | } |
499 | | |
500 | 0 | cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */ |
501 | 0 | *h_num_bands = num_bands0; /* Output nr of bands */ |
502 | 0 | } |
503 | 0 | } else /* Linear mode */ |
504 | 0 | { |
505 | 0 | if (alterScale == 0) { |
506 | 0 | dk = 1; |
507 | 0 | num_bands0 = 2 * ((k2 - k0) / 2); /* FLOOR to get to few number of bands*/ |
508 | 0 | } else { |
509 | 0 | dk = 2; |
510 | 0 | num_bands0 = |
511 | 0 | 2 * (((k2 - k0) / dk + 1) / 2); /* ROUND to get closest fit */ |
512 | 0 | } |
513 | |
|
514 | 0 | k2_achived = k0 + num_bands0 * dk; |
515 | 0 | k2_diff = k2 - k2_achived; |
516 | |
|
517 | 0 | for (i = 0; i < num_bands0; i++) diff_tot[i] = dk; |
518 | | |
519 | | /* If linear scale wasn't achived */ |
520 | | /* and we got wide SBR are */ |
521 | 0 | if (k2_diff < 0) { |
522 | 0 | incr = 1; |
523 | 0 | i = 0; |
524 | 0 | } |
525 | | |
526 | | /* If linear scale wasn't achived */ |
527 | | /* and we got small SBR are */ |
528 | 0 | if (k2_diff > 0) { |
529 | 0 | incr = -1; |
530 | 0 | i = num_bands0 - 1; |
531 | 0 | } |
532 | | |
533 | | /* Adjust diff vector to get sepc. SBR range */ |
534 | 0 | while (k2_diff != 0) { |
535 | 0 | diff_tot[i] = diff_tot[i] - incr; |
536 | 0 | i = i + incr; |
537 | 0 | k2_diff = k2_diff + incr; |
538 | 0 | } |
539 | |
|
540 | 0 | cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */ |
541 | 0 | *h_num_bands = num_bands0; /* Output nr of bands */ |
542 | 0 | } |
543 | | |
544 | 0 | if (*h_num_bands < 1) return (1); /*To small sbr area */ |
545 | | |
546 | 0 | return (0); |
547 | 0 | } /* End FDKsbrEnc_UpdateFreqScale */ |
548 | | |
549 | 0 | static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor) { |
550 | 0 | INT result = 0; |
551 | | /* result = 2* (INT) ( (double)b_p_o * |
552 | | * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) * |
553 | | * (double)FX_DBL2FL(warp_factor) + 0.5); */ |
554 | 0 | result = ((b_p_o * fMult((CalcLdInt(stop) - CalcLdInt(start)), warp_factor) + |
555 | 0 | (FL2FX_DBL(0.5f) >> LD_DATA_SHIFT)) >> |
556 | 0 | ((DFRACT_BITS - 1) - LD_DATA_SHIFT)) |
557 | 0 | << 1; /* do not optimize anymore (rounding!!) */ |
558 | |
|
559 | 0 | return (result); |
560 | 0 | } |
561 | | |
562 | 0 | static void CalcBands(INT *diff, INT start, INT stop, INT num_bands) { |
563 | 0 | INT i, qb, qe, qtmp; |
564 | 0 | INT previous; |
565 | 0 | INT current; |
566 | 0 | FIXP_DBL base, exp, tmp; |
567 | |
|
568 | 0 | previous = start; |
569 | 0 | for (i = 1; i <= num_bands; i++) { |
570 | 0 | base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb); |
571 | 0 | exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe); |
572 | 0 | tmp = fPow(base, qb, exp, qe, &qtmp); |
573 | 0 | tmp = fMult(tmp, (FIXP_DBL)(start << 24)); |
574 | 0 | current = (INT)scaleValue(tmp, qtmp - 23); |
575 | 0 | current = (current + 1) >> 1; /* rounding*/ |
576 | 0 | diff[i - 1] = current - previous; |
577 | 0 | previous = current; |
578 | 0 | } |
579 | |
|
580 | 0 | } /* End CalcBands */ |
581 | | |
582 | | static void cumSum(INT start_value, INT *diff, INT length, |
583 | 0 | UCHAR *start_adress) { |
584 | 0 | INT i; |
585 | 0 | start_adress[0] = start_value; |
586 | 0 | for (i = 1; i <= length; i++) |
587 | 0 | start_adress[i] = start_adress[i - 1] + diff[i - 1]; |
588 | 0 | } /* End cumSum */ |
589 | | |
590 | 0 | static INT modifyBands(INT max_band_previous, INT *diff, INT length) { |
591 | 0 | INT change = max_band_previous - diff[0]; |
592 | | |
593 | | /* Limit the change so that the last band cannot get narrower than the first |
594 | | * one */ |
595 | 0 | if (change > (diff[length - 1] - diff[0]) / 2) |
596 | 0 | change = (diff[length - 1] - diff[0]) / 2; |
597 | |
|
598 | 0 | diff[0] += change; |
599 | 0 | diff[length - 1] -= change; |
600 | 0 | FDKsbrEnc_Shellsort_int(diff, length); |
601 | |
|
602 | 0 | return (0); |
603 | 0 | } /* End modifyBands */ |
604 | | |
605 | | /******************************************************************************* |
606 | | Functionname: FDKsbrEnc_UpdateHiRes |
607 | | ******************************************************************************* |
608 | | Description: |
609 | | |
610 | | |
611 | | Arguments: |
612 | | |
613 | | Return: |
614 | | *******************************************************************************/ |
615 | | INT FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires, UCHAR *v_k_master, |
616 | 0 | INT num_master, INT *xover_band) { |
617 | 0 | INT i; |
618 | 0 | INT max1, max2; |
619 | |
|
620 | 0 | if ((v_k_master[*xover_band] > |
621 | 0 | 32) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */ |
622 | 0 | (*xover_band > num_master)) { |
623 | | /* xover_band error, too big for this startFreq. Will be clipped */ |
624 | | |
625 | | /* Calculate maximum value for xover_band */ |
626 | 0 | max1 = 0; |
627 | 0 | max2 = num_master; |
628 | 0 | while ((v_k_master[max1 + 1] < 32) && /* noQMFChannels(dualRate)/divider */ |
629 | 0 | ((max1 + 1) < max2)) { |
630 | 0 | max1++; |
631 | 0 | } |
632 | |
|
633 | 0 | *xover_band = max1; |
634 | 0 | } |
635 | |
|
636 | 0 | *num_hires = num_master - *xover_band; |
637 | 0 | for (i = *xover_band; i <= num_master; i++) { |
638 | 0 | h_hires[i - *xover_band] = v_k_master[i]; |
639 | 0 | } |
640 | |
|
641 | 0 | return (0); |
642 | 0 | } /* End FDKsbrEnc_UpdateHiRes */ |
643 | | |
644 | | /******************************************************************************* |
645 | | Functionname: FDKsbrEnc_UpdateLoRes |
646 | | ******************************************************************************* |
647 | | Description: |
648 | | |
649 | | Arguments: |
650 | | |
651 | | Return: |
652 | | *******************************************************************************/ |
653 | | void FDKsbrEnc_UpdateLoRes(UCHAR *h_lores, INT *num_lores, UCHAR *h_hires, |
654 | 0 | INT num_hires) { |
655 | 0 | INT i; |
656 | |
|
657 | 0 | if (num_hires % 2 == 0) /* if even number of hires bands */ |
658 | 0 | { |
659 | 0 | *num_lores = num_hires / 2; |
660 | | /* Use every second lores=hires[0,2,4...] */ |
661 | 0 | for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2]; |
662 | |
|
663 | 0 | } else /* odd number of hires which means xover is odd */ |
664 | 0 | { |
665 | 0 | *num_lores = (num_hires + 1) / 2; |
666 | | |
667 | | /* Use lores=hires[0,1,3,5 ...] */ |
668 | 0 | h_lores[0] = h_hires[0]; |
669 | 0 | for (i = 1; i <= *num_lores; i++) { |
670 | 0 | h_lores[i] = h_hires[i * 2 - 1]; |
671 | 0 | } |
672 | 0 | } |
673 | |
|
674 | 0 | } /* End FDKsbrEnc_UpdateLoRes */ |