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

📄 sbrhfadj.c

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