• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 /*!
85   \file
86   \brief  Frequency scale calculation
87 */
88 
89 #include "sbrdec_freq_sca.h"
90 
91 #include "transcendent.h"
92 #include "sbr_rom.h"
93 #include "env_extr.h"
94 
95 #include "genericStds.h"      /* need log() for debug-code only */
96 
97 #define MAX_OCTAVE         29
98 #define MAX_SECOND_REGION  50
99 
100 
101 static int  numberOfBands(FIXP_SGL bpo_div16, int start, int stop, int warpFlag);
102 static void CalcBands(UCHAR * diff, UCHAR start, UCHAR stop, UCHAR num_bands);
103 static SBR_ERROR modifyBands(UCHAR max_band, UCHAR * diff, UCHAR length);
104 static void cumSum(UCHAR start_value, UCHAR* diff, UCHAR length, UCHAR *start_adress);
105 
106 
107 
108 /*!
109   \brief     Retrieve QMF-band where the SBR range starts
110 
111   Convert startFreq which was read from the bitstream into a
112   QMF-channel number.
113 
114   \return  Number of start band
115 */
116 static UCHAR
getStartBand(UINT fs,UCHAR startFreq,UINT headerDataFlags)117 getStartBand(UINT   fs,               /*!< Output sampling frequency */
118              UCHAR  startFreq,        /*!< Index to table of possible start bands */
119              UINT   headerDataFlags)  /*!< Info to SBR mode */
120 {
121   INT  band;
122   UINT fsMapped;
123 
124     fsMapped = fs;
125 
126   switch (fsMapped) {
127     case 48000:
128       band = FDK_sbrDecoder_sbr_start_freq_48[startFreq];
129       break;
130     case 44100:
131       band = FDK_sbrDecoder_sbr_start_freq_44[startFreq];
132       break;
133     case 32000:
134       band = FDK_sbrDecoder_sbr_start_freq_32[startFreq];
135       break;
136     case 24000:
137       band = FDK_sbrDecoder_sbr_start_freq_24[startFreq];
138       break;
139     case 22050:
140       band = FDK_sbrDecoder_sbr_start_freq_22[startFreq];
141       break;
142     case 16000:
143       band = FDK_sbrDecoder_sbr_start_freq_16[startFreq];
144       break;
145     default:
146       band = 255;
147   }
148 
149   return band;
150 }
151 
152 
153 /*!
154   \brief     Retrieve QMF-band where the SBR range starts
155 
156   Convert startFreq which was read from the bitstream into a
157   QMF-channel number.
158 
159   \return  Number of start band
160 */
161 static UCHAR
getStopBand(UINT fs,UCHAR stopFreq,UINT headerDataFlags,UCHAR k0)162 getStopBand(UINT   fs,               /*!< Output sampling frequency */
163             UCHAR  stopFreq,         /*!< Index to table of possible start bands */
164             UINT   headerDataFlags,  /*!< Info to SBR mode */
165             UCHAR  k0)               /*!< Start freq index */
166 {
167   UCHAR k2;
168 
169   if (stopFreq < 14) {
170     INT    stopMin;
171     UCHAR  diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
172     UCHAR *diff0 = diff_tot;
173     UCHAR *diff1 = diff_tot+MAX_OCTAVE;
174 
175     if (fs < 32000) {
176       stopMin = (((2*6000*2*(64)) / fs) + 1) >> 1;
177     }
178     else {
179       if (fs < 64000) {
180         stopMin = (((2*8000*2*(64)) / fs) + 1) >> 1;
181       }
182       else {
183         stopMin = (((2*10000*2*(64)) / fs) + 1) >> 1;
184       }
185     }
186 
187     /*
188       Choose a stop band between k1 and 64 depending on stopFreq (0..13),
189       based on a logarithmic scale.
190       The vectors diff0 and diff1 are used temporarily here.
191     */
192     CalcBands( diff0, stopMin, 64, 13);
193     shellsort( diff0, 13);
194     cumSum(stopMin, diff0, 13, diff1);
195     k2 = diff1[stopFreq];
196   }
197   else if (stopFreq==14)
198     k2 = 2*k0;
199   else
200     k2 = 3*k0;
201 
202   /* Limit to Nyquist */
203   if (k2 > (64))
204     k2 = (64);
205 
206 
207   /* Range checks */
208   /* 1 <= difference <= 48; 1 <= fs <= 96000 */
209   if ( ((k2 - k0) > MAX_FREQ_COEFFS) || (k2 <= k0) ) {
210     return 255;
211   }
212 
213   if (headerDataFlags & (SBRDEC_SYNTAX_USAC|SBRDEC_SYNTAX_RSVD50)) {
214     /* 1 <= difference <= 35; 42000 <= fs <= 96000 */
215     if ( (fs >= 42000) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS44100 ) ) {
216       return 255;
217     }
218     /* 1 <= difference <= 32; 46009 <= fs <= 96000 */
219     if ( (fs >= 46009) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS48000 ) ) {
220       return 255;
221     }
222   }
223   else {
224     /* 1 <= difference <= 35; fs == 44100 */
225     if ( (fs == 44100) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS44100 ) ) {
226       return 255;
227     }
228     /* 1 <= difference <= 32; 48000 <= fs <= 96000 */
229     if ( (fs >= 48000) && ( (k2 - k0) > MAX_FREQ_COEFFS_FS48000 ) ) {
230       return 255;
231     }
232   }
233 
234   return k2;
235 }
236 
237 
238 /*!
239   \brief     Generates master frequency tables
240 
241   Frequency tables are calculated according to the selected domain
242   (linear/logarithmic) and granularity.
243   IEC 14496-3 4.6.18.3.2.1
244 
245   \return  errorCode, 0 if successful
246 */
247 SBR_ERROR
sbrdecUpdateFreqScale(UCHAR * v_k_master,UCHAR * numMaster,UINT fs,HANDLE_SBR_HEADER_DATA hHeaderData,UINT flags)248 sbrdecUpdateFreqScale(UCHAR * v_k_master,    /*!< Master table to be created */
249                       UCHAR *numMaster,      /*!< Number of entries in master table */
250                       UINT   fs,             /*!< SBR working sampling rate */
251                       HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Control data from bitstream */
252                       UINT flags)
253 {
254   FIXP_SGL bpo_div16;        /* bands_per_octave divided by 16 */
255   INT      dk=0;
256 
257   /* Internal variables */
258   UCHAR  k0, k2, i;
259   UCHAR  num_bands0 = 0;
260   UCHAR  num_bands1 = 0;
261   UCHAR  diff_tot[MAX_OCTAVE + MAX_SECOND_REGION];
262   UCHAR *diff0 = diff_tot;
263   UCHAR *diff1 = diff_tot+MAX_OCTAVE;
264   INT    k2_achived;
265   INT    k2_diff;
266   INT    incr=0;
267 
268   /*
269     Determine start band
270   */
271   k0 = getStartBand(fs, hHeaderData->bs_data.startFreq, flags);
272   if (k0 == 255) {
273     return SBRDEC_UNSUPPORTED_CONFIG;
274   }
275 
276   /*
277     Determine stop band
278   */
279   k2 = getStopBand(fs, hHeaderData->bs_data.stopFreq, flags, k0);
280   if (k2 == 255) {
281     return SBRDEC_UNSUPPORTED_CONFIG;
282   }
283 
284   if(hHeaderData->bs_data.freqScale>0) { /* Bark */
285     INT k1;
286 
287     if(hHeaderData->bs_data.freqScale==1) {
288       bpo_div16 = FL2FXCONST_SGL(12.0f/16.0f);
289     }
290     else if(hHeaderData->bs_data.freqScale==2) {
291       bpo_div16 = FL2FXCONST_SGL(10.0f/16.0f);
292     }
293     else {
294       bpo_div16 =  FL2FXCONST_SGL(8.0f/16.0f);
295     }
296 
297 
298     if( 1000 * k2 > 2245 * k0 ) { /* Two or more regions */
299       k1 = 2*k0;
300 
301       num_bands0 = numberOfBands(bpo_div16, k0, k1, 0);
302       num_bands1 = numberOfBands(bpo_div16, k1, k2, hHeaderData->bs_data.alterScale );
303       if ( num_bands0 < 1) {
304         return SBRDEC_UNSUPPORTED_CONFIG;
305       }
306       if ( num_bands1 < 1 ) {
307         return SBRDEC_UNSUPPORTED_CONFIG;
308       }
309 
310       CalcBands(diff0, k0, k1, num_bands0);
311       shellsort( diff0, num_bands0);
312       if (diff0[0] == 0) {
313 #ifdef DEBUG_TOOLS
314 #endif
315         return SBRDEC_UNSUPPORTED_CONFIG;
316       }
317 
318       cumSum(k0, diff0, num_bands0, v_k_master);
319 
320       CalcBands(diff1, k1, k2, num_bands1);
321       shellsort( diff1, num_bands1);
322       if(diff0[num_bands0-1] > diff1[0]) {
323         SBR_ERROR err;
324 
325         err = modifyBands(diff0[num_bands0-1],diff1, num_bands1);
326         if (err)
327           return SBRDEC_UNSUPPORTED_CONFIG;
328       }
329 
330       /* Add 2nd region */
331       cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]);
332       *numMaster = num_bands0 + num_bands1;     /* Output nr of bands */
333 
334     }
335     else { /* Only one region */
336       k1=k2;
337 
338       num_bands0 = numberOfBands(bpo_div16, k0, k1, 0);
339       if ( num_bands0 < 1) {
340         return SBRDEC_UNSUPPORTED_CONFIG;
341       }
342       CalcBands(diff0, k0, k1, num_bands0);
343       shellsort(diff0, num_bands0);
344       if (diff0[0] == 0) {
345 #ifdef DEBUG_TOOLS
346 #endif
347         return SBRDEC_UNSUPPORTED_CONFIG;
348       }
349 
350       cumSum(k0, diff0, num_bands0, v_k_master);
351       *numMaster = num_bands0;        /* Output nr of bands */
352 
353     }
354   }
355   else { /* Linear mode */
356      if (hHeaderData->bs_data.alterScale==0) {
357         dk = 1;
358         /* FLOOR to get to few number of bands (next lower even number) */
359         num_bands0 = (k2 - k0) & 254;
360       } else {
361         dk = 2;
362         num_bands0 = ( ((k2 - k0) >> 1) + 1 ) & 254; /* ROUND to the closest fit */
363       }
364 
365       if (num_bands0 < 1) {
366         return SBRDEC_UNSUPPORTED_CONFIG;
367         /* We must return already here because 'i' can become negative below. */
368       }
369 
370       k2_achived = k0 + num_bands0*dk;
371       k2_diff = k2 - k2_achived;
372 
373       for(i=0;i<num_bands0;i++)
374         diff_tot[i] = dk;
375 
376       /* If linear scale wasn't achieved */
377       /* and we got too wide SBR area */
378       if (k2_diff < 0) {
379           incr = 1;
380           i = 0;
381       }
382 
383       /* If linear scale wasn't achieved */
384       /* and we got too small SBR area */
385       if (k2_diff > 0) {
386           incr = -1;
387           i = num_bands0-1;
388       }
389 
390       /* Adjust diff vector to get sepc. SBR range */
391       while (k2_diff != 0) {
392         diff_tot[i] = diff_tot[i] - incr;
393         i = i + incr;
394         k2_diff = k2_diff + incr;
395       }
396 
397       cumSum(k0, diff_tot, num_bands0, v_k_master);/* cumsum */
398     *numMaster = num_bands0;  /* Output nr of bands */
399   }
400 
401   if (*numMaster < 1) {
402     return SBRDEC_UNSUPPORTED_CONFIG;
403   }
404 
405 
406   /*
407     Print out the calculated table
408   */
409 
410   return SBRDEC_OK;
411 }
412 
413 
414 /*!
415   \brief     Calculate frequency ratio of one SBR band
416 
417   All SBR bands should span a constant frequency range in the logarithmic
418   domain. This function calculates the ratio of any SBR band's upper and lower
419   frequency.
420 
421  \return    num_band-th root of k_start/k_stop
422 */
calcFactorPerBand(int k_start,int k_stop,int num_bands)423 static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands)
424 {
425 /* Scaled bandfactor and step 1 bit right to avoid overflow
426  * use double data type */
427   FIXP_DBL bandfactor = FL2FXCONST_DBL(0.25f); /* Start value */
428   FIXP_DBL step = FL2FXCONST_DBL(0.125f);      /* Initial increment for factor */
429 
430   int    direction = 1;
431 
432 /* Because saturation can't be done in INT IIS,
433  * changed start and stop data type from FIXP_SGL to FIXP_DBL */
434   FIXP_DBL start = k_start << (DFRACT_BITS-8);
435   FIXP_DBL stop = k_stop << (DFRACT_BITS-8);
436 
437   FIXP_DBL temp;
438 
439   int   j, i=0;
440 
441   while ( step > FL2FXCONST_DBL(0.0f)) {
442     i++;
443     temp = stop;
444 
445     /* Calculate temp^num_bands: */
446     for (j=0; j<num_bands; j++)
447       //temp = fMult(temp,bandfactor);
448       temp = fMultDiv2(temp,bandfactor)<<2;
449 
450     if (temp<start) { /* Factor too strong, make it weaker */
451       if (direction == 0)
452         /* Halfen step. Right shift is not done as fract because otherwise the
453            lowest bit cannot be cleared due to rounding */
454         step = (FIXP_DBL)((LONG)step >> 1);
455       direction = 1;
456       bandfactor = bandfactor + step;
457     }
458     else {  /* Factor is too weak: make it stronger */
459       if (direction == 1)
460         step = (FIXP_DBL)((LONG)step >> 1);
461       direction = 0;
462       bandfactor = bandfactor - step;
463     }
464 
465     if (i>100) {
466       step = FL2FXCONST_DBL(0.0f);
467     }
468   }
469   return FX_DBL2FX_SGL(bandfactor<<1);
470 }
471 
472 
473 /*!
474   \brief     Calculate number of SBR bands between start and stop band
475 
476   Given the number of bands per octave, this function calculates how many
477   bands fit in the given frequency range.
478   When the warpFlag is set, the 'band density' is decreased by a factor
479   of 1/1.3
480 
481   \return    number of bands
482 */
483 static int
numberOfBands(FIXP_SGL bpo_div16,int start,int stop,int warpFlag)484 numberOfBands(FIXP_SGL bpo_div16, /*!< Input: number of bands per octave divided by 16 */
485               int    start,     /*!< First QMF band of SBR frequency range */
486               int    stop,      /*!< Last QMF band of SBR frequency range + 1 */
487               int    warpFlag)  /*!< Stretching flag */
488 {
489   FIXP_SGL num_bands_div128;
490   int    num_bands;
491 
492   num_bands_div128 = FX_DBL2FX_SGL(fMult(FDK_getNumOctavesDiv8(start,stop),bpo_div16));
493 
494   if (warpFlag) {
495     /* Apply the warp factor of 1.3 to get wider bands.  We use a value
496        of 32768/25200 instead of the exact value to avoid critical cases
497        of rounding.
498     */
499     num_bands_div128 = FX_DBL2FX_SGL(fMult(num_bands_div128, FL2FXCONST_SGL(25200.0/32768.0)));
500   }
501 
502   /* add scaled 1 for rounding to even numbers: */
503   num_bands_div128 = num_bands_div128 + FL2FXCONST_SGL( 1.0f/128.0f );
504   /* scale back to right aligned integer and double the value: */
505   num_bands = 2 * ((LONG)num_bands_div128 >> (FRACT_BITS - 7));
506 
507   return(num_bands);
508 }
509 
510 
511 /*!
512   \brief     Calculate width of SBR bands
513 
514   Given the desired number of bands within the SBR frequency range,
515   this function calculates the width of each SBR band in QMF channels.
516   The bands get wider from start to stop (bark scale).
517 */
518 static void
CalcBands(UCHAR * diff,UCHAR start,UCHAR stop,UCHAR num_bands)519 CalcBands(UCHAR * diff,    /*!< Vector of widths to be calculated */
520           UCHAR start,     /*!< Lower end of subband range */
521           UCHAR stop,      /*!< Upper end of subband range */
522           UCHAR num_bands) /*!< Desired number of bands */
523 {
524   int i;
525   int previous;
526   int current;
527   FIXP_SGL exact, temp;
528   FIXP_SGL bandfactor = calcFactorPerBand(start, stop, num_bands);
529 
530   previous = stop; /* Start with highest QMF channel */
531   exact = (FIXP_SGL)(stop << (FRACT_BITS-8)); /* Shift left to gain some accuracy */
532 
533   for(i=num_bands-1; i>=0; i--) {
534     /* Calculate border of next lower sbr band */
535     exact = FX_DBL2FX_SGL(fMult(exact,bandfactor));
536 
537     /* Add scaled 0.5 for rounding:
538        We use a value 128/256 instead of 0.5 to avoid some critical cases of rounding. */
539     temp = exact +  FL2FXCONST_SGL(128.0/32768.0);
540 
541     /* scale back to right alinged integer: */
542     current = (LONG)temp >> (FRACT_BITS-8);
543 
544     /* Save width of band i */
545     diff[i] = previous - current;
546     previous = current;
547   }
548 }
549 
550 
551 /*!
552   \brief     Calculate cumulated sum vector from delta vector
553 */
554 static void
cumSum(UCHAR start_value,UCHAR * diff,UCHAR length,UCHAR * start_adress)555 cumSum(UCHAR start_value, UCHAR* diff, UCHAR length, UCHAR *start_adress)
556 {
557   int i;
558   start_adress[0]=start_value;
559   for(i=1; i<=length; i++)
560     start_adress[i] = start_adress[i-1] + diff[i-1];
561 }
562 
563 
564 /*!
565   \brief     Adapt width of frequency bands in the second region
566 
567   If SBR spans more than 2 octaves, the upper part of a bark-frequency-scale
568   is calculated separately. This function tries to avoid that the second region
569   starts with a band smaller than the highest band of the first region.
570 */
571 static SBR_ERROR
modifyBands(UCHAR max_band_previous,UCHAR * diff,UCHAR length)572 modifyBands(UCHAR max_band_previous, UCHAR * diff, UCHAR length)
573 {
574   int change = max_band_previous - diff[0];
575 
576   /* Limit the change so that the last band cannot get narrower than the first one */
577   if ( change > (diff[length-1]-diff[0])>>1 )
578     change = (diff[length-1]-diff[0])>>1;
579 
580   diff[0] += change;
581   diff[length-1] -= change;
582   shellsort(diff, length);
583 
584   return SBRDEC_OK;
585 }
586 
587 
588 /*!
589   \brief   Update high resolution frequency band table
590 */
591 static void
sbrdecUpdateHiRes(UCHAR * h_hires,UCHAR * num_hires,UCHAR * v_k_master,UCHAR num_bands,UCHAR xover_band)592 sbrdecUpdateHiRes(UCHAR * h_hires,
593                   UCHAR * num_hires,
594                   UCHAR * v_k_master,
595                   UCHAR num_bands,
596                   UCHAR xover_band)
597 {
598   UCHAR i;
599 
600   *num_hires = num_bands-xover_band;
601 
602   for(i=xover_band; i<=num_bands; i++) {
603     h_hires[i-xover_band] = v_k_master[i];
604   }
605 }
606 
607 
608 /*!
609   \brief  Build low resolution table out of high resolution table
610 */
611 static void
sbrdecUpdateLoRes(UCHAR * h_lores,UCHAR * num_lores,UCHAR * h_hires,UCHAR num_hires)612 sbrdecUpdateLoRes(UCHAR * h_lores,
613                   UCHAR * num_lores,
614                   UCHAR * h_hires,
615                   UCHAR num_hires)
616 {
617   UCHAR i;
618 
619   if( (num_hires & 1) == 0) {
620     /* If even number of hires bands */
621     *num_lores = num_hires >> 1;
622     /* Use every second lores=hires[0,2,4...] */
623     for(i=0; i<=*num_lores; i++)
624       h_lores[i] = h_hires[i*2];
625   }
626   else {
627     /* Odd number of hires, which means xover is odd */
628     *num_lores = (num_hires+1) >> 1;
629     /* Use lores=hires[0,1,3,5 ...] */
630     h_lores[0] = h_hires[0];
631     for(i=1; i<=*num_lores; i++) {
632       h_lores[i] = h_hires[i*2-1];
633     }
634   }
635 }
636 
637 
638 /*!
639   \brief   Derive a low-resolution frequency-table from the master frequency table
640 */
641 void
sbrdecDownSampleLoRes(UCHAR * v_result,UCHAR num_result,UCHAR * freqBandTableRef,UCHAR num_Ref)642 sbrdecDownSampleLoRes(UCHAR *v_result,
643                       UCHAR num_result,
644                       UCHAR *freqBandTableRef,
645                       UCHAR num_Ref)
646 {
647   int step;
648   int i,j;
649   int org_length,result_length;
650   int v_index[MAX_FREQ_COEFFS>>1];
651 
652   /* init */
653   org_length = num_Ref;
654   result_length = num_result;
655 
656   v_index[0] = 0;   /* Always use left border */
657   i=0;
658   while(org_length > 0) {
659     /* Create downsample vector */
660     i++;
661     step = org_length / result_length;
662     org_length = org_length - step;
663     result_length--;
664     v_index[i] = v_index[i-1] + step;
665   }
666 
667   for(j=0;j<=i;j++) {
668     /* Use downsample vector to index LoResolution vector */
669     v_result[j]=freqBandTableRef[v_index[j]];
670   }
671 
672 }
673 
674 
675 /*!
676   \brief   Sorting routine
677 */
shellsort(UCHAR * in,UCHAR n)678 void shellsort(UCHAR *in, UCHAR n)
679 {
680 
681   int i, j, v, w;
682   int inc = 1;
683 
684   do
685     inc = 3 * inc + 1;
686   while (inc <= n);
687 
688   do {
689     inc = inc / 3;
690     for (i = inc; i < n; i++) {
691       v = in[i];
692       j = i;
693       while ((w=in[j-inc]) > v) {
694         in[j] = w;
695         j -= inc;
696         if (j < inc)
697           break;
698       }
699       in[j] = v;
700     }
701   } while (inc > 1);
702 
703 }
704 
705 
706 
707 /*!
708   \brief   Reset frequency band tables
709   \return  errorCode, 0 if successful
710 */
711 SBR_ERROR
resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData,const UINT flags)712 resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags)
713 {
714   SBR_ERROR err = SBRDEC_OK;
715   int k2,kx, lsb, usb;
716   int     intTemp;
717   UCHAR    nBandsLo, nBandsHi;
718   HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
719 
720   /* Calculate master frequency function */
721   err = sbrdecUpdateFreqScale(hFreq->v_k_master,
722                               &hFreq->numMaster,
723                               hHeaderData->sbrProcSmplRate,
724                               hHeaderData,
725                               flags);
726 
727   if ( err || (hHeaderData->bs_info.xover_band > hFreq->numMaster) ) {
728     return SBRDEC_UNSUPPORTED_CONFIG;
729   }
730 
731   /* Derive Hiresolution from master frequency function */
732   sbrdecUpdateHiRes(hFreq->freqBandTable[1], &nBandsHi, hFreq->v_k_master, hFreq->numMaster, hHeaderData->bs_info.xover_band );
733   /* Derive Loresolution from Hiresolution */
734   sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1], nBandsHi);
735 
736 
737   hFreq->nSfb[0] = nBandsLo;
738   hFreq->nSfb[1] = nBandsHi;
739 
740   /* Check index to freqBandTable[0] */
741   if ( !(nBandsLo > 0) || (nBandsLo > (MAX_FREQ_COEFFS>>1)) ) {
742     return SBRDEC_UNSUPPORTED_CONFIG;
743   }
744 
745   lsb = hFreq->freqBandTable[0][0];
746   usb = hFreq->freqBandTable[0][nBandsLo];
747 
748   /* Additional check for lsb */
749   if ( (lsb > (32)) || (lsb >= usb) ) {
750     return SBRDEC_UNSUPPORTED_CONFIG;
751   }
752 
753 
754   /* Calculate number of noise bands */
755 
756   k2 = hFreq->freqBandTable[1][nBandsHi];
757   kx = hFreq->freqBandTable[1][0];
758 
759   if (hHeaderData->bs_data.noise_bands == 0)
760   {
761     hFreq->nNfb = 1;
762   }
763   else /* Calculate no of noise bands 1,2 or 3 bands/octave */
764   {
765     /* Fetch number of octaves divided by 32 */
766     intTemp = (LONG)FDK_getNumOctavesDiv8(kx,k2) >> 2;
767 
768     /* Integer-Multiplication with number of bands: */
769     intTemp = intTemp * hHeaderData->bs_data.noise_bands;
770 
771     /* Add scaled 0.5 for rounding: */
772     intTemp = intTemp + (LONG)FL2FXCONST_SGL(0.5f/32.0f);
773 
774     /* Convert to right-aligned integer: */
775     intTemp = intTemp >> (FRACT_BITS - 1 /*sign*/ - 5 /* rescale */);
776 
777     /* Compare with float calculation */
778     FDK_ASSERT( intTemp ==  (int)((hHeaderData->bs_data.noise_bands * FDKlog( (float)k2/kx) / (float)(FDKlog(2.0)))+0.5) );
779 
780     if( intTemp==0)
781       intTemp=1;
782 
783     hFreq->nNfb = intTemp;
784   }
785 
786   hFreq->nInvfBands = hFreq->nNfb;
787 
788   if( hFreq->nNfb > MAX_NOISE_COEFFS ) {
789     return SBRDEC_UNSUPPORTED_CONFIG;
790   }
791 
792   /* Get noise bands */
793   sbrdecDownSampleLoRes(hFreq->freqBandTableNoise,
794                         hFreq->nNfb,
795                         hFreq->freqBandTable[0],
796                         nBandsLo);
797 
798 
799 
800 
801   hFreq->lowSubband  = lsb;
802   hFreq->highSubband = usb;
803 
804   return SBRDEC_OK;
805 }
806