| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 | 
							- /* ***** BEGIN LICENSE BLOCK *****  
 
-  * Source last modified: $Id: sbrfreq.c,v 1.2 2005/05/20 18:05:41 jrecker Exp $ 
 
-  *   
 
-  * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.  
 
-  *       
 
-  * The contents of this file, and the files included with this file, 
 
-  * are subject to the current version of the RealNetworks Public 
 
-  * Source License (the "RPSL") available at 
 
-  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 
-  * the file under the current version of the RealNetworks Community 
 
-  * Source License (the "RCSL") available at 
 
-  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL 
 
-  * will apply. You may also obtain the license terms directly from 
 
-  * RealNetworks.  You may not use this file except in compliance with 
 
-  * the RPSL or, if you have a valid RCSL with RealNetworks applicable 
 
-  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for 
 
-  * the rights, obligations and limitations governing use of the 
 
-  * contents of the file. 
 
-  *   
 
-  * This file is part of the Helix DNA Technology. RealNetworks is the 
 
-  * developer of the Original Code and owns the copyrights in the 
 
-  * portions it created. 
 
-  *   
 
-  * This file, and the files included with this file, is distributed 
 
-  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY 
 
-  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS 
 
-  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES 
 
-  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET 
 
-  * ENJOYMENT OR NON-INFRINGEMENT. 
 
-  *  
 
-  * Technology Compatibility Kit Test Suite(s) Location:  
 
-  *    http://www.helixcommunity.org/content/tck  
 
-  *  
 
-  * Contributor(s):  
 
-  *   
 
-  * ***** END LICENSE BLOCK ***** */  
 
- /**************************************************************************************
 
-  * Fixed-point HE-AAC decoder
 
-  * Jon Recker (jrecker@real.com)
 
-  * February 2005
 
-  *
 
-  * sbrfreq.c - frequency band table calculation for SBR
 
-  **************************************************************************************/
 
- #include "sbr.h"
 
- #include "assembly.h"
 
- /**************************************************************************************
 
-  * Function:    BubbleSort
 
-  *
 
-  * Description: in-place sort of unsigned chars
 
-  *
 
-  * Inputs:      buffer of elements to sort
 
-  *              number of elements to sort
 
-  *
 
-  * Outputs:     sorted buffer
 
-  *
 
-  * Return:      none
 
-  **************************************************************************************/
 
- static void BubbleSort(unsigned char *v, int nItems)
 
- {
 
- 	int i;
 
- 	unsigned char t;
 
- 	while (nItems >= 2) {
 
- 		for (i = 0; i < nItems-1; i++) {
 
- 			if (v[i+1] < v[i]) {
 
- 				t = v[i+1];	
 
- 				v[i+1] = v[i];	
 
- 				v[i] = t;
 
- 			}
 
- 		}
 
- 		nItems--;
 
- 	}
 
- }
 
- /**************************************************************************************
 
-  * Function:    VMin
 
-  *
 
-  * Description: find smallest element in a buffer of unsigned chars
 
-  *
 
-  * Inputs:      buffer of elements to search
 
-  *              number of elements to search
 
-  *
 
-  * Outputs:     none
 
-  *
 
-  * Return:      smallest element in buffer
 
-  **************************************************************************************/
 
- static unsigned char VMin(unsigned char *v, int nItems)
 
- {
 
- 	int i;
 
- 	unsigned char vMin;
 
- 	vMin = v[0];
 
- 	for (i = 1; i < nItems; i++) {
 
- 		if (v[i] < vMin)
 
- 			vMin = v[i];
 
- 	}
 
- 	return vMin;
 
- }
 
- /**************************************************************************************
 
-  * Function:    VMax
 
-  *
 
-  * Description: find largest element in a buffer of unsigned chars
 
-  *
 
-  * Inputs:      buffer of elements to search
 
-  *              number of elements to search
 
-  *
 
-  * Outputs:     none
 
-  *
 
-  * Return:      largest element in buffer
 
-  **************************************************************************************/
 
- static unsigned char VMax(unsigned char *v, int nItems)
 
- {
 
- 	int i;
 
- 	unsigned char vMax;
 
- 	vMax = v[0];
 
- 	for (i = 1; i < nItems; i++) {
 
- 		if (v[i] > vMax)
 
- 			vMax = v[i];
 
- 	}
 
- 	return vMax;
 
- }
 
- /**************************************************************************************
 
-  * Function:    CalcFreqMasterScaleZero
 
-  *
 
-  * Description: calculate master frequency table when freqScale == 0 
 
-  *                (4.6.18.3.2.1, figure 4.39)
 
-  *
 
-  * Inputs:      alterScale flag
 
-  *              index of first QMF subband in master freq table (k0)
 
-  *              index of last QMF subband (k2)
 
-  *
 
-  * Outputs:     master frequency table
 
-  *
 
-  * Return:      number of bands in master frequency table
 
-  *
 
-  * Notes:       assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6)
 
-  **************************************************************************************/
 
- static int CalcFreqMasterScaleZero(unsigned char *freqMaster, int alterScale, int k0, int k2)
 
- {
 
- 	int nMaster, k, nBands, k2Achieved, dk, vDk[64], k2Diff;
 
- 	if (alterScale) {
 
- 		dk = 2;
 
- 		nBands = 2 * ((k2 - k0 + 2) >> 2);
 
- 	} else {
 
- 		dk = 1;
 
- 		nBands = 2 * ((k2 - k0) >> 1);
 
- 	}
 
- 	if (nBands <= 0)
 
- 		return 0;
 
- 	k2Achieved = k0 + nBands * dk;
 
- 	k2Diff = k2 - k2Achieved;
 
- 	for (k = 0; k < nBands; k++)
 
- 		vDk[k] = dk;
 
- 	if (k2Diff > 0) {
 
- 		k = nBands - 1;
 
- 		while (k2Diff) {
 
- 			vDk[k]++;
 
- 			k--;
 
- 			k2Diff--;
 
- 		}
 
- 	} else if (k2Diff < 0) {
 
- 		k = 0;
 
- 		while (k2Diff) {
 
- 			vDk[k]--;
 
- 			k++;
 
- 			k2Diff++;
 
- 		}
 
- 	}
 
- 	nMaster = nBands;
 
- 	freqMaster[0] = k0;
 
- 	for (k = 1; k <= nBands; k++)
 
- 		freqMaster[k] = freqMaster[k-1] + vDk[k-1];
 
- 	return nMaster;
 
- }
 
- /* mBandTab[i] = temp1[i] / 2 */
 
- static const int mBandTab[3] PROGMEM = {6, 5, 4};
 
- /* invWarpTab[i] = 1.0 / temp2[i], Q30 (see 4.6.18.3.2.1) */
 
- static const int invWarpTab[2] PROGMEM = {0x40000000, 0x313b13b1};
 
- /**************************************************************************************
 
-  * Function:    CalcFreqMasterScale
 
-  *
 
-  * Description: calculate master frequency table when freqScale > 0 
 
-  *                (4.6.18.3.2.1, figure 4.39)
 
-  *
 
-  * Inputs:      alterScale flag
 
-  *              freqScale flag
 
-  *              index of first QMF subband in master freq table (k0)
 
-  *              index of last QMF subband (k2)
 
-  *
 
-  * Outputs:     master frequency table
 
-  *
 
-  * Return:      number of bands in master frequency table
 
-  *
 
-  * Notes:       assumes k2 - k0 <= 48 and k2 >= k0 (4.6.18.3.6)
 
-  **************************************************************************************/
 
- static int CalcFreqMaster(unsigned char *freqMaster, int freqScale, int alterScale, int k0, int k2)
 
- {
 
- 	int bands, twoRegions, k, k1, t, vLast, vCurr, pCurr;
 
- 	int invWarp, nBands0, nBands1, change;
 
- 	unsigned char vDk1Min, vDk0Max;
 
- 	unsigned char *vDelta;
 
- 	if (freqScale < 1 || freqScale > 3)
 
- 		return -1;
 
- 	bands = mBandTab[freqScale - 1];
 
- 	invWarp = invWarpTab[alterScale];
 
- 	/* tested for all k0 = [5, 64], k2 = [k0, 64] */
 
- 	if (k2*10000 > 22449*k0) {
 
- 		twoRegions = 1;
 
- 		k1 = 2*k0;
 
- 	} else {
 
- 		twoRegions = 0;
 
- 		k1 = k2;
 
- 	}
 
- 	
 
- 	/* tested for all k0 = [5, 64], k1 = [k0, 64], freqScale = [1,3] */
 
- 	t = (log2Tab[k1] - log2Tab[k0]) >> 3;				/* log2(k1/k0), Q28 to Q25 */
 
- 	nBands0 = 2 * (((bands * t) + (1 << 24)) >> 25);	/* multiply by bands/2, round to nearest int (mBandTab has factor of 1/2 rolled in) */
 
- 	/* tested for all valid combinations of k0, k1, nBands (from sampRate, freqScale, alterScale) 
 
- 	 * roundoff error can be a problem with fixpt (e.g. pCurr = 12.499999 instead of 12.50003)
 
- 	 *   because successive multiplication always undershoots a little bit, but this
 
- 	 *   doesn't occur in any of the ratios we encounter from the valid k0/k1 bands in the spec
 
- 	 */
 
- 	t = RatioPowInv(k1, k0, nBands0);
 
- 	pCurr = k0 << 24;
 
- 	vLast = k0;
 
- 	vDelta = freqMaster + 1;	/* operate in-place */
 
- 	for (k = 0; k < nBands0; k++) {
 
- 		pCurr = MULSHIFT32(pCurr, t) << 8;	/* keep in Q24 */
 
- 		vCurr = (pCurr + (1 << 23)) >> 24;
 
- 		vDelta[k] = (vCurr - vLast);
 
- 		vLast = vCurr;
 
- 	}
 
- 	/* sort the deltas and find max delta for first region */
 
- 	BubbleSort(vDelta, nBands0);
 
- 	vDk0Max = VMax(vDelta, nBands0);
 
- 	/* fill master frequency table with bands from first region */
 
- 	freqMaster[0] = k0;
 
- 	for (k = 1; k <= nBands0; k++)
 
- 		freqMaster[k] += freqMaster[k-1];
 
- 	/* if only one region, then the table is complete */
 
- 	if (!twoRegions)
 
- 		return nBands0;
 
- 	/* tested for all k1 = [10, 64], k2 = [k0, 64], freqScale = [1,3] */
 
- 	t = (log2Tab[k2] - log2Tab[k1]) >> 3;		/* log2(k1/k0), Q28 to Q25 */
 
- 	t = MULSHIFT32(bands * t, invWarp) << 2;	/* multiply by bands/2, divide by warp factor, keep Q25 */
 
- 	nBands1 = 2 * ((t + (1 << 24)) >> 25);		/* round to nearest int */
 
- 				
 
- 	/* see comments above for calculations in first region */
 
- 	t = RatioPowInv(k2, k1, nBands1);
 
- 	pCurr = k1 << 24;
 
- 	vLast = k1;
 
- 	vDelta = freqMaster + nBands0 + 1;	/* operate in-place */
 
- 	for (k = 0; k < nBands1; k++) {
 
- 		pCurr = MULSHIFT32(pCurr, t) << 8;	/* keep in Q24 */
 
- 		vCurr = (pCurr + (1 << 23)) >> 24;
 
- 		vDelta[k] = (vCurr - vLast);
 
- 		vLast = vCurr;
 
- 	}
 
- 	/* sort the deltas, adjusting first and last if the second region has smaller deltas than the first */
 
- 	vDk1Min = VMin(vDelta, nBands1);
 
- 	if (vDk1Min < vDk0Max) {
 
- 		BubbleSort(vDelta, nBands1);
 
- 		change = vDk0Max - vDelta[0];
 
- 		if (change > ((vDelta[nBands1 - 1] - vDelta[0]) >> 1))
 
- 			 change = ((vDelta[nBands1 - 1] - vDelta[0]) >> 1);
 
- 		vDelta[0] += change;
 
- 		vDelta[nBands1-1] -= change;
 
- 	}
 
- 	BubbleSort(vDelta, nBands1);
 
- 	/* fill master frequency table with bands from second region 
 
- 	 * Note: freqMaster[nBands0] = k1
 
- 	 */
 
- 	for (k = 1; k <= nBands1; k++)
 
- 		freqMaster[k + nBands0] += freqMaster[k + nBands0 - 1];
 
- 	return (nBands0 + nBands1);
 
- }
 
- /**************************************************************************************
 
-  * Function:    CalcFreqHigh
 
-  *
 
-  * Description: calculate high resolution frequency table (4.6.18.3.2.2)
 
-  *
 
-  * Inputs:      master frequency table
 
-  *              number of bands in master frequency table 
 
-  *              crossover band from header
 
-  *
 
-  * Outputs:     high resolution frequency table
 
-  *
 
-  * Return:      number of bands in high resolution frequency table
 
-  **************************************************************************************/
 
- static int CalcFreqHigh(unsigned char *freqHigh, unsigned char *freqMaster, int nMaster, int crossOverBand)
 
- {
 
- 	int k, nHigh;
 
- 	nHigh = nMaster - crossOverBand;
 
- 	for (k = 0; k <= nHigh; k++)
 
- 		freqHigh[k] = freqMaster[k + crossOverBand];
 
- 	
 
- 	return nHigh;
 
- }
 
- /**************************************************************************************
 
-  * Function:    CalcFreqLow
 
-  *
 
-  * Description: calculate low resolution frequency table (4.6.18.3.2.2)
 
-  *
 
-  * Inputs:      high resolution frequency table
 
-  *              number of bands in high resolution frequency table 
 
-  *
 
-  * Outputs:     low resolution frequency table
 
-  *
 
-  * Return:      number of bands in low resolution frequency table
 
-  **************************************************************************************/
 
- static int CalcFreqLow(unsigned char *freqLow, unsigned char *freqHigh, int nHigh)
 
- {
 
- 	int k, nLow, oddFlag;
 
- 	nLow = nHigh - (nHigh >> 1);
 
- 	freqLow[0] = freqHigh[0];
 
- 	oddFlag = nHigh & 0x01;
 
- 	for (k = 1; k <= nLow; k++)
 
- 		freqLow[k] = freqHigh[2*k - oddFlag];
 
- 	return nLow;
 
- }
 
- /**************************************************************************************
 
-  * Function:    CalcFreqNoise
 
-  *
 
-  * Description: calculate noise floor frequency table (4.6.18.3.2.2)
 
-  *
 
-  * Inputs:      low resolution frequency table
 
-  *              number of bands in low resolution frequency table
 
-  *              index of starting QMF subband for SBR (kStart)
 
-  *              index of last QMF subband (k2)
 
-  *              number of noise bands
 
-  *
 
-  * Outputs:     noise floor frequency table
 
-  *
 
-  * Return:      number of bands in noise floor frequency table
 
-  **************************************************************************************/
 
- static int CalcFreqNoise(unsigned char *freqNoise, unsigned char *freqLow, int nLow, int kStart, int k2, int noiseBands)
 
- {
 
- 	int i, iLast, k, nQ, lTop, lBottom;
 
- 	lTop = log2Tab[k2];
 
- 	lBottom = log2Tab[kStart];
 
- 	nQ = noiseBands*((lTop - lBottom) >> 2);	/* Q28 to Q26, noiseBands = [0,3] */
 
- 	nQ = (nQ + (1 << 25)) >> 26;
 
- 	if (nQ < 1)
 
- 		nQ = 1;
 
- 	ASSERT(nQ <= MAX_NUM_NOISE_FLOOR_BANDS);	/* required from 4.6.18.3.6 */
 
- 	iLast = 0;
 
- 	freqNoise[0] = freqLow[0];
 
- 	for (k = 1; k <= nQ; k++) {
 
- 		i = iLast + (nLow - iLast) / (nQ + 1 - k);	/* truncating division */
 
- 		freqNoise[k] = freqLow[i];
 
- 		iLast = i;
 
- 	}
 
- 	return nQ;
 
- }
 
- /**************************************************************************************
 
-  * Function:    BuildPatches
 
-  *
 
-  * Description: build high frequency patches (4.6.18.6.3)
 
-  *
 
-  * Inputs:      master frequency table
 
-  *              number of bands in low resolution frequency table
 
-  *              index of first QMF subband in master freq table (k0)
 
-  *              index of starting QMF subband for SBR (kStart)
 
-  *              number of QMF bands in high resolution frequency table
 
-  *              sample rate index
 
-  *
 
-  * Outputs:     starting subband for each patch
 
-  *              number of subbands in each patch
 
-  *
 
-  * Return:      number of patches
 
-  **************************************************************************************/
 
- static int BuildPatches(unsigned char *patchNumSubbands, unsigned char *patchStartSubband, unsigned char *freqMaster, 
 
- 						int nMaster, int k0, int kStart, int numQMFBands, int sampRateIdx)
 
- {
 
- 	int i, j, k;
 
- 	int msb, sb, usb, numPatches, goalSB, oddFlag;
 
- 	msb = k0;
 
- 	usb = kStart;
 
- 	numPatches = 0;
 
- 	goalSB = goalSBTab[sampRateIdx];
 
- 	if (nMaster == 0) {
 
- 		patchNumSubbands[0] = 0;
 
- 		patchStartSubband[0] = 0;
 
- 		return 0;
 
- 	}
 
- 	if (goalSB < kStart + numQMFBands) {
 
- 		k = 0;
 
- 		for (i = 0; freqMaster[i] < goalSB; i++)
 
- 			k = i+1;
 
- 	} else {
 
- 		k = nMaster;
 
- 	}
 
- 	do {
 
- 		j = k+1;
 
- 		do {
 
- 			j--;
 
- 			sb = freqMaster[j];
 
- 			oddFlag = (sb - 2 + k0) & 0x01;
 
- 		} while (sb > k0 - 1 + msb - oddFlag);
 
- 		patchNumSubbands[numPatches] = MAX(sb - usb, 0);
 
- 		patchStartSubband[numPatches] = k0 - oddFlag - patchNumSubbands[numPatches];
 
- 		/* from MPEG reference code - slightly different from spec */
 
- 		if ((patchNumSubbands[numPatches] < 3) && (numPatches > 0))
 
- 			break;
 
- 		if (patchNumSubbands[numPatches] > 0) {
 
- 			usb = sb;
 
- 			msb = sb;
 
- 			numPatches++;
 
- 		} else {
 
- 			msb = kStart;
 
- 		}
 
- 		if (freqMaster[k] - sb < 3)
 
- 			k = nMaster;
 
- 	} while (sb != (kStart + numQMFBands) && numPatches <= MAX_NUM_PATCHES);
 
- 	return numPatches;
 
- }
 
- /**************************************************************************************
 
-  * Function:    FindFreq
 
-  *
 
-  * Description: search buffer of unsigned chars for a specific value
 
-  *
 
-  * Inputs:      buffer of elements to search
 
-  *              number of elements to search
 
-  *              value to search for
 
-  *
 
-  * Outputs:     none
 
-  *
 
-  * Return:      non-zero if the value is found anywhere in the buffer, zero otherwise
 
-  **************************************************************************************/
 
- static int FindFreq(unsigned char *freq, int nFreq, unsigned char val)
 
- {
 
- 	int k;
 
- 	for (k = 0; k < nFreq; k++) {
 
- 		if (freq[k] == val)
 
- 			return 1;
 
- 	}
 
- 	return 0;
 
- }
 
- /**************************************************************************************
 
-  * Function:    RemoveFreq
 
-  *
 
-  * Description: remove one element from a buffer of unsigned chars
 
-  *
 
-  * Inputs:      buffer of elements
 
-  *              number of elements
 
-  *              index of element to remove
 
-  *
 
-  * Outputs:     new buffer of length nFreq-1
 
-  *
 
-  * Return:      none
 
-  **************************************************************************************/
 
- static void RemoveFreq(unsigned char *freq, int nFreq, int removeIdx)
 
- {
 
- 	int k;
 
- 	if (removeIdx >= nFreq)
 
- 		return;
 
- 	for (k = removeIdx; k < nFreq - 1; k++)
 
- 		freq[k] = freq[k+1];
 
- }
 
- /**************************************************************************************
 
-  * Function:    CalcFreqLimiter
 
-  *
 
-  * Description: calculate limiter frequency table (4.6.18.3.2.3)
 
-  *
 
-  * Inputs:      number of subbands in each patch
 
-  *              low resolution frequency table
 
-  *              number of bands in low resolution frequency table
 
-  *              index of starting QMF subband for SBR (kStart)
 
-  *              number of limiter bands
 
-  *              number of patches
 
-  *
 
-  * Outputs:     limiter frequency table
 
-  *
 
-  * Return:      number of bands in limiter frequency table
 
-  **************************************************************************************/
 
- static int CalcFreqLimiter(unsigned char *freqLimiter, unsigned char *patchNumSubbands, unsigned char *freqLow, 
 
- 						   int nLow, int kStart, int limiterBands, int numPatches)
 
- {
 
- 	int k, bands, nLimiter, nOctaves;
 
- 	int limBandsPerOctave[3] = {120, 200, 300};		/* [1.2, 2.0, 3.0] * 100 */
 
- 	unsigned char patchBorders[MAX_NUM_PATCHES + 1];
 
- 	/* simple case */
 
- 	if (limiterBands == 0) {
 
- 		freqLimiter[0] = freqLow[0] - kStart;
 
- 		freqLimiter[1] = freqLow[nLow] - kStart;
 
- 		return 1;
 
- 	}
 
- 	bands = limBandsPerOctave[limiterBands - 1];
 
- 	patchBorders[0] = kStart;
 
- 	/* from MPEG reference code - slightly different from spec (top border) */
 
- 	for (k = 1; k < numPatches; k++)
 
- 		patchBorders[k] = patchBorders[k-1] + patchNumSubbands[k-1];
 
- 	patchBorders[k] = freqLow[nLow];
 
- 	for (k = 0; k <= nLow; k++)
 
- 		freqLimiter[k] = freqLow[k];
 
- 	for (k = 1; k < numPatches; k++)
 
- 		freqLimiter[k+nLow] = patchBorders[k];
 
- 	k = 1;
 
- 	nLimiter = nLow + numPatches - 1;
 
- 	BubbleSort(freqLimiter, nLimiter + 1);
 
- 	while (k <= nLimiter) {
 
- 		nOctaves = log2Tab[freqLimiter[k]] - log2Tab[freqLimiter[k-1]];	/* Q28 */
 
- 		nOctaves = (nOctaves >> 9) * bands;	/* Q19, max bands = 300 < 2^9 */
 
- 		if (nOctaves < (49 << 19)) {		/* compare with 0.49*100, in Q19 */
 
- 			if (freqLimiter[k] == freqLimiter[k-1] || FindFreq(patchBorders, numPatches + 1, freqLimiter[k]) == 0) {
 
- 				RemoveFreq(freqLimiter, nLimiter + 1, k);
 
- 				nLimiter--;
 
- 			} else if (FindFreq(patchBorders, numPatches + 1, freqLimiter[k-1]) == 0) {
 
- 				RemoveFreq(freqLimiter, nLimiter + 1, k-1);
 
- 				nLimiter--;
 
- 			} else {
 
- 				k++;
 
- 			}
 
- 		} else {
 
- 			k++;
 
- 		}
 
- 	}
 
- 	/* store limiter boundaries as offsets from kStart */
 
- 	for (k = 0; k <= nLimiter; k++)
 
- 		freqLimiter[k] -= kStart;
 
- 	return nLimiter;
 
- }
 
- /**************************************************************************************
 
-  * Function:    CalcFreqTables
 
-  *
 
-  * Description: calulate master and derived frequency tables, and patches
 
-  *
 
-  * Inputs:      initialized SBRHeader struct for this SCE/CPE block
 
-  *              initialized SBRFreq struct for this SCE/CPE block
 
-  *              sample rate index of output sample rate (after SBR)
 
-  *
 
-  * Outputs:     master and derived frequency tables, and patches
 
-  *
 
-  * Return:      non-zero if error, zero otherwise
 
-  **************************************************************************************/
 
- int CalcFreqTables(SBRHeader *sbrHdr, SBRFreq *sbrFreq, int sampRateIdx)
 
- {
 
- 	int k0, k2;
 
- 	k0 = k0Tab[sampRateIdx][sbrHdr->startFreq];
 
- 	if (sbrHdr->stopFreq == 14)
 
- 		k2 = 2*k0;
 
- 	else if (sbrHdr->stopFreq == 15)
 
- 		k2 = 3*k0;
 
- 	else
 
- 		k2 = k2Tab[sampRateIdx][sbrHdr->stopFreq];
 
- 	if (k2 > 64)
 
- 		k2 = 64;
 
- 	/* calculate master frequency table */
 
- 	if (sbrHdr->freqScale == 0)
 
- 		sbrFreq->nMaster = CalcFreqMasterScaleZero(sbrFreq->freqMaster, sbrHdr->alterScale, k0, k2);
 
- 	else
 
- 		sbrFreq->nMaster = CalcFreqMaster(sbrFreq->freqMaster, sbrHdr->freqScale, sbrHdr->alterScale, k0, k2);
 
- 	/* calculate high frequency table and related parameters */
 
- 	sbrFreq->nHigh = CalcFreqHigh(sbrFreq->freqHigh, sbrFreq->freqMaster, sbrFreq->nMaster, sbrHdr->crossOverBand);
 
- 	sbrFreq->numQMFBands = sbrFreq->freqHigh[sbrFreq->nHigh] - sbrFreq->freqHigh[0];
 
- 	sbrFreq->kStart = sbrFreq->freqHigh[0];
 
- 	/* calculate low frequency table */
 
- 	sbrFreq->nLow = CalcFreqLow(sbrFreq->freqLow, sbrFreq->freqHigh, sbrFreq->nHigh);
 
- 	/* calculate noise floor frequency table */
 
- 	sbrFreq->numNoiseFloorBands = CalcFreqNoise(sbrFreq->freqNoise, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart, k2, sbrHdr->noiseBands);
 
- 	/* calculate limiter table */
 
- 	sbrFreq->numPatches = BuildPatches(sbrFreq->patchNumSubbands, sbrFreq->patchStartSubband, sbrFreq->freqMaster, 
 
- 		sbrFreq->nMaster, k0, sbrFreq->kStart, sbrFreq->numQMFBands, sampRateIdx);
 
- 	sbrFreq->nLimiter = CalcFreqLimiter(sbrFreq->freqLimiter, sbrFreq->patchNumSubbands, sbrFreq->freqLow, sbrFreq->nLow, sbrFreq->kStart,
 
- 		sbrHdr->limiterBands, sbrFreq->numPatches);
 
- 	return 0;
 
- }
 
 
  |