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

📄 mpeg1dec.c

📁 mp3解码源代码
💻 C
字号:
/****************************************************************************//* *	mpeg1dec.c -- MPEG layer I decoding functions * *	Author  :   St閜hane TAVENARD * *	(C) Copyright 1997-1997 St閜hane TAVENARD *	    All Rights Reserved * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. *	 *	This program is distributed in the hope that it will be useful, *	but WITHOUT ANY WARRANTY; without even the implied warranty of *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *	GNU General Public License for more details. *	 *	You should have received a copy of the GNU General Public License *	along with this program; if not, write to the Free Software *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//****************************************************************************/#include "defs.h"#include "bitstr.h"#include "mpegaud.h"#include "mpegtab.h"#include "mpegsub.h"#include "mpegdec.h"#include "mpeg1dec.h"/****************************************************************************//* *	Decode the bit allocations of MPEG I stream *	Return 0 if Ok */static int MPEG1_decode_bitalloc(MPA_STREAM *mps){	INT16 sb;	INT16 *bal0, *bal1;	INT16 value;	BITSTREAM *bs = mps->bitstream;	bal0 = &mps->bit_alloc[0][0];	if (mps->stereo) {		bal1 = &mps->bit_alloc[1][0];		for (sb = 0; sb < mps->jsbound; sb++) {			value = (INT16) BSTR_read_bits(bs, 8);			if (((value & 0xF0) == 0xF0) || ((value & 0x0F) == 0x0F))				return(MPEGDEC_ERR_BADFRAME);			*bal0++ = (value >> 4) & 0xF;			*bal1++ = value & 0xF;		}		for (; sb < MPA_SBLIMIT; sb++) {			*bal0 = BSTR_read_bits(bs, 4);			if (*bal0 == 0xF)				return(MPEGDEC_ERR_BADFRAME);			*bal1++ = *bal0++;		}	} else {		for (sb = 0; sb < MPA_SBLIMIT; sb++) {			value = BSTR_read_bits(bs, 4);			if (value == 0x0F)				return(MPEGDEC_ERR_BADFRAME);			*bal0++ = value;		}	}	return(MPEGDEC_ERR_NONE);}/****************************************************************************/#ifdef MPEGAUD_INT#define COEFF_TYPE	INT32#define COEFF_BITS	15#define COEFF_MULTK(k, m) \	((coeff[ k ] * (m))>>(COEFF_BITS+MPEGTAB_MULT_BITS-MPEGAUD_SCALE_BITS))/* *	Precalc of 2*2^COEFF_BITS/(2^(k+1)-1)  k:0..15 *	 Rounded to lower value */static const COEFF_TYPE coeff[16] = {    0, 21845, 9362, 4369, 2114, 1040, 516, 257,    128, 64, 32, 16, 8, 4, 2, 1};#else#define COEFF_MULTK(k, m)	(coeff[ k ] * (m))/* *	Precalc of 2/(2^(k+1)-1)  k:0..15 */static const REAL coeff[16] = {    2.0, 0.6666666667, 0.2857142857, 0.1333333333,    0.06451612903, 0.03174603175, 0.0157480315, 7.843137255e-3,    3.913894325e-3, 1.955034213e-3, 9.770395701e-4, 4.884004884e-4,    2.441704310e-4, 1.220777635e-4, 6.103701895e-5, 3.051804379e-5};#endif/****************************************************************************//* *	Decode the scales of MPEG I stream *	Return 0 if Ok*/static int MPEG1_decode_scale(MPA_STREAM *mps){	INT16 sb;	INT16 *bal0, *bal1;	MPEGAUD_SCALE_TYPE *sca0, *sca1;	INT16 k;	BITSTREAM *bs = mps->bitstream;	sca0 = &mps->scale[0][0][0];	bal0 = &mps->bit_alloc[0][0];	if (mps->stereo) {		bal1 = &mps->bit_alloc[1][0];		sca1 = &mps->scale[1][0][0];		for (sb = 0; sb < MPA_SBLIMIT; sb++) {			k = *bal0++;			if (k)				*sca0++ = COEFF_MULTK(k, MPT_multiple[BSTR_read_bits(bs, 6)]);			else				*sca0++ = (MPEGAUD_SCALE_TYPE) 0;					k = *bal1++;			if (k)				*sca1++ = COEFF_MULTK(k, MPT_multiple[BSTR_read_bits(bs, 6)]);			else				*sca1++ = (MPEGAUD_SCALE_TYPE) 0;		}	} else {		for (sb = 0; sb < MPA_SBLIMIT; sb++) {			k = *bal0++;			if (k)				*sca0++ = COEFF_MULTK(k, MPT_multiple[BSTR_read_bits(bs, 6)]);			else				*sca0++ = (MPEGAUD_SCALE_TYPE) 0;		}	}	return(MPEGDEC_ERR_NONE);}/****************************************************************************/#ifdef MPEGAUD_INT#define FRACT_MULT(sc, sa) \	(((sc) * (sa))>>(MPEGAUD_SCALE_BITS-MPEGAUD_FRACT_BITS))#else#define FRACT_MULT(sc, sa) ((sc) * (sa))#endif/* *	Read the samples of MPEG I stream & dequantize *	Return 0 if Ok */static int MPEG1_read_samples(MPA_STREAM *mps){	INT16 *bal0, *bal1;	MPEGAUD_SCALE_TYPE *sca0, *sca1;	MPEGAUD_FRACT_TYPE *fra0, *fra1;	INT16 sb, k;	INT32 s;	BITSTREAM *bs = mps->bitstream;	bal0 = &mps->bit_alloc[0][0];	sca0 = &mps->scale[0][0][0];	fra0 = &mps->fraction[0][0][0];	if (mps->stereo) {		bal1 = &mps->bit_alloc[1][0];		sca1 = &mps->scale[1][0][0];		fra1 = &mps->fraction[1][0][0];		for (sb = 0; sb < mps->jsbound; sb++) {			k = *bal0++;			if (k) {				s = 1 - (1 << k) + BSTR_read_bits(bs, k + 1);				*fra0++ = FRACT_MULT(*sca0, s);			} else {				*fra0++ = (MPEGAUD_SCALE_TYPE) 0;			}	    		sca0++;	    		k = *bal1++;			if (k) {				s = 1 - (1 << k) + BSTR_read_bits(bs, k + 1);				*fra1++ = FRACT_MULT(*sca1, s);			} else {				*fra1++ = (MPEGAUD_SCALE_TYPE) 0;			}			sca1++;		}		for (; sb < MPA_SBLIMIT; sb++) {			k = *bal0++;			if (k) {				s = 1 - (1 << k) + BSTR_read_bits(bs, k + 1);				*fra0++ = FRACT_MULT(*sca0, s);				*fra1++ = FRACT_MULT(*sca1, s);			} else {				*fra0++ = *fra1++ = (MPEGAUD_SCALE_TYPE) 0;			}			sca0++;			sca1++;		}	} else {		for (sb = 0; sb < MPA_SBLIMIT; sb++) {			k = *bal0++;			if (k) {				s = 1 - (1 << k) + BSTR_read_bits(bs, k + 1);				*fra0++ = FRACT_MULT(*sca0, s);			} else {				*fra0++ = (MPEGAUD_SCALE_TYPE) 0;			}			sca0++;		}	}	return(MPEGDEC_ERR_NONE);}/****************************************************************************//* *	Reset the decoder */int MPEG1_reset(MPA_STREAM *mps){	return(MPEGDEC_ERR_NONE);}/****************************************************************************//* *	Decode the current frame *	Return # of decoded samples */INT32 MPEG1_decode_frame(MPA_STREAM *mps){	INT16 block;	INT16 ch;	INT16 pcm_offset = 0;	INT16 pcm_count = 0;	INT16 channels = (mps->force_mono) ? 1 : mps->channels;	int err;	err = MPEG1_decode_bitalloc(mps);	if (err)		return err;	err = MPEG1_decode_scale(mps);	if (err)		return err;	for (block = 0; block < MPA_SCALE_BLOCK; block++) {		err = MPEG1_read_samples(mps);		if (err)			return(err);		for (ch = 0; ch < channels; ch++) {			pcm_count = MPEGSUB_synthesis(mps->mpegsub,				&mps->fraction[ch][0][0], ch,				&mps->pcm[ch][pcm_offset]);		}		pcm_offset += pcm_count;	}	return((INT32) pcm_offset);}/****************************************************************************/

⌨️ 快捷键说明

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