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