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