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

📄 sbrhfadj.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ***** BEGIN LICENSE BLOCK *****
 *
 * 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
 *
 * sbrhfadj.c - high frequency adjustment for SBR
 **************************************************************************************/

#include "sbr.h"
#include "assembly.h"

/* invBandTab[i] = 1.0 / (i + 1), Q31 */
static const int invBandTab[64] = {
	0x7fffffff, 0x40000000, 0x2aaaaaab, 0x20000000, 0x1999999a, 0x15555555, 0x12492492, 0x10000000,
	0x0e38e38e, 0x0ccccccd, 0x0ba2e8ba, 0x0aaaaaab, 0x09d89d8a, 0x09249249, 0x08888889, 0x08000000,
	0x07878788, 0x071c71c7, 0x06bca1af, 0x06666666, 0x06186186, 0x05d1745d, 0x0590b216, 0x05555555,
	0x051eb852, 0x04ec4ec5, 0x04bda12f, 0x04924925, 0x0469ee58, 0x04444444, 0x04210842, 0x04000000,
	0x03e0f83e, 0x03c3c3c4, 0x03a83a84, 0x038e38e4, 0x03759f23, 0x035e50d8, 0x03483483, 0x03333333,
	0x031f3832, 0x030c30c3, 0x02fa0be8, 0x02e8ba2f, 0x02d82d83, 0x02c8590b, 0x02b93105, 0x02aaaaab,
	0x029cbc15, 0x028f5c29, 0x02828283, 0x02762762, 0x026a439f, 0x025ed098, 0x0253c825, 0x02492492,
	0x023ee090, 0x0234f72c, 0x022b63cc, 0x02222222, 0x02192e2a, 0x02108421, 0x02082082, 0x02000000,
};

/**************************************************************************************
 * Function:    EstimateEnvelope
 *
 * Description: estimate power of generated HF QMF bands in one time-domain envelope
 *                (4.6.18.7.3)
 *
 * 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
 *              index of current envelope
 *
 * Outputs:     power of each QMF subband, stored as integer (Q0) * 2^N, N >= 0
 *
 * Return:      none
 **************************************************************************************/
static void EstimateEnvelope(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int env)
{
	int i, m, iStart, iEnd, xre, xim, nScale, expMax;
	int p, n, mStart, mEnd, invFact, t;
	int *XBuf;
	U64 eCurr;
	unsigned char *freqBandTab;

	/* estimate current envelope */
	iStart = sbrGrid->envTimeBorder[env] + HF_ADJ;
	iEnd =   sbrGrid->envTimeBorder[env+1] + HF_ADJ;
	if (sbrGrid->freqRes[env]) {
		n = sbrFreq->nHigh;
		freqBandTab = sbrFreq->freqHigh;
	} else {
		n = sbrFreq->nLow;
		freqBandTab = sbrFreq->freqLow;
	}

	/* ADS should inline MADD64 (smlal) properly, but check to make sure */
	expMax = 0;
	if (sbrHdr->interpFreq) {
		for (m = 0; m < sbrFreq->numQMFBands; m++) {
			eCurr.w64 = 0;
			XBuf = psi->XBuf[iStart][sbrFreq->kStart + m];
			for (i = iStart; i < iEnd; i++) {
				/* scale to int before calculating power (precision not critical, and avoids overflow) */
				xre = (*XBuf) >> FBITS_OUT_QMFA;	XBuf += 1;
				xim = (*XBuf) >> FBITS_OUT_QMFA;	XBuf += (2*64 - 1);
				eCurr.w64 = MADD64(eCurr.w64, xre, xre);
				eCurr.w64 = MADD64(eCurr.w64, xim, xim);
			}

			/* eCurr.w64 is now Q(64 - 2*FBITS_OUT_QMFA) (64-bit word)
			 * if energy is too big to fit in 32-bit word (> 2^31) scale down by power of 2
			 */
			nScale = 0;
			if (eCurr.r.hi32) {
				nScale = (32 - CLZ(eCurr.r.hi32)) + 1;
				t  = (int)(eCurr.r.lo32 >> nScale);		/* logical (unsigned) >> */
				t |= eCurr.r.hi32 << (32 - nScale);
			} else if (eCurr.r.lo32 >> 31) {
				nScale = 1;
				t  = (int)(eCurr.r.lo32 >> nScale);		/* logical (unsigned) >> */
			} else {
				t  = (int)eCurr.r.lo32;
			}

			invFact = invBandTab[(iEnd - iStart)-1];
			psi->eCurr[m] = MULSHIFT32(t, invFact);
			psi->eCurrExp[m] = nScale + 1;	/* +1 for invFact = Q31 */
			if (psi->eCurrExp[m] > expMax)
				expMax = psi->eCurrExp[m];
		}
	} else {
		for (p = 0; p < n; p++) {
			mStart = freqBandTab[p];
			mEnd =   freqBandTab[p+1];
			eCurr.w64 = 0;
			for (i = iStart; i < iEnd; i++) {
				XBuf = psi->XBuf[i][mStart];
				for (m = mStart; m < mEnd; m++) {
					xre = (*XBuf++) >> FBITS_OUT_QMFA;
					xim = (*XBuf++) >> FBITS_OUT_QMFA;
					eCurr.w64 = MADD64(eCurr.w64, xre, xre);
					eCurr.w64 = MADD64(eCurr.w64, xim, xim);
				}
			}

			nScale = 0;
			if (eCurr.r.hi32) {
				nScale = (32 - CLZ(eCurr.r.hi32)) + 1;
				t  = (int)(eCurr.r.lo32 >> nScale);		/* logical (unsigned) >> */
				t |= eCurr.r.hi32 << (32 - nScale);
			} else if (eCurr.r.lo32 >> 31) {
				nScale = 1;
				t  = (int)(eCurr.r.lo32 >> nScale);		/* logical (unsigned) >> */
			} else {
				t  = (int)eCurr.r.lo32;
			}

			invFact = invBandTab[(iEnd - iStart)-1];
			invFact = MULSHIFT32(invBandTab[(mEnd - mStart)-1], invFact) << 1;
			t = MULSHIFT32(t, invFact);

			for (m = mStart; m < mEnd; m++) {
				psi->eCurr[m - sbrFreq->kStart] = t;
				psi->eCurrExp[m - sbrFreq->kStart] = nScale + 1;	/* +1 for invFact = Q31 */
			}
			if (psi->eCurrExp[mStart - sbrFreq->kStart] > expMax)
				expMax = psi->eCurrExp[mStart - sbrFreq->kStart];
		}
	}
	psi->eCurrExpMax = expMax;
}

/**************************************************************************************
 * Function:    GetSMapped
 *
 * Description: calculate SMapped (4.6.18.7.2)
 *
 * Inputs:      initialized PSInfoSBR struct
 *              initialized SBRGrid struct for this channel
 *              initialized SBRFreq struct for this SCE/CPE block
 *              initialized SBRChan struct for this channel
 *              index of current envelope
 *              index of current QMF band
 *              la flag for this envelope
 *
 * Outputs:     none
 *
 * Return:      1 if a sinusoid is present in this band, 0 if not
 **************************************************************************************/
static int GetSMapped(SBRGrid *sbrGrid, SBRFreq *sbrFreq, SBRChan *sbrChan, int env, int band, int la)
{
	int bandStart, bandEnd, oddFlag, r;

	if (sbrGrid->freqRes[env]) {
		/* high resolution */
		bandStart = band;
		bandEnd = band+1;
	} else {
		/* low resolution (see CalcFreqLow() for mapping) */
		oddFlag = sbrFreq->nHigh & 0x01;
		bandStart = (band > 0 ? 2*band - oddFlag : 0);		/* starting index for freqLow[band] */
		bandEnd = 2*(band+1) - oddFlag;						/* ending index for freqLow[band+1] */
	}

	/* sMapped = 1 if sIndexMapped == 1 for any frequency in this band */
	for (band = bandStart; band < bandEnd; band++) {
		if (sbrChan->addHarmonic[1][band]) {
			r = ((sbrFreq->freqHigh[band+1] + sbrFreq->freqHigh[band]) >> 1);
			if (env >= la || sbrChan->addHarmonic[0][r] == 1)
				return 1;
		}
	}
	return 0;
}

#define GBOOST_MAX	0x2830afd3	/* Q28, 1.584893192 squared */
#define	ACC_SCALE	6

/* squared version of table in 4.6.18.7.5 */
static const int limGainTab[4] = {0x20138ca7, 0x40000000, 0x7fb27dce, 0x80000000};	/* Q30 (0x80000000 = sentinel for GMAX) */

/**************************************************************************************
 * Function:    CalcMaxGain
 *
 * Description: calculate max gain in one limiter band (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
 *              index of current channel (0 for SCE, 0 or 1 for CPE)
 *              index of current envelope
 *              index of current limiter band
 *              number of fraction bits in dequantized envelope 
 *                (max = Q(FBITS_OUT_DQ_ENV - 6) = Q23, can go negative)
 *
 * Outputs:     updated gainMax, gainMaxFBits, and sumEOrigMapped in PSInfoSBR struct
 *
 * Return:      none
 **************************************************************************************/
static void CalcMaxGain(PSInfoSBR *psi, SBRHeader *sbrHdr, SBRGrid *sbrGrid, SBRFreq *sbrFreq, int ch, int env, int lim, int fbitsDQ)
{
	int m, mStart, mEnd, q, z, r;
	int sumEOrigMapped, sumECurr, gainMax, eOMGainMax, envBand;
	unsigned char eCurrExpMax;
	unsigned char *freqBandTab;

	mStart = sbrFreq->freqLimiter[lim];   /* these are offsets from kStart */
	mEnd =   sbrFreq->freqLimiter[lim + 1];
	freqBandTab = (sbrGrid->freqRes[env] ? sbrFreq->freqHigh : sbrFreq->freqLow);

	/* calculate max gain to apply to signal in this limiter band */
	sumECurr = 0;
	sumEOrigMapped = 0;
	eCurrExpMax = psi->eCurrExpMax;
	eOMGainMax = psi->eOMGainMax;
	envBand = psi->envBand;
	for (m = mStart; m < mEnd; m++) {
		/* map current QMF band to appropriate envelope band */
		if (m == freqBandTab[envBand + 1] - sbrFreq->kStart) {
			envBand++;
			eOMGainMax = psi->envDataDequant[ch][env][envBand] >> ACC_SCALE;	/* summing max 48 bands */
		}
		sumEOrigMapped += eOMGainMax;

		/* easy test for overflow on ARM */
		sumECurr += (psi->eCurr[m] >> (eCurrExpMax - psi->eCurrExp[m]));
		if (sumECurr >> 30) {
			sumECurr >>= 1;
			eCurrExpMax++;
		}
	}
	psi->eOMGainMax = eOMGainMax;
	psi->envBand = envBand;

	psi->gainMaxFBits = 30;	/* Q30 tables */
	if (sumECurr == 0) {
		/* any non-zero numerator * 1/EPS_0 is > G_MAX */
		gainMax = (sumEOrigMapped == 0 ? limGainTab[sbrHdr->limiterGains] : 0x80000000);
	} else if (sumEOrigMapped == 0) {
		/* 1/(any non-zero denominator) * EPS_0 * limGainTab[x] is appx. 0 */
		gainMax = 0;
	} else {
		/* sumEOrigMapped = Q(fbitsDQ - ACC_SCALE), sumECurr = Q(-eCurrExpMax) */
		gainMax = limGainTab[sbrHdr->limiterGains];
		if (sbrHdr->limiterGains != 3) {

⌨️ 快捷键说明

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