• 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
87 */
88 
89 #include "sbrenc_freq_sca.h"
90 #include "sbr_misc.h"
91 
92 #include "genericStds.h"
93 
94 /*  StartFreq */
95 static INT getStartFreq(INT fs, const INT start_freq);
96 
97 /* StopFreq */
98 static INT getStopFreq(INT fs, const INT stop_freq, const INT noChannels);
99 
100 static INT  numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor);
101 static void CalcBands(INT * diff, INT start , INT stop , INT num_bands);
102 static INT  modifyBands(INT max_band, INT * diff, INT length);
103 static 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 
117 INT
FDKsbrEnc_getSbrStartFreqRAW(INT startFreq,INT QMFbands,INT fs)118 FDKsbrEnc_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  *******************************************************************************/
FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq,INT QMFbands,INT fs)144 INT 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  *******************************************************************************/
169 static INT
getStartFreq(INT fs,const INT start_freq)170 getStartFreq(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
getStopFreq(INT fs,const INT stop_freq,const INT noChannels)252 getStopFreq(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  *******************************************************************************/
329 INT
FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq,const INT noChannels,const INT startFreq,const INT stopFreq,const SR_MODE sampleRateMode,INT * k0,INT * k2)330 FDKsbrEnc_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  *******************************************************************************/
392 INT
FDKsbrEnc_UpdateFreqScale(UCHAR * v_k_master,INT * h_num_bands,const INT k0,const INT k2,const INT freqScale,const INT alterScale)393 FDKsbrEnc_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 
527 static INT
numberOfBands(INT b_p_o,INT start,INT stop,FIXP_DBL warp_factor)528 numberOfBands(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 
539 static void
CalcBands(INT * diff,INT start,INT stop,INT num_bands)540 CalcBands(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 
563 static void
cumSum(INT start_value,INT * diff,INT length,UCHAR * start_adress)564 cumSum(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 
573 static INT
modifyBands(INT max_band_previous,INT * diff,INT length)574 modifyBands(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  *******************************************************************************/
599 INT
FDKsbrEnc_UpdateHiRes(UCHAR * h_hires,INT * num_hires,UCHAR * v_k_master,INT num_master,INT * xover_band,SR_MODE drOrSr,INT noQMFChannels)600 FDKsbrEnc_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  *******************************************************************************/
646 void
FDKsbrEnc_UpdateLoRes(UCHAR * h_lores,INT * num_lores,UCHAR * h_hires,INT num_hires)647 FDKsbrEnc_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