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

📄 sbrfreq.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 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 + -