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

📄 imdct.c

📁 qt91上实现的mp3播放机,支持sam9260,参考用
💻 C
📖 第 1 页 / 共 2 页
字号:
		es = 0;		/* max gain = 18, assume adequate guard bits */		for (i = 8; i >= 0; i--) {				acc1 = (*xCurr--) - acc1;			acc2 = acc1 - acc2;			acc1 = (*xCurr--) - acc1;			xBuf[i+9] = acc2;	/* odd */			xBuf[i+0] = acc1;	/* even */		}	}	/* xEven[0] and xOdd[0] scaled by 0.5 */	xBuf[9] >>= 1;	xBuf[0] >>= 1;	/* do 9-point IDCT on even and odd */	idct9(xBuf+0);	/* even */	idct9(xBuf+9);	/* odd */	xp = xBuf + 8;	cp = c18 + 8;	mOut = 0;	if (btPrev == 0 && btCurr == 0) {		/* fast path - use symmetry of sin window to reduce windowing multiplies to 18 (N/2) */		wp = fastWin36;		for (i = 0; i < 9; i++) {			/* do ARM-style pointer arithmetic (i still needed for y[] indexing - compiler spills if 2 y pointers) */			c = *cp--;	xo = *(xp + 9);		xe = *xp--;			/* gain 2 int bits here */			xo = MULSHIFT32(c, xo);			/* 2*c18*xOdd (mul by 2 implicit in scaling)  */			xe >>= 2;			s = -(*xPrev);		/* sum from last block (always at least 2 guard bits) */			d = -(xe - xo);		/* gain 2 int bits, don't shift xo (effective << 1 to eat sign bit, << 1 for mul by 2) */			(*xPrev++) = xe + xo;			/* symmetry - xPrev[i] = xPrev[17-i] for long blocks */			t = s - d;			yLo = (d + (MULSHIFT32(t, *wp++) << 2));			yHi = (s + (MULSHIFT32(t, *wp++) << 2));			y[(i)*NBANDS]    = 	yLo;			y[(17-i)*NBANDS] =  yHi;			mOut |= FASTABS(yLo);			mOut |= FASTABS(yHi);		}	} else {		/* slower method - either prev or curr is using window type != 0 so do full 36-point window 		 * output xPrevWin has at least 3 guard bits (xPrev has 2, gain 1 in WinPrevious)		 */		WinPrevious(xPrev, xPrevWin, btPrev);		wp = imdctWin[btCurr];		for (i = 0; i < 9; i++) {			c = *cp--;	xo = *(xp + 9);		xe = *xp--;			/* gain 2 int bits here */			xo = MULSHIFT32(c, xo);			/* 2*c18*xOdd (mul by 2 implicit in scaling)  */			xe >>= 2;			d = xe - xo;			(*xPrev++) = xe + xo;	/* symmetry - xPrev[i] = xPrev[17-i] for long blocks */						yLo = (xPrevWin[i]    + MULSHIFT32(d, wp[i])) << 2;			yHi = (xPrevWin[17-i] + MULSHIFT32(d, wp[17-i])) << 2;			y[(i)*NBANDS]    = yLo;			y[(17-i)*NBANDS] = yHi;			mOut |= FASTABS(yLo);			mOut |= FASTABS(yHi);		}	}	xPrev -= 9;	mOut |= FreqInvertRescale(y, xPrev, blockIdx, es);	return mOut;}static const int c3_0 = 0x6ed9eba1;	/* format = Q31, cos(pi/6) */static const int c6[3] = { 0x7ba3751d, 0x5a82799a, 0x2120fb83 };	/* format = Q31, cos(((0:2) + 0.5) * (pi/6)) *//* 12-point inverse DCT, used in IMDCT12x3()  * 4 input guard bits will ensure no overflow */static __inline void imdct12 (int *x, int *out){	int a0, a1, a2;	int x0, x1, x2, x3, x4, x5;	x0 = *x;	x+=3;	x1 = *x;	x+=3;	x2 = *x;	x+=3;	x3 = *x;	x+=3;	x4 = *x;	x+=3;	x5 = *x;	x+=3;	x4 -= x5;	x3 -= x4;	x2 -= x3;	x3 -= x5;	x1 -= x2;	x0 -= x1;	x1 -= x3;	x0 >>= 1;	x1 >>= 1;	a0 = MULSHIFT32(c3_0, x2) << 1;	a1 = x0 + (x4 >> 1);	a2 = x0 - x4;	x0 = a1 + a0;	x2 = a2;	x4 = a1 - a0;	a0 = MULSHIFT32(c3_0, x3) << 1;	a1 = x1 + (x5 >> 1);	a2 = x1 - x5;	/* cos window odd samples, mul by 2, eat sign bit */	x1 = MULSHIFT32(c6[0], a1 + a0) << 2;				x3 = MULSHIFT32(c6[1], a2) << 2;	x5 = MULSHIFT32(c6[2], a1 - a0) << 2;	*out = x0 + x1;	out++;	*out = x2 + x3;	out++;	*out = x4 + x5;	out++;	*out = x4 - x5;	out++;	*out = x2 - x3;	out++;	*out = x0 - x1;}/************************************************************************************** * Function:    IMDCT12x3 * * Description: three 12-point modified DCT's for short blocks, with windowing, *                short block concatenation, and overlap-add * * Inputs:      3 interleaved vectors of 6 samples each  *                (block0[0], block1[0], block2[0], block0[1], block1[1]....) *              overlap part of last IMDCT (9 samples - see output comments) *              window type (0,1,2,3) of previous block *              current block index (for deciding whether to do frequency inversion) *              number of guard bits in input vector * * Outputs:     updated sample vector x, net gain of 1 integer bit *              second half of (unwindowed) IMDCT's - save for next time *                only save 9 xPrev samples, using symmetry (see WinPrevious()) * * Return:      mOut (OR of abs(y) for all y calculated here) * * TODO:        optimize for ARM **************************************************************************************/static int IMDCT12x3(int *xCurr, int *xPrev, int *y, int btPrev, int blockIdx, int gb){	int i, es, mOut, yLo, xBuf[18], xPrevWin[18];	/* need temp buffer for reordering short blocks */	const int *wp;	es = 0;	/* 7 gb is always adequate for accumulator loop + idct12 + window + overlap */	if (gb < 7) {		es = 7 - gb;		for (i = 0; i < 18; i+=2) {			xCurr[i+0] >>= es;			xCurr[i+1] >>= es;			*xPrev++ >>= es;		}		xPrev -= 9;	}	/* requires 4 input guard bits for each imdct12 */	imdct12(xCurr + 0, xBuf + 0);	imdct12(xCurr + 1, xBuf + 6);	imdct12(xCurr + 2, xBuf + 12);	/* window previous from last time */	WinPrevious(xPrev, xPrevWin, btPrev);	/* could unroll this for speed, minimum loads (short blocks usually rare, so doesn't make much overall difference) 	 * xPrevWin[i] << 2 still has 1 gb always, max gain of windowed xBuf stuff also < 1.0 and gain the sign bit	 * so y calculations won't overflow	 */	wp = imdctWin[2];	mOut = 0;	for (i = 0; i < 3; i++) {		yLo = (xPrevWin[ 0+i] << 2);		mOut |= FASTABS(yLo);	y[( 0+i)*NBANDS] = yLo;		yLo = (xPrevWin[ 3+i] << 2);		mOut |= FASTABS(yLo);	y[( 3+i)*NBANDS] = yLo;		yLo = (xPrevWin[ 6+i] << 2) + (MULSHIFT32(wp[0+i], xBuf[3+i]));			mOut |= FASTABS(yLo);	y[( 6+i)*NBANDS] = yLo;		yLo = (xPrevWin[ 9+i] << 2) + (MULSHIFT32(wp[3+i], xBuf[5-i]));			mOut |= FASTABS(yLo);	y[( 9+i)*NBANDS] = yLo;		yLo = (xPrevWin[12+i] << 2) + (MULSHIFT32(wp[6+i], xBuf[2-i]) + MULSHIFT32(wp[0+i], xBuf[(6+3)+i]));			mOut |= FASTABS(yLo);	y[(12+i)*NBANDS] = yLo;		yLo = (xPrevWin[15+i] << 2) + (MULSHIFT32(wp[9+i], xBuf[0+i]) + MULSHIFT32(wp[3+i], xBuf[(6+5)-i]));			mOut |= FASTABS(yLo);	y[(15+i)*NBANDS] = yLo;	}	/* save previous (unwindowed) for overlap - only need samples 6-8, 12-17 */	for (i = 6; i < 9; i++)		*xPrev++ = xBuf[i] >> 2;	for (i = 12; i < 18; i++)		*xPrev++ = xBuf[i] >> 2;	xPrev -= 9;	mOut |= FreqInvertRescale(y, xPrev, blockIdx, es);	return mOut;}/************************************************************************************** * Function:    HybridTransform * * Description: IMDCT's, windowing, and overlap-add on long/short/mixed blocks * * Inputs:      vector of input coefficients, length = nBlocksTotal * 18) *              vector of overlap samples from last time, length = nBlocksPrev * 9) *              buffer for output samples, length = MAXNSAMP *              SideInfoSub struct for this granule/channel *              BlockCount struct with necessary info *                number of non-zero input and overlap blocks *                number of long blocks in input vector (rest assumed to be short blocks) *                number of blocks which use long window (type) 0 in case of mixed block *                  (bc->currWinSwitch, 0 for non-mixed blocks) * * Outputs:     transformed, windowed, and overlapped sample buffer *              does frequency inversion on odd blocks *              updated buffer of samples for overlap * * Return:      number of non-zero IMDCT blocks calculated in this call *                (including overlap-add) * * TODO:        examine mixedBlock/winSwitch logic carefully (test he_mode.bit) **************************************************************************************/static int HybridTransform(int *xCurr, int *xPrev, int y[BLOCK_SIZE][NBANDS], SideInfoSub *sis, BlockCount *bc){	int xPrevWin[18], currWinIdx, prevWinIdx;	int i, j, nBlocksOut, nonZero, mOut;	int fiBit, xp;	ASSERT(bc->nBlocksLong  <= NBANDS);	ASSERT(bc->nBlocksTotal <= NBANDS);	ASSERT(bc->nBlocksPrev  <= NBANDS);	mOut = 0;	/* do long blocks, if any */	for(i = 0; i < bc->nBlocksLong; i++) {		/* currWinIdx picks the right window for long blocks (if mixed, long blocks use window type 0) */		currWinIdx = sis->blockType;		if (sis->mixedBlock && i < bc->currWinSwitch) 			currWinIdx = 0;		prevWinIdx = bc->prevType;		if (i < bc->prevWinSwitch)			 prevWinIdx = 0;		/* do 36-point IMDCT, including windowing and overlap-add */		mOut |= IMDCT36(xCurr, xPrev, &(y[0][i]), currWinIdx, prevWinIdx, i, bc->gbIn);		xCurr += 18;		xPrev += 9;	}	/* do short blocks (if any) */	for (   ; i < bc->nBlocksTotal; i++) {		ASSERT(sis->blockType == 2);		prevWinIdx = bc->prevType;		if (i < bc->prevWinSwitch)			 prevWinIdx = 0;				mOut |= IMDCT12x3(xCurr, xPrev, &(y[0][i]), prevWinIdx, i, bc->gbIn);		xCurr += 18;		xPrev += 9;	}	nBlocksOut = i;		/* window and overlap prev if prev longer that current */	for (   ; i < bc->nBlocksPrev; i++) {		prevWinIdx = bc->prevType;		if (i < bc->prevWinSwitch)			 prevWinIdx = 0;		WinPrevious(xPrev, xPrevWin, prevWinIdx);		nonZero = 0;		fiBit = i << 31;		for (j = 0; j < 9; j++) {			xp = xPrevWin[2*j+0] << 2;	/* << 2 temp for scaling */			nonZero |= xp;			y[2*j+0][i] = xp;			mOut |= FASTABS(xp);			/* frequency inversion on odd blocks/odd samples (flip sign if i odd, j odd) */			xp = xPrevWin[2*j+1] << 2;			xp = (xp ^ (fiBit >> 31)) + (i & 0x01);				nonZero |= xp;			y[2*j+1][i] = xp;			mOut |= FASTABS(xp);			xPrev[j] = 0;		}		xPrev += 9;		if (nonZero)			nBlocksOut = i;	}		/* clear rest of blocks */	for (   ; i < 32; i++) {		for (j = 0; j < 18; j++) 			y[j][i] = 0;	}	bc->gbOut = CLZ(mOut) - 1;	return nBlocksOut;}/************************************************************************************** * Function:    IMDCT * * Description: do alias reduction, inverse MDCT, overlap-add, and frequency inversion * * Inputs:      MP3DecInfo structure filled by UnpackFrameHeader(), UnpackSideInfo(), *                UnpackScaleFactors(), and DecodeHuffman() (for this granule, channel) *                includes PCM samples in overBuf (from last call to IMDCT) for OLA *              index of current granule and channel * * Outputs:     PCM samples in outBuf, for input to subband transform *              PCM samples in overBuf, for OLA next time *              updated hi->nonZeroBound index for this channel * * Return:      0 on success,  -1 if null input pointers **************************************************************************************/int IMDCT(MP3DecInfo *mp3DecInfo, int gr, int ch){	int nBfly, blockCutoff;	FrameHeader *fh;	SideInfo *si;	HuffmanInfo *hi;	IMDCTInfo *mi;	BlockCount bc;	/* validate pointers */	if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || 		!mp3DecInfo->HuffmanInfoPS || !mp3DecInfo->IMDCTInfoPS)		return -1;	/* si is an array of up to 4 structs, stored as gr0ch0, gr0ch1, gr1ch0, gr1ch1 */	fh = (FrameHeader *)(mp3DecInfo->FrameHeaderPS);	si = (SideInfo *)(mp3DecInfo->SideInfoPS);	hi = (HuffmanInfo*)(mp3DecInfo->HuffmanInfoPS);	mi = (IMDCTInfo *)(mp3DecInfo->IMDCTInfoPS);	/* anti-aliasing done on whole long blocks only	 * for mixed blocks, nBfly always 1, except 3 for 8 kHz MPEG 2.5 (see sfBandTab)      *   nLongBlocks = number of blocks with (possibly) non-zero power 	 *   nBfly = number of butterflies to do (nLongBlocks - 1, unless no long blocks)	 */	blockCutoff = fh->sfBand->l[(fh->ver == MPEG1 ? 8 : 6)] / 18;	/* same as 3* num short sfb's in spec */	if (si->sis[gr][ch].blockType != 2) {		/* all long transforms */		bc.nBlocksLong = MIN((hi->nonZeroBound[ch] + 7) / 18 + 1, 32);			nBfly = bc.nBlocksLong - 1;	} else if (si->sis[gr][ch].blockType == 2 && si->sis[gr][ch].mixedBlock) {		/* mixed block - long transforms until cutoff, then short transforms */		bc.nBlocksLong = blockCutoff;			nBfly = bc.nBlocksLong - 1;	} else {		/* all short transforms */		bc.nBlocksLong = 0;		nBfly = 0;	} 	AntiAlias(hi->huffDecBuf[ch], nBfly);	hi->nonZeroBound[ch] = MAX(hi->nonZeroBound[ch], (nBfly * 18) + 8);	ASSERT(hi->nonZeroBound[ch] <= MAX_NSAMP);	/* for readability, use a struct instead of passing a million parameters to HybridTransform() */	bc.nBlocksTotal = (hi->nonZeroBound[ch] + 17) / 18;	bc.nBlocksPrev = mi->numPrevIMDCT[ch];	bc.prevType = mi->prevType[ch];	bc.prevWinSwitch = mi->prevWinSwitch[ch];	bc.currWinSwitch = (si->sis[gr][ch].mixedBlock ? blockCutoff : 0);	/* where WINDOW switches (not nec. transform) */	bc.gbIn = hi->gb[ch];	mi->numPrevIMDCT[ch] = HybridTransform(hi->huffDecBuf[ch], mi->overBuf[ch], mi->outBuf[ch], &si->sis[gr][ch], &bc);	mi->prevType[ch] = si->sis[gr][ch].blockType;	mi->prevWinSwitch[ch] = bc.currWinSwitch;		/* 0 means not a mixed block (either all short or all long) */	mi->gb[ch] = bc.gbOut;	ASSERT(mi->numPrevIMDCT[ch] <= NBANDS);	/* output has gained 2 int bits */	return 0;}

⌨️ 快捷键说明

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