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

📄 mpeg3dec.c

📁 mp3解码源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				while (sb--) {					temp = ST_MULT((*xrp0 + *xrp1), sq2);					*xrp1 = ST_MULT((*xrp0 - *xrp1), sq2);					*xrp0++ = temp;					xrp1++;			} else {				xrp0 += sb;				xrp1 += sb;			}			for (; sfb < sbmax; sfb++) {				// sbmax instead of 22				sb = band_l[sfb + 1] - band_l[sfb];				if (sfb < 21) {					// keep previous ispos for last sfb					ispos = sf->l[sfb];					is_illegal = (lsf) ? mps->						is_max_l[sfb] : 7;				}				if (ispos == is_illegal) {					if (ms_stereo)						while (sb--) {							temp = ST_MULT((*xrp0 + *xrp1), sq2);							*xrp1 = ST_MULT((*xrp0 - *xrp1), sq2);							*xrp0++ = temp;							xrp1++;					} else {						xrp0 += sb;						xrp1 += sb;					}				} else {					// ispos != is_illegal					k0 = pow_iok0[ispos];					k1 = pow_iok1[ispos];					while (sb--) {						temp = ST_MULT(*xrp0, k0);						*xrp1 = ST_MULT(*xrp0, k1);						*xrp0++ = temp;						xrp1++;					}				}			}		}	} else if ((mps->stereo) && ms_stereo) {		// MS stereo		xrp0 = xr;		xrp1 = &xr[MPA_GRANULE_SIZE];		sb = mps->imdct_max[0];		if (sb < mps->imdct_max[1])			sb = mps->imdct_max[1];		sb = (INT16) (sb + 1) * MPA_SSLIMIT;		if (sb > MPA_GRANULE_SIZE)			sb = MPA_GRANULE_SIZE;		while (sb--) {			temp = ST_MULT((*xrp0 + *xrp1), sq2);			*xrp1 = ST_MULT((*xrp0 - *xrp1), sq2);			*xrp0++ = temp;			xrp1++;		}	} else {		//Normal stereo or mono -> nothing to do !	}	return(MPEGDEC_ERR_NONE);}/****************************************************************************//* *	Decode the stereo data -> mono of a granule *	Return 0 if Ok */static int MPEG3_stereo_mono(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr, INT16 gr){	const INT16 *band_l = sfBandIndex_l[mps->header.ID][mps->header.sampling_frequency];	const INT16 *band_s = sfBandIndex_s[mps->header.ID][mps->header.sampling_frequency];	MPA_SCALE_FAC3 *sf = &mps->scale_fac3[1];	MPA_GRANULE_INFO *gi = &mps->side_info.ch[0].gr[gr];	BOOL ms_stereo = (mps->header.mode == MPA_MODE_JOINT_STEREO) &&		(mps->header.mode_extension & 0x2);	BOOL i_stereo = (mps->header.mode == MPA_MODE_JOINT_STEREO) &&		(mps->header.mode_extension & 0x1);	INT16 sfb;	INT16 i, j, sb, sbmax;	BOOL lsf = (mps->header.ID == MPA_ID_2);#define MAX_POS1	7#define MAX_POS2	32	const ST_TYPE *pow_iok0;	MPEGAUD_FRACT_TYPE *xrp0, *xrp1;#ifdef MPEGAUD_INT	ST_TYPE sq2 = 0.7071067812 * (1 << ST_BITS);#else	REAL sq2 = 0.7071067812;#endif	if (lsf) {		if (gi->scalefac_compress & 1)			pow_iok0 = pow_io0[1];		else			pow_iok0 = pow_io0[0];	} else {		pow_iok0 = tan_pos0;	}	if ((mps->stereo) && i_stereo) {		ST_TYPE k0;		INT16 sfb_top;		INT16 max_sfb = 0;		INT16 ispos;		INT16 is_illegal;		if (gi->window_switching_flag && (gi->block_type == 2)) {			sbmax = mps->sfb_nul_s_top[0];			if (sbmax < mps->sfb_nul_s_top[1])				sbmax = mps->sfb_nul_s_top[1];			sbmax++;			if (sbmax > 13)				sbmax = 13;			for (j = 0; j < 3; j++) {				sfb_top = mps->sfb_nul_s[j][1];				if ((gi->mixed_block_flag) && (sfb_top < 3))					sfb_top = 3;	// Normaly not !!!				if (sfb_top > max_sfb)					max_sfb = sfb_top;				is_illegal = (lsf) ? mps->is_max_s[j][0] : 7;				// Implicit: ispos == is_illegal here (not nul bands)				ispos = is_illegal;				for (sfb = 0; sfb < sfb_top; sfb++) {					sb = band_s[sfb + 1] - band_s[sfb];					i = 3 * band_s[sfb] + j * sb;					xrp0 = &xr[i];					xrp1 = &xr[MPA_GRANULE_SIZE + i];					if (ms_stereo)						while (sb--) {							*xrp0 = ST_MULT((*xrp0 + *xrp1), sq2);							xrp0++;							xrp1++;						}				}				while (sfb < sbmax) {					// #9: sbmax instead of 13					sb = band_s[sfb + 1] - band_s[sfb];					i = 3 * band_s[sfb] + j * sb;					xrp0 = &xr[i];					xrp1 = &xr[MPA_GRANULE_SIZE + i];					if (sfb < 12) {						// keep previous ispos for						// last sfb						ispos = sf->s[j][sfb];						is_illegal = (lsf) ? mps->							is_max_s[j][sfb] : 7;					}					if (ispos == is_illegal) {						if (ms_stereo)							while (sb--) {								*xrp0 = ST_MULT((*xrp0 + *xrp1), sq2);								xrp0++;								xrp1++;							}					} else {						// ispos != is_illegal						k0 = pow_iok0[ispos];						while (sb--) {							*xrp0 = ST_MULT(*xrp0, k0);							xrp0++;						}					}					sfb++;				}			}			if (gi->mixed_block_flag) {				INT16 sfb_max = (lsf) ? 6 : 8;				xrp0 = xr;				xrp1 = &xr[MPA_GRANULE_SIZE];				if (max_sfb <= 3) {					// Top of nul bands in long blocks					sfb = mps->sfb_nul_l[1];					// Begin of nul bands				} else {					sfb = sfb_max;					// Begin of nul band not in long blocks				}				sb = band_l[sfb];				// Implicit: ispos == is_illegal here (not nul bands)				if (ms_stereo)					while (sb--) {						*xrp0 = ST_MULT((*xrp0 + *xrp1), sq2);						xrp0++;						xrp1++;				} else {					xrp0 += sb;					xrp1 += sb;				}				for (; sfb < sfb_max; sfb++) {					sb = band_l[sfb + 1] - band_l[sfb];					ispos = sf->l[sfb];					is_illegal = (lsf) ? mps->						is_max_l[sfb] : 7;					if (ispos == is_illegal) {						if (ms_stereo)							while (sb--) {								*xrp0 = ST_MULT((*xrp0 + *xrp1), sq2);								xrp0++;								xrp1++;						} else {							xrp0 += sb;							xrp1 += sb;						}					} else {						// ispos != is_illegal						k0 = pow_iok0[ispos];						xrp1 += sb;						while (sb--) {							*xrp0 = ST_MULT(*xrp0, k0);							xrp0++;						}					}				}			}		} else {			// Long blocks, intensity stereo			sbmax = mps->sfb_nul_l[0];			if (sbmax < mps->sfb_nul_l[1])				sbmax = mps->sfb_nul_l[1];			sbmax++;			if (sbmax > 22)				sbmax = 22;			xrp0 = xr;			xrp1 = &xr[MPA_GRANULE_SIZE];			sfb = mps->sfb_nul_l[1];	// Begin of nul bands			sb = band_l[sfb];			is_illegal = (lsf) ? mps->is_max_l[0] : 7;			// Implicit: ispos == is_illegal here (not nul bands)			ispos = is_illegal;			if (ms_stereo)				while (sb--) {					*xrp0 = ST_MULT((*xrp0 + *xrp1), sq2);					xrp0++;					xrp1++;			} else {				xrp0 += sb;				xrp1 += sb;			}			for (; sfb < sbmax; sfb++) {				// #9: sbmax instead of 22				sb = band_l[sfb + 1] - band_l[sfb];				if (sfb < 21) {					// keep previous ispos for last sfb					ispos = sf->l[sfb];					is_illegal = (lsf) ? mps->						is_max_l[sfb] : 7;				}				if (ispos == is_illegal) {					if (ms_stereo)						while (sb--) {							*xrp0 = ST_MULT((*xrp0 + *xrp1), sq2);							xrp0++;							xrp1++;					} else {						xrp0 += sb;						xrp1 += sb;					}				} else {					// ispos != is_illegal					k0 = pow_iok0[ispos];					xrp1 += sb;					while (sb--) {						*xrp0 = ST_MULT(*xrp0, k0);						xrp0++;					}				}			}		}	} else if ((mps->stereo) && ms_stereo) {		// MS stereo		xrp0 = xr;		xrp1 = &xr[MPA_GRANULE_SIZE];		sb = mps->imdct_max[0];		if (sb < mps->imdct_max[1])			sb = mps->imdct_max[1];		sb = (INT16) (sb + 1) * MPA_SSLIMIT;		if (sb > MPA_GRANULE_SIZE)			sb = MPA_GRANULE_SIZE;		while (sb--) {			*xrp0 = ST_MULT((*xrp0 + *xrp1), sq2);			xrp0++;			xrp1++;		}	} else {		//Normal stereo or mono -> nothing to do !	}	return(MPEGDEC_ERR_NONE);}/****************************************************************************//* *	Reorder a granule (block type 2) *	Return 0 if Ok*/static int MPEG3_reorder(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr,	MPEGAUD_FRACT_TYPE *ro, INT16 gr, INT16 ch){	MPA_GRANULE_INFO *gi = &mps->side_info.ch[ch].gr[gr];	register MPEGAUD_FRACT_TYPE *pro;	register MPEGAUD_FRACT_TYPE *pxr0, *pxr1, *pxr2;	const INT16 *sfbindex;	INT16 sfb, freq;	INT16 sfb_start, sfb_lines;	// In ISO/IEC 11172-3 window_switching_flag is set if window type <> 0	// so, must be set if gi->block_type == 2 !	if (gi->window_switching_flag && (gi->block_type == 2)) {		pro = ro;		pxr2 = xr;		sfbindex = sfBandIndex_s[mps->header.ID][mps->header.sampling_frequency];		sfb = 13;		if (gi->mixed_block_flag) {			// No Reorder for the 2 first subbands			freq = (2 * MPA_SSLIMIT);			while (freq--)				*pro++ = *pxr2++;			sfb -= 3;			sfbindex += 3;		}		while (sfb--) {			sfb_start = *sfbindex++;			sfb_lines = *sfbindex - sfb_start;			pxr0 = pxr2;			pxr1 = pxr0 + sfb_lines;			pxr2 = pxr1 + sfb_lines;			freq = sfb_lines;			while (freq--) {				*pro++ = *pxr0++;				*pro++ = *pxr1++;				*pro++ = *pxr2++;			}		}	} else {		// Long blocks are in good order		memcpy(ro, xr, MPA_GRANULE_SIZE * sizeof(MPEGAUD_FRACT_TYPE));	}	return(MPEGDEC_ERR_NONE);}/****************************************************************************/#ifdef MPEGAUD_INT#define ALIAS_TYPE	INT16#define ALIAS_BITS	15#define ALIAS_MULT(bu, cx)	(((bu) * (cx))>>(ALIAS_BITS))#else#define ALIAS_TYPE	REAL#define ALIAS_MULT(bu, cx)	((bu) * (cx))#endif/****************************************************************************//* *	Apply the antialiasing buterfflies on a granule *	Return 0 if Ok */static int MPEG3_antialias(MPA_STREAM *mps, MPEGAUD_FRACT_TYPE *xr,	INT16 gr, INT16 ch, INT16 sb_max){	MPA_GRANULE_INFO *gi = &mps->side_info.ch[ch].gr[gr];#ifdef MPEGAUD_INT	// Pre-calc tables for ALIAS_BITS=15	static const ALIAS_TYPE ca[8] = {		-16858, -15457, -10268, -5960, -3099, -1342, -465, -121,	};	static const ALIAS_TYPE cs[8] = {		28098, 28892, 31117, 32221, 32621, 32740, 32764, 32767,	};#else	static const ALIAS_TYPE ca[8] = {		-0.514495730, -0.471731961, -0.313377440, -0.181913197,		-0.094574191, -0.040965579, -0.014198568, -0.003699975,	};	static const ALIAS_TYPE cs[8] = {		0.857492924, 0.881741941, 0.949628592, 0.983314574,		0.995517790, 0.999160528, 0.999899149, 0.999993145,	};#endif	INT16 sb, ss, i;	MPEGAUD_FRACT_TYPE *bu, *bd;  // upper and lower butterfly inputs	const ALIAS_TYPE *csi, *cai;	MPEGAUD_FRACT_TYPE obu;       // temp butterfly output	INT16 sblim;	if (gi->window_switching_flag && (gi->block_type == 2)) {		if (!gi->mixed_block_flag)			return(MPEGDEC_ERR_NONE);		sblim = 1;	} else {		sblim = sb_max - 1;	}	i = MPA_SSLIMIT - 1;	for (sb = 0; sb < sblim; sb++) {		bu = &xr[i];		bd = bu + 1;		i += MPA_SSLIMIT;		csi = cs;		cai = ca;		for (ss = 0; ss < 8; ss++) {			obu = ALIAS_MULT(*bu, *csi) - ALIAS_MULT(*bd, *cai);			*bd = ALIAS_MULT(*bd, *csi) + ALIAS_MULT(*bu, *cai);			*bu = obu;			csi++;			cai++;			bd++;			bu--;		}	}	return(MPEGDEC_ERR_NONE);}/****************************************************************************//* *	Reset the decoder */int MPEG3_reset(MPA_STREAM *mps){	// Reset the huffman decoder	return(HUFF_reset(mps->huffman));}/****************************************************************************//* *	Decode the current frame *	Return # of decoded samples */INT32 MPEG3_decode_frame(MPA_STREAM *mps){	INT16 max_gr, gr, ch;	int slots;	BITSTREAM *bs = mps->bitstream;	HUFFMAN *h = mps->huffman;	register char byte;	int status;	int start, seek_pos;	INT16 pcm_offset[2];	INT16 sb_max;	INT16 channels = (mps->force_mono) ? 1 : mps->channels;	int err;#define ERR_CHECK(i) \	err = i;\	if (err) { \		printf("Error %d in decode_frame\n", i); \		return(err); \	}	ERR_CHECK(MPEG3_decode_side_info(mps));	status = HUFF_set_start(h, mps->side_info.main_data_begin);	slots = MPEG3_main_data_slots(mps);	{		// 1440 is the max theorical value for layer III		char buffer[1440];		int i;		while (slots > 0) {			i = (slots > 1440) ? 1440 : slots;			BSTR_read_bytes(bs, slots, buffer);#ifdef USE_RC4			if (mps->header.private_bit) {				if (mps->keyp == NULL)					return(-1);				RC4(mps->keyp, slots, buffer, buffer);			}#endif			HUFF_fill_bytes(h, slots, buffer);			slots -= i;		}	}	if (BSTR_end(bs))		return(MPEGDEC_ERR_EOF);	if (status) {		// Can't decode this frame (not enough data)		// printf("Can't decode this frame (not enough data)\n");		return(0);	}	max_gr = (mps->header.ID == MPA_ID_1) ? 2 : 1;	pcm_offset[0] = pcm_offset[1] = 0;	seek_pos = HUFF_pos(h);	for (gr = 0; gr < max_gr; gr++) {		for (ch = 0; ch < mps->channels; ch++) {			// WE HAVE TO SEEK IN HUFFMAN DATA			// use part2_3_length of each granule			HUFF_seek(h, seek_pos);			start = HUFF_pos(h);			// calculate next seek position with actual part2_3_length			seek_pos += mps->side_info.ch[ch].gr[gr].part2_3_length;			if (mps->header.ID == MPA_ID_1) {				ERR_CHECK(MPEG3_decode_scale1(mps, gr, ch));			} else {				ERR_CHECK(MPEG3_decode_scale2(mps, gr, ch));			}			ERR_CHECK(MPEG3_huffman_decode				  (mps, mps->is, gr, ch, start));			MPEG3_get_nul_pos(mps, mps->is, gr, ch);			ERR_CHECK(MPEG3_dequantize_samples				  (mps, mps->is, &mps->xr[ch][0], gr, ch));		}		if (channels == 2) {			ERR_CHECK(MPEG3_stereo(mps, &mps->xr[0][0], gr));		} else if ((channels == 1) && (mps->channels == 2)) {			ERR_CHECK(MPEG3_stereo_mono(mps, &mps->xr[0][0], gr));		}		for (ch = 0; ch < channels; ch++) {			INT16 ss;			MPEGAUD_FRACT_TYPE *sub;			INT16 *pcm;			sb_max = mps->imdct_max[ch];			pcm = mps->pcm[ch];			if (mps->side_info.ch[ch].gr[gr].window_switching_flag			    && (mps->side_info.ch[ch].gr[gr].block_type == 2)) {				ERR_CHECK(MPEG3_reorder(mps, &mps->xr[ch][0],					&mps->lr[0][0], gr, ch));				ERR_CHECK(MPEG3_antialias(mps, &mps->lr[0][0],					 gr, ch, sb_max));				sub = &mps->lr[1][0];				MPEGIMDCT_hybrid(mps->mpegimdct,					&mps->lr[0][0], sub,					mps->side_info.ch[ch].gr[gr].block_type,					(BOOL) mps->side_info.ch[ch].gr[gr].mixed_block_flag, ch, sb_max);			} else {				ERR_CHECK(MPEG3_antialias(mps, &mps->xr[ch][0], gr, ch, sb_max));				sub = &mps->lr[1][0];				MPEGIMDCT_hybrid(mps->mpegimdct,					&mps->xr[ch][0], sub,					mps->side_info.ch[ch].gr[gr].block_type,					(BOOL) mps->side_info.ch[ch].gr[gr].mixed_block_flag, ch, sb_max);			}			for (ss = 0; ss < MPA_SSLIMIT; ss++) {				pcm_offset[ch] += MPEGSUB_synthesis(					mps->mpegsub, sub, ch,					&pcm[pcm_offset[ch]]);				sub += MPA_SBLIMIT;			}		}	}	HUFF_seek(h, seek_pos);	return((INT32) pcm_offset[0]);}/****************************************************************************/

⌨️ 快捷键说明

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