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