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

📄 sbrhfadj.c

📁 nds上大名鼎鼎的DSOrganize 2.8最新源代码。很值得研究。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ***** BEGIN LICENSE BLOCK *****   * Source last modified: $Id: sbrhfadj.c,v 1.1.2.3 2005/05/24 20:34:40 albertofloyd Exp $  *    * 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];

⌨️ 快捷键说明

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