⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbrfreq.c

📁 nds上大名鼎鼎的DSOrganize 2.8最新源代码。很值得研究。
💻 C
📖 第 1 页 / 共 2 页
字号:
	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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -