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

📄 sbrhfadj.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
		}

		q = MULSHIFT32(psi->smBuf[m], gBoost) << 2;		/* Q(fbitsDQ) * Q(28) --> Q(fbitsDQ-2) */
		r = SqrtFix(q, fbitsDQ - 2, &z);
		z -= FBITS_OUT_QMFA;		/* justify for adding to signal (xBuf) later */
		if (z >= 0) {
			psi->smBoost[m] = r >> MIN(31, z);
		} else {
			z = MIN(30, -z);
			CLIP_2N_SHIFT30(r, z);
			psi->smBoost[m] = r;
		}
	}
}

/**************************************************************************************
 * Function:    CalcGain
 *
 * Description: calculate and apply proper gain to HF components in one envelope 
 *                (4.6.18.7.5)
 *
 * Inputs:      initialized PSInfoSBR struct
 *              initialized SBRHeader struct for this SCE/CPE block
 *              initialized SBRGrid struct for this channel
 *              initialized SBRFreq struct for this SCE/CPE block
 *              initialized SBRChan struct for this channel
 *              index of current channel (0 for SCE, 0 or 1 for CPE)
 *              index of current envelope
 *
 * Outputs:     envelope gain, sinusoids and noise after scaling
 *
 * Return:      none
 **************************************************************************************/
static void CalcGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch, int env)
{
	int lim, fbitsDQ;

	/* initialize to -1 so that mapping limiter bands to env/noise bands works right on first pass */
	psi->envBand        = -1;
	psi->noiseFloorBand = -1;
	psi->sBand          = -1;
	psi->highBand       = -1;

	fbitsDQ = (FBITS_OUT_DQ_ENV - psi->envDataDequantScale[ch][env]);	/* Q(29 - optional scalefactor) */
	for (lim = 0; lim < sbrFreq->nLimiter; lim++) {
		/* the QMF bands are divided into lim regions (consecutive, non-overlapping) */
		CalcMaxGain(psi, sbrHdr, sbrGrid, sbrFreq, ch, env, lim, fbitsDQ);
		CalcComponentGains(psi, sbrGrid, sbrFreq, sbrChan, ch, env, lim, fbitsDQ);
		ApplyBoost(psi, sbrFreq, lim, fbitsDQ);
	}
}

/* hSmooth table from 4.7.18.7.6, format = Q31 */
static const int hSmoothCoef[MAX_NUM_SMOOTH_COEFS] = {
	0x2aaaaaab, 0x2697a512, 0x1becfa68, 0x0ebdb043, 0x04130598,
};

/**************************************************************************************
 * Function:    MapHF
 *
 * Description: map HF components to proper QMF bands, with optional gain smoothing
 *                filter (4.6.18.7.6)
 *
 * Inputs:      initialized PSInfoSBR struct
 *              initialized SBRHeader struct for this SCE/CPE block
 *              initialized SBRGrid struct for this channel
 *              initialized SBRFreq struct for this SCE/CPE block
 *              initialized SBRChan struct for this channel
 *              index of current envelope
 *              reset flag (can be non-zero for first envelope only)
 *
 * Outputs:     complete reconstructed subband QMF samples for this envelope
 *
 * Return:      none
 *
 * Notes:       ensures that output has >= MIN_GBITS_IN_QMFS guard bits,
 *                so it's not necessary to check anything in the synth QMF
 **************************************************************************************/
static void MapHF(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int hfReset)
{
	int noiseTabIndex, sinIndex, gainNoiseIndex, hSL;
	int i, iStart, iEnd, m, idx, j, s, n, smre, smim;
	int gFilt, qFilt, xre, xim, gbMask, gbIdx;
	int *XBuf;

	noiseTabIndex =   sbrChan->noiseTabIndex;
	sinIndex =        sbrChan->sinIndex;
	gainNoiseIndex =  sbrChan->gainNoiseIndex;	/* oldest entries in filter delay buffer */

	if (hfReset)
		noiseTabIndex = 2;	/* starts at 1, double since complex */
	hSL = (sbrHdr->smoothMode ? 0 : 4);

	if (hfReset) {
		for (i = 0; i < hSL; i++) {
			for (m = 0; m < sbrFreq->numQMFBands; m++) {
				sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m];
				sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m];
			}
			gainNoiseIndex++;
			if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS)
				gainNoiseIndex = 0;
		}
		ASSERT(env == 0);	/* should only be reset when env == 0 */
	}

	iStart = sbrGrid->envTimeBorder[env];
	iEnd =   sbrGrid->envTimeBorder[env+1];
	for (i = iStart; i < iEnd; i++) {
		/* save new values in temp buffers (delay)
		 * we only store MAX_NUM_SMOOTH_COEFS most recent values,
		 *   so don't keep storing the same value over and over
		 */
		if (i - iStart < MAX_NUM_SMOOTH_COEFS) {
			for (m = 0; m < sbrFreq->numQMFBands; m++) {
				sbrChan->gTemp[gainNoiseIndex][m] = psi->gLimBoost[m];
				sbrChan->qTemp[gainNoiseIndex][m] = psi->qmLimBoost[m];
			}
		}

		/* see 4.6.18.7.6 */
		XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart];
		gbMask = 0;
		for (m = 0; m < sbrFreq->numQMFBands; m++) {
			if (env == psi->la || env == sbrChan->laPrev) {
				/* no smoothing filter for gain, and qFilt = 0 (only need to do once) */
				if (i == iStart) {
					psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m];
					psi->qFiltLast[m] = 0;
				}
			} else if (hSL == 0) {
				/* no smoothing filter for gain, (only need to do once) */
				if (i == iStart) {
					psi->gFiltLast[m] = sbrChan->gTemp[gainNoiseIndex][m];
					psi->qFiltLast[m] = sbrChan->qTemp[gainNoiseIndex][m];
				}
			} else {
				/* apply smoothing filter to gain and noise (after MAX_NUM_SMOOTH_COEFS, it's always the same) */
				if (i - iStart < MAX_NUM_SMOOTH_COEFS) {
					gFilt = 0;
					qFilt = 0;
					idx = gainNoiseIndex;
					for (j = 0; j < MAX_NUM_SMOOTH_COEFS; j++) {
						/* sum(abs(hSmoothCoef[j])) for all j < 1.0 */
						gFilt += MULSHIFT32(sbrChan->gTemp[idx][m], hSmoothCoef[j]);
						qFilt += MULSHIFT32(sbrChan->qTemp[idx][m], hSmoothCoef[j]);
						idx--;
						if (idx < 0)
							idx += MAX_NUM_SMOOTH_COEFS;
					}
					psi->gFiltLast[m] = gFilt << 1;	/* restore to Q(FBITS_GLIM_BOOST) (gain of filter < 1.0, so no overflow) */
					psi->qFiltLast[m] = qFilt << 1;	/* restore to Q(FBITS_QLIM_BOOST) */
				}
			}

			if (psi->smBoost[m] != 0) {
				/* add scaled signal and sinusoid, don't add noise (qFilt = 0) */
				smre = psi->smBoost[m];
				smim = smre;

				/* sinIndex:  [0] xre += sm   [1] xim += sm*s   [2] xre -= sm   [3] xim -= sm*s  */
				s = (sinIndex >> 1);	/* if 2 or 3, flip sign to subtract sm */
				s <<= 31;
				smre ^= (s >> 31);
				smre -= (s >> 31);
				s ^= ((m + sbrFreq->kStart) << 31);
				smim ^= (s >> 31);
				smim -= (s >> 31);

				/* if sinIndex == 0 or 2, smim = 0; if sinIndex == 1 or 3, smre = 0 */
				s = sinIndex << 31;
				smim &= (s >> 31);
				s ^= 0x80000000;
				smre &= (s >> 31);

				noiseTabIndex += 2;		/* noise filtered by 0, but still need to bump index */
			} else {
				/* add scaled signal and scaled noise */
				qFilt = psi->qFiltLast[m];
				n = noiseTab[noiseTabIndex++];
				smre = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA);

				n = noiseTab[noiseTabIndex++];
				smim = MULSHIFT32(n, qFilt) >> (FBITS_QLIM_BOOST - 1 - FBITS_OUT_QMFA);
			}
			noiseTabIndex &= 1023;	/* 512 complex numbers */

			gFilt = psi->gFiltLast[m];
			xre = MULSHIFT32(gFilt, XBuf[0]);
			xim = MULSHIFT32(gFilt, XBuf[1]);
			CLIP_2N_SHIFT30(xre, 32 - FBITS_GLIM_BOOST);
			CLIP_2N_SHIFT30(xim, 32 - FBITS_GLIM_BOOST);

			xre += smre;	*XBuf++ = xre;
			xim += smim;	*XBuf++ = xim;

			gbMask |= FASTABS(xre);
			gbMask |= FASTABS(xim);
		}
		/* update circular buffer index */
		gainNoiseIndex++;
		if (gainNoiseIndex == MAX_NUM_SMOOTH_COEFS)
			gainNoiseIndex = 0;

		sinIndex++;
		sinIndex &= 3;

		/* ensure MIN_GBITS_IN_QMFS guard bits in output
		 * almost never occurs in practice, but checking here makes synth QMF logic very simple
		 */
		if (gbMask >> (31 - MIN_GBITS_IN_QMFS)) {
			XBuf = psi->XBuf[i + HF_ADJ][sbrFreq->kStart];
			for (m = 0; m < sbrFreq->numQMFBands; m++) {
				xre = XBuf[0];	xim = XBuf[1];
				CLIP_2N(xre, (31 - MIN_GBITS_IN_QMFS));
				CLIP_2N(xim, (31 - MIN_GBITS_IN_QMFS));
				*XBuf++ = xre;	*XBuf++ = xim;
			}
			CLIP_2N(gbMask, (31 - MIN_GBITS_IN_QMFS));
		}
		gbIdx = ((i + HF_ADJ) >> 5) & 0x01;
		sbrChan->gbMask[gbIdx] |= gbMask;
	}
	sbrChan->noiseTabIndex =  noiseTabIndex;
	sbrChan->sinIndex =       sinIndex;
	sbrChan->gainNoiseIndex = gainNoiseIndex;
}

/**************************************************************************************
 * Function:    AdjustHighFreq
 *
 * Description: adjust high frequencies and add noise and sinusoids (4.6.18.7)
 *
 * Inputs:      initialized PSInfoSBR struct
 *              initialized SBRHeader struct for this SCE/CPE block
 *              initialized SBRGrid struct for this channel
 *              initialized SBRFreq struct for this SCE/CPE block
 *              initialized SBRChan struct for this channel
 *              index of current channel (0 for SCE, 0 or 1 for CPE)
 *
 * Outputs:     complete reconstructed subband QMF samples for this channel
 *
 * Return:      none
 **************************************************************************************/
void AdjustHighFreq(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int ch)
{
	int i, env, hfReset;
	unsigned char frameClass, pointer;

	frameClass = sbrGrid->frameClass;
	pointer  = sbrGrid->pointer;

	/* derive la from table 4.159 */
	if ((frameClass == SBR_GRID_FIXVAR || frameClass == SBR_GRID_VARVAR) && pointer > 0)
		psi->la = sbrGrid->numEnv + 1 - pointer;
	else if (frameClass == SBR_GRID_VARFIX && pointer > 1)
		psi->la = pointer - 1;
	else
		psi->la = -1;

	/* for each envelope, estimate gain and adjust SBR QMF bands */
	hfReset = sbrChan->reset;
	for (env = 0; env < sbrGrid->numEnv; env++) {
		EstimateEnvelope(psi, sbrHdr, sbrGrid, sbrFreq, env);
		CalcGain(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, ch, env);
		MapHF(psi, sbrHdr, sbrGrid, sbrFreq, sbrChan, env, hfReset);
		hfReset = 0;	/* only set for first envelope after header reset */
	}

	/* set saved sine flags to 0 for QMF bands outside of current frequency range */
	for (i = 0; i < sbrFreq->freqLimiter[0] + sbrFreq->kStart; i++)
		sbrChan->addHarmonic[0][i] = 0;
	for (i = sbrFreq->freqLimiter[sbrFreq->nLimiter] + sbrFreq->kStart; i < 64; i++)
		sbrChan->addHarmonic[0][i] = 0;
	sbrChan->addHarmonicFlag[0] = sbrChan->addHarmonicFlag[1];

	/* save la for next frame */
	if (psi->la == sbrGrid->numEnv)
		sbrChan->laPrev = 0;
	else
		sbrChan->laPrev = -1;
}

⌨️ 快捷键说明

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