| |
| /* ----------------------------------------------------------------------------------------------------------- |
| Software License for The Fraunhofer FDK AAC Codec Library for Android |
| |
| © Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. |
| All rights reserved. |
| |
| 1. INTRODUCTION |
| The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements |
| the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. |
| This FDK AAC Codec software is intended to be used on a wide variety of Android devices. |
| |
| AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual |
| audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by |
| independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part |
| of the MPEG specifications. |
| |
| Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) |
| may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners |
| individually for the purpose of encoding or decoding bit streams in products that are compliant with |
| the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license |
| these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec |
| software may already be covered under those patent licenses when it is used for those licensed purposes only. |
| |
| Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, |
| are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional |
| applications information and documentation. |
| |
| 2. COPYRIGHT LICENSE |
| |
| Redistribution and use in source and binary forms, with or without modification, are permitted without |
| payment of copyright license fees provided that you satisfy the following conditions: |
| |
| You must retain the complete text of this software license in redistributions of the FDK AAC Codec or |
| your modifications thereto in source code form. |
| |
| You must retain the complete text of this software license in the documentation and/or other materials |
| provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. |
| You must make available free of charge copies of the complete source code of the FDK AAC Codec and your |
| modifications thereto to recipients of copies in binary form. |
| |
| The name of Fraunhofer may not be used to endorse or promote products derived from this library without |
| prior written permission. |
| |
| You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec |
| software or your modifications thereto. |
| |
| Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software |
| and the date of any change. For modified versions of the FDK AAC Codec, the term |
| "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term |
| "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." |
| |
| 3. NO PATENT LICENSE |
| |
| NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, |
| ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with |
| respect to this software. |
| |
| You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized |
| by appropriate patent licenses. |
| |
| 4. DISCLAIMER |
| |
| This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors |
| "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties |
| of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, |
| including but not limited to procurement of substitute goods or services; loss of use, data, or profits, |
| or business interruption, however caused and on any theory of liability, whether in contract, strict |
| liability, or tort (including negligence), arising in any way out of the use of this software, even if |
| advised of the possibility of such damage. |
| |
| 5. CONTACT INFORMATION |
| |
| Fraunhofer Institute for Integrated Circuits IIS |
| Attention: Audio and Multimedia Departments - FDK AAC LL |
| Am Wolfsmantel 33 |
| 91058 Erlangen, Germany |
| |
| www.iis.fraunhofer.de/amm |
| amm-info@iis.fraunhofer.de |
| ----------------------------------------------------------------------------------------------------------- */ |
| |
| /*! |
| \file |
| \brief frequency scale |
| */ |
| |
| #include "sbrenc_freq_sca.h" |
| #include "sbr_misc.h" |
| |
| #include "genericStds.h" |
| |
| /* StartFreq */ |
| static INT getStartFreq(INT fs, const INT start_freq); |
| |
| /* StopFreq */ |
| static INT getStopFreq(INT fs, const INT stop_freq, const INT noChannels); |
| |
| static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor); |
| static void CalcBands(INT * diff, INT start , INT stop , INT num_bands); |
| static INT modifyBands(INT max_band, INT * diff, INT length); |
| static void cumSum(INT start_value, INT* diff, INT length, UCHAR *start_adress); |
| |
| |
| |
| /******************************************************************************* |
| Functionname: FDKsbrEnc_getSbrStartFreqRAW |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| |
| INT |
| FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs) |
| { |
| INT result; |
| |
| if ( startFreq < 0 || startFreq > 15) { |
| return -1; |
| } |
| /* Update startFreq struct */ |
| result = getStartFreq(fs, startFreq); |
| |
| result = (result*fs/QMFbands+1)>>1; |
| |
| return (result); |
| |
| } /* End FDKsbrEnc_getSbrStartFreqRAW */ |
| |
| |
| /******************************************************************************* |
| Functionname: getSbrStopFreq |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs) |
| { |
| INT result; |
| |
| if ( stopFreq < 0 || stopFreq > 13) |
| return -1; |
| |
| |
| /* Uppdate stopFreq struct */ |
| result = getStopFreq( fs, stopFreq, QMFbands); |
| result = (result*fs/QMFbands+1)>>1; |
| |
| return (result); |
| } /* End getSbrStopFreq */ |
| |
| |
| /******************************************************************************* |
| Functionname: getStartFreq |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| static INT |
| getStartFreq(INT fs, const INT start_freq) |
| { |
| INT k0_min; |
| |
| switch(fs){ |
| case 16000: k0_min = 24; |
| break; |
| case 22050: k0_min = 17; |
| break; |
| case 24000: k0_min = 16; |
| break; |
| case 32000: k0_min = 16; |
| break; |
| case 44100: k0_min = 12; |
| break; |
| case 48000: k0_min = 11; |
| break; |
| case 64000: k0_min = 10; |
| break; |
| case 88200: k0_min = 7; |
| break; |
| case 96000: k0_min = 7; |
| break; |
| default: |
| k0_min=11; /* illegal fs */ |
| } |
| |
| |
| switch (fs) { |
| |
| case 16000: |
| { |
| INT v_offset[]= {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; |
| return (k0_min + v_offset[start_freq]); |
| } |
| case 22050: |
| { |
| INT v_offset[]= {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}; |
| return (k0_min + v_offset[start_freq]); |
| } |
| case 24000: |
| { |
| INT v_offset[]= {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; |
| return (k0_min + v_offset[start_freq]); |
| } |
| case 32000: |
| { |
| INT v_offset[]= {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; |
| return (k0_min + v_offset[start_freq]); |
| } |
| case 44100: |
| case 48000: |
| case 64000: |
| { |
| INT v_offset[]= {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}; |
| return (k0_min + v_offset[start_freq]); |
| } |
| case 88200: |
| case 96000: |
| { |
| INT v_offset[]= {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}; |
| return (k0_min + v_offset[start_freq]); |
| } |
| default: |
| { |
| INT v_offset[]= {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33}; |
| return (k0_min + v_offset[start_freq]); |
| } |
| } |
| } /* End getStartFreq */ |
| |
| |
| /******************************************************************************* |
| Functionname: getStopFreq |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| static INT |
| getStopFreq(INT fs, const INT stop_freq, const INT noChannels) |
| { |
| INT result,i; |
| INT k1_min; |
| INT v_dstop[13]; |
| |
| |
| INT *v_stop_freq = NULL; |
| INT v_stop_freq_16[14] = {48,49,50,51,52,54,55,56,57,59,60,61,63,64}; |
| INT v_stop_freq_22[14] = {35,37,38,40,42,44,46,48,51,53,56,58,61,64}; |
| INT v_stop_freq_24[14] = {32,34,36,38,40,42,44,46,49,52,55,58,61,64}; |
| INT v_stop_freq_32[14] = {32,34,36,38,40,42,44,46,49,52,55,58,61,64}; |
| INT v_stop_freq_44[14] = {23,25,27,29,32,34,37,40,43,47,51,55,59,64}; |
| INT v_stop_freq_48[14] = {21,23,25,27,30,32,35,38,42,45,49,54,59,64}; |
| INT v_stop_freq_64[14] = {20,22,24,26,29,31,34,37,41,45,49,54,59,64}; |
| INT v_stop_freq_88[14] = {15,17,19,21,23,26,29,33,37,41,46,51,57,64}; |
| INT v_stop_freq_96[14] = {13,15,17,19,21,24,27,31,35,39,44,50,57,64}; |
| |
| switch(fs){ |
| case 16000: k1_min = 48; |
| v_stop_freq =v_stop_freq_16; |
| break; |
| case 22050: k1_min = 35; |
| v_stop_freq =v_stop_freq_22; |
| break; |
| case 24000: k1_min = 32; |
| v_stop_freq =v_stop_freq_24; |
| break; |
| case 32000: k1_min = 32; |
| v_stop_freq =v_stop_freq_32; |
| break; |
| case 44100: k1_min = 23; |
| v_stop_freq =v_stop_freq_44; |
| break; |
| case 48000: k1_min = 21; |
| v_stop_freq =v_stop_freq_48; |
| break; |
| case 64000: k1_min = 20; |
| v_stop_freq =v_stop_freq_64; |
| break; |
| case 88200: k1_min = 15; |
| v_stop_freq =v_stop_freq_88; |
| break; |
| case 96000: k1_min = 13; |
| v_stop_freq =v_stop_freq_96; |
| break; |
| default: |
| k1_min = 21; /* illegal fs */ |
| } |
| |
| |
| /* Ensure increasing bandwidth */ |
| for(i = 0; i <= 12; i++) { |
| v_dstop[i] = v_stop_freq[i+1] - v_stop_freq[i]; |
| } |
| |
| FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */ |
| |
| result = k1_min; |
| for(i = 0; i < stop_freq; i++) { |
| result = result + v_dstop[i]; |
| } |
| |
| return(result); |
| |
| }/* End getStopFreq */ |
| |
| |
| /******************************************************************************* |
| Functionname: FDKsbrEnc_FindStartAndStopBand |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| INT |
| FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, |
| const INT noChannels, |
| const INT startFreq, |
| const INT stopFreq, |
| const SR_MODE sampleRateMode, |
| INT *k0, |
| INT *k2) |
| { |
| |
| /* Update startFreq struct */ |
| *k0 = getStartFreq(samplingFreq, startFreq); |
| |
| /* Test if start freq is outside corecoder range */ |
| if( ( sampleRateMode == 1 ) && |
| ( samplingFreq*noChannels < |
| 2**k0 * samplingFreq) ) { |
| return (1); /* raise the cross-over frequency and/or lower the number |
| of target bands per octave (or lower the sampling frequency) */ |
| } |
| |
| /*Update stopFreq struct */ |
| if ( stopFreq < 14 ) { |
| *k2 = getStopFreq(samplingFreq, stopFreq, noChannels); |
| } else if( stopFreq == 14 ) { |
| *k2 = 2 * *k0; |
| } else { |
| *k2 = 3 * *k0; |
| } |
| |
| /* limit to Nyqvist */ |
| if (*k2 > noChannels) { |
| *k2 = noChannels; |
| } |
| |
| |
| |
| /* Test for invalid k0 k2 combinations */ |
| if ( (samplingFreq == 44100) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS44100 ) ) |
| return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs=44.1kHz */ |
| |
| if ( (samplingFreq >= 48000) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS48000 ) ) |
| return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs>=48kHz */ |
| |
| if ((*k2 - *k0) > MAX_FREQ_COEFFS) |
| return (1);/*Number of bands exceeds valid range of MAX_FREQ_COEFFS */ |
| |
| if ((*k2 - *k0) < 0) |
| return (1);/* Number of bands is negative */ |
| |
| |
| return(0); |
| } |
| |
| /******************************************************************************* |
| Functionname: FDKsbrEnc_UpdateFreqScale |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| INT |
| FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, |
| const INT k0, const INT k2, |
| const INT freqScale, |
| const INT alterScale) |
| |
| { |
| |
| INT b_p_o = 0; /* bands_per_octave */ |
| FIXP_DBL warp = FL2FXCONST_DBL(0.0f); |
| INT dk = 0; |
| |
| /* Internal variables */ |
| INT k1 = 0, i; |
| INT num_bands0; |
| INT num_bands1; |
| INT diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; |
| INT *diff0 = diff_tot; |
| INT *diff1 = diff_tot+MAX_OCTAVE; |
| INT k2_achived; |
| INT k2_diff; |
| INT incr = 0; |
| |
| /* Init */ |
| if (freqScale==1) b_p_o = 12; |
| if (freqScale==2) b_p_o = 10; |
| if (freqScale==3) b_p_o = 8; |
| |
| |
| if(freqScale > 0) /*Bark*/ |
| { |
| if(alterScale==0) |
| warp = FL2FXCONST_DBL(0.5f); /* 1.0/(1.0*2.0) */ |
| else |
| warp = FL2FXCONST_DBL(1.0f/2.6f); /* 1.0/(1.3*2.0); */ |
| |
| |
| if(4*k2 >= 9*k0) /*two or more regions*/ |
| { |
| k1=2*k0; |
| |
| num_bands0=numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); |
| num_bands1=numberOfBands(b_p_o, k1, k2, warp); |
| |
| CalcBands(diff0, k0, k1, num_bands0);/*CalcBands1 => diff0 */ |
| FDKsbrEnc_Shellsort_int( diff0, num_bands0);/*SortBands sort diff0 */ |
| |
| if (diff0[0] == 0) /* too wide FB bands for target tuning */ |
| { |
| return (1);/* raise the cross-over frequency and/or lower the number |
| of target bands per octave (or lower the sampling frequency */ |
| } |
| |
| cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */ |
| |
| CalcBands(diff1, k1, k2, num_bands1); /* CalcBands2 => diff1 */ |
| FDKsbrEnc_Shellsort_int( diff1, num_bands1); /* SortBands sort diff1 */ |
| if(diff0[num_bands0-1] > diff1[0]) /* max(1) > min(2) */ |
| { |
| if(modifyBands(diff0[num_bands0-1],diff1, num_bands1)) |
| return(1); |
| } |
| |
| /* Add 2'nd region */ |
| cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]); |
| *h_num_bands=num_bands0+num_bands1; /* Output nr of bands */ |
| |
| } |
| else /* one region */ |
| { |
| k1=k2; |
| |
| num_bands0=numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); |
| CalcBands(diff0, k0, k1, num_bands0);/* CalcBands1 => diff0 */ |
| FDKsbrEnc_Shellsort_int( diff0, num_bands0); /* SortBands sort diff0 */ |
| |
| if (diff0[0] == 0) /* too wide FB bands for target tuning */ |
| { |
| return (1); /* raise the cross-over frequency and/or lower the number |
| of target bands per octave (or lower the sampling frequency */ |
| } |
| |
| cumSum(k0, diff0, num_bands0, v_k_master);/* cumsum */ |
| *h_num_bands=num_bands0; /* Output nr of bands */ |
| |
| } |
| } |
| else /* Linear mode */ |
| { |
| if (alterScale==0) { |
| dk = 1; |
| num_bands0 = 2 * ((k2 - k0)/2); /* FLOOR to get to few number of bands*/ |
| } else { |
| dk = 2; |
| num_bands0 = 2 * (((k2 - k0)/dk +1)/2); /* ROUND to get closest fit */ |
| } |
| |
| k2_achived = k0 + num_bands0*dk; |
| k2_diff = k2 - k2_achived; |
| |
| for(i=0;i<num_bands0;i++) |
| diff_tot[i] = dk; |
| |
| /* If linear scale wasn't achived */ |
| /* and we got wide SBR are */ |
| if (k2_diff < 0) { |
| incr = 1; |
| i = 0; |
| } |
| |
| /* If linear scale wasn't achived */ |
| /* and we got small SBR are */ |
| if (k2_diff > 0) { |
| incr = -1; |
| i = num_bands0-1; |
| } |
| |
| /* Adjust diff vector to get sepc. SBR range */ |
| while (k2_diff != 0) { |
| diff_tot[i] = diff_tot[i] - incr; |
| i = i + incr; |
| k2_diff = k2_diff + incr; |
| } |
| |
| cumSum(k0, diff_tot, num_bands0, v_k_master);/* cumsum */ |
| *h_num_bands=num_bands0; /* Output nr of bands */ |
| |
| } |
| |
| if (*h_num_bands < 1) |
| return(1); /*To small sbr area */ |
| |
| return (0); |
| }/* End FDKsbrEnc_UpdateFreqScale */ |
| |
| static INT |
| numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor) |
| { |
| INT result=0; |
| /* result = 2* (INT) ( (double)b_p_o * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) * (double)FX_DBL2FL(warp_factor) + 0.5); */ |
| result = ( ( b_p_o * fMult( (CalcLdInt(stop) - CalcLdInt(start)), warp_factor) + (FL2FX_DBL(0.5f)>>LD_DATA_SHIFT) |
| ) >> ((DFRACT_BITS-1)-LD_DATA_SHIFT) ) << 1; /* do not optimize anymore (rounding!!) */ |
| |
| return(result); |
| } |
| |
| |
| static void |
| CalcBands(INT * diff, INT start , INT stop , INT num_bands) |
| { |
| INT i, qb, qe, qtmp; |
| INT previous; |
| INT current; |
| FIXP_DBL base, exp, tmp; |
| |
| previous=start; |
| for(i=1; i<= num_bands; i++) |
| { |
| base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb); |
| exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe); |
| tmp = fPow(base, qb, exp, qe, &qtmp); |
| tmp = fMult(tmp, (FIXP_DBL)(start<<24)); |
| current = (INT)scaleValue(tmp, qtmp-23); |
| current = (current+1) >> 1; /* rounding*/ |
| diff[i-1] = current-previous; |
| previous = current; |
| } |
| |
| }/* End CalcBands */ |
| |
| |
| static void |
| cumSum(INT start_value, INT* diff, INT length, UCHAR *start_adress) |
| { |
| INT i; |
| start_adress[0]=start_value; |
| for(i=1;i<=length;i++) |
| start_adress[i]=start_adress[i-1]+diff[i-1]; |
| } /* End cumSum */ |
| |
| |
| static INT |
| modifyBands(INT max_band_previous, INT * diff, INT length) |
| { |
| INT change=max_band_previous-diff[0]; |
| |
| /* Limit the change so that the last band cannot get narrower than the first one */ |
| if ( change > (diff[length-1] - diff[0]) / 2 ) |
| change = (diff[length-1] - diff[0]) / 2; |
| |
| diff[0] += change; |
| diff[length-1] -= change; |
| FDKsbrEnc_Shellsort_int(diff, length); |
| |
| return(0); |
| }/* End modifyBands */ |
| |
| |
| /******************************************************************************* |
| Functionname: FDKsbrEnc_UpdateHiRes |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| INT |
| FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires,UCHAR * v_k_master, |
| INT num_master , INT *xover_band, SR_MODE drOrSr, |
| INT noQMFChannels) |
| { |
| INT i; |
| INT divider; |
| INT max1,max2; |
| |
| /* Check if we use a Dual rate => diver=2 else 1 */ |
| divider = (drOrSr == DUAL_RATE) ? 2 : 1; |
| |
| if( (v_k_master[*xover_band] > (noQMFChannels/divider) ) || |
| ( *xover_band > num_master ) ) { |
| /* xover_band error, too big for this startFreq. Will be clipped */ |
| |
| /* Calculate maximum value for xover_band */ |
| max1=0; |
| max2=num_master; |
| while( (v_k_master[max1+1] < (noQMFChannels/divider)) && |
| ( (max1+1) < max2) ) |
| { |
| max1++; |
| } |
| |
| *xover_band=max1; |
| } |
| |
| *num_hires = num_master - *xover_band; |
| for(i = *xover_band; i <= num_master; i++) |
| { |
| h_hires[i - *xover_band] = v_k_master[i]; |
| } |
| |
| return (0); |
| }/* End FDKsbrEnc_UpdateHiRes */ |
| |
| |
| /******************************************************************************* |
| Functionname: FDKsbrEnc_UpdateLoRes |
| ******************************************************************************* |
| Description: |
| |
| Arguments: |
| |
| Return: |
| *******************************************************************************/ |
| void |
| FDKsbrEnc_UpdateLoRes(UCHAR * h_lores, INT *num_lores, UCHAR * h_hires, INT num_hires) |
| { |
| INT i; |
| |
| if(num_hires%2 == 0) /* if even number of hires bands */ |
| { |
| *num_lores=num_hires/2; |
| /* Use every second lores=hires[0,2,4...] */ |
| for(i=0;i<=*num_lores;i++) |
| h_lores[i]=h_hires[i*2]; |
| |
| } |
| else /* odd number of hires which means xover is odd */ |
| { |
| *num_lores=(num_hires+1)/2; |
| |
| /* Use lores=hires[0,1,3,5 ...] */ |
| h_lores[0]=h_hires[0]; |
| for(i=1;i<=*num_lores;i++) |
| { |
| h_lores[i]=h_hires[i*2-1]; |
| } |
| } |
| |
| }/* End FDKsbrEnc_UpdateLoRes */ |