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