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

📄 mp3onlydec.c

📁 mp3解码源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************//* *	mpegdec.c -- MPEG 3 only Audio decoder ... * *	Author  :   St閜hane TAVENARD * *	(C) Copyright 1997-1998 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 "mpegaud.h"#include "mpeg3dec.h"#include "mpegdec.h"#include "mpegtab.h"#ifdef USE_RC4#include "rc4.h"#endif/****************************************************************************//* *	Now default buffer size */#define MPEGDEC_BITSTREAM_BUFFER_SIZE	16384/****************************************************************************//* *	Decode the current Header *	Return 0 if Ok */static int MPEGDEC_decode_header(MPA_STREAM *mps){	MPA_HEADER *mph = &mps->header;	INT16 bitrate_per_channel;	INT16 table;	mps->bitrate = MPT_bitrate[mph->ID][mph->layer-1][mph->bitrate_index];	if (mph->mode == MPA_MODE_MONO) {		mps->stereo = FALSE;		mps->channels = 1;		bitrate_per_channel = mps->bitrate;	} else {		mps->stereo = TRUE;		mps->channels = 2;		bitrate_per_channel = mps->bitrate>>1;	}	mps->sfreq = MPT_freq[mph->ID][mph->sampling_frequency];	if (!mps->sfreq)		return(MPEGDEC_ERR_BADFRAME);	if (mph->half_freq)		mps->sfreq >>= 1; // #2		if (mph->layer == 2) {		if (mph->ID == MPA_ID_1) {			if (((mph->sampling_frequency == MPA_SAMP_48000) &&			   (bitrate_per_channel >= 56)) ||			   ((bitrate_per_channel >= 56) &&			   (bitrate_per_channel <= 80)))				table = 0;			else if ((mph->sampling_frequency != MPA_SAMP_48000) &&			   (bitrate_per_channel >= 96))				table = 1;			else if ((mph->sampling_frequency != MPA_SAMP_32000) &&			   (bitrate_per_channel <= 48))				table = 2;			else				table = 3;		} else {			table = 4;		}		mps->sblimit = MPT_sblimit[ table ];		if (table != mps->current_table) {			switch( table ) {			case 0: mps->alloc = MPT_alloc_0; break;			case 1: mps->alloc = MPT_alloc_1; break;			case 2: mps->alloc = MPT_alloc_2; break;			case 3: mps->alloc = MPT_alloc_3; break;			default: mps->alloc = MPT_alloc_4; break;			}			mps->current_table = table;			/*			 * *** WARNING ***			 * Reset when sblimit changed (because some MPEG			 * layer I inside layer II) reset fraction's			 */			memset(mps->fraction, 0, MPA_MAX_CHANNELS * MPA_GROUPS *				MPA_SBLIMIT * sizeof(MPEGAUD_FRACT_TYPE));		}	} else {		mps->sblimit = MPA_SBLIMIT;	}		if (mph->mode == MPA_MODE_JOINT_STEREO)		mps->jsbound = MPT_jsbound[mph->layer-1][mph->mode_extension];	else		mps->jsbound = mps->sblimit;	return(MPEGDEC_ERR_NONE);}/****************************************************************************//* *	Read the next MPEG AUDIO Header *	check: check if it's an mpeg audio stream, ie begin with a sync word *	Return MPEGDEC_ERR_EOF if end of stream reached. */static int MPEGDEC_read_header(MPA_STREAM *mps, BOOL check){	UINT32 value;	UINT32 header;	BITSTREAM *bs;	MPA_HEADER *mph;	UINT8 old_first;/* *	We check: Sync is either 0xFFF or 0xFFE (MPEG 2.5) *	Layer is not 4 (coded value is 0x0) *	Bitrate index is not 0xF (forbidden) *	Bitrate index is not 0x0 (free not supported) *	Frequency index is not 0x3 (reserved) */#define SYNC_VALID( v )	(((v & 0xFFE00000) == 0xFFE00000) && \			  ((v & 0x00060000) != 0x00000000) && \			  ((v & 0xF000) != 0xF000) && \			  ((v & 0xF000) != 0x0000) && \			  ((v & 0x0C00) != 0xC000))	bs = mps->bitstream;	if (BSTR_end(bs))		 return(MPEGDEC_ERR_EOF);	mph = &mps->header;	/*	 *	Header is: <Sync:12><ID:1><Lay:2><Prot:1>	 *		   <Rate:4><Freq:2><Pad:1><Priv:1>	 *		   <Mode:2><Ext:2><Copy:1><Orig:1><Emph:2>	 *	Total: 32 bits	 *	with <Sync> = 0xFFF for MPEG 1,2 <Sync> = 0xFFE for MPEG 2.5	 *	<Rate> can't be 0xF, so use it to skip leading 0xFF	 */	// Seek to sync word	old_first = bs->bits; // This could be the last byte read (not always !)	// Read first 24 bits	value = BSTR_read_byte(bs);	value <<= 8;	value |= BSTR_read_byte(bs);	value <<= 8;	value |= BSTR_read_byte(bs);	// Check if first sync is valid	value <<= 8;	if (SYNC_VALID(value)) {		// Ok, first sync is valid		value |= BSTR_read_byte(bs);	} else {		// first sync not valid -> try to use previous byte (tolerance!)		int loops = 16384;		if (check)			return(MPEGDEC_ERR_BADFRAME); // Not an MPEG Stream !		value >>= 8;		value |= old_first << 24; // use previous byte		while (!SYNC_VALID(value)) {			value <<= 8;			value |= BSTR_read_byte(bs);			if (BSTR_end(bs))				return(MPEGDEC_ERR_EOF);			if (loops-- <=0)				return(MPEGDEC_ERR_BADFRAME);		}	}	mph->header_pos = BSTR_pos(bs) - 4; // (header is 4 bytes long)	mph->half_freq = (value & 0x00100000) ? FALSE : TRUE;	header = value;	mph->emphasis = header & 0x0003; header >>= 2;	mph->original = header & 0x0001; header >>= 1;	mph->copyright = header & 0x0001; header >>= 1;	mph->mode_extension = header & 0x0003; header >>= 2;	mph->mode = header & 0x0003; header >>= 2;	mph->private_bit = header & 0x0001; header >>= 1;	mph->padding_bit = header & 0x0001; header >>= 1;	mph->sampling_frequency = header & 0x0003; header >>= 2;	mph->bitrate_index = header & 0x000F; header >>= 4;	mph->protection_bit = (header & 0x0001) ? FALSE : TRUE; header >>= 1;	mph->layer = 4 - (header & 0x0003); header >>= 2;	mph->ID = header & 0x0001;	// Check for correct values	if (mph->bitrate_index == 0xF)		return(MPEGDEC_ERR_BADFRAME); // Already checked in sync search	if (mph->sampling_frequency == 0x3)		return(MPEGDEC_ERR_BADFRAME);	if (mph->layer == 4)		return(MPEGDEC_ERR_BADFRAME);	if (mph->protection_bit)		mph->crc_check = BSTR_read_bits(bs, 16);	return(MPEGDEC_decode_header(mps));}/****************************************************************************//* *	Find an mpeg synchronization pattern in a buffer *	This function can be use to check if a file contains MPEG audio stream *	Inputs: buffer = stream buffer to analyze *	        buffer_size = need to know top of buffer (must be >= 4) *	Return the the sync position (>=0) or MPEGDEC_ERR_NO_SYNC if not found*/INT32 MPEGDEC_find_sync(INT8 *buffer, INT32 buffer_size){	INT32 index = 0;	UINT32 value = 0;	UINT8 *b;	b = (UINT8 *)buffer;	while (index < buffer_size) {		value <<= 8;		value |= (UINT32)(*b++);		if ((index >= 3) && SYNC_VALID(value))			return(index - 3);		index++;	}	return(MPEGDEC_ERR_NO_SYNC);}/****************************************************************************//* *	Synchronize the bitstream *	Return 0 if ok*/static int synchronize(MPA_STREAM *mps){#define MAX_TRIES 9	INT16 try = MAX_TRIES;	int status;	INT32 slots;	while (try--) {		status = MPEGDEC_read_header(mps, FALSE);		if (status == MPEGDEC_ERR_EOF)			return(status);		if (status == MPEGDEC_ERR_NONE) {			// Header found			int bitrate, sfreq, layer, id;			MPA_HEADER *mph = &mps->header;			id = mph->ID;			layer = mph->layer;			sfreq = mps->sfreq;			bitrate = mps->bitrate;				// Calculate the number of slots between 2 headers			if (layer == 1)				slots = 48000;			else				slots = 144000;			if ((layer == 3) && (id == MPA_ID_2))				slots >>= 1;			slots *= bitrate;			slots /= sfreq;			if (mph->padding_bit)				slots++;			// Now skip slots-4 bytes			if (mph->protection_bit)				slots -= 6; // #12			else slots -= 4;			while (slots--)				BSTR_read_byte(mps->bitstream);				// Now check if header ok and same id, norm, (bitrate) and freq			status = MPEGDEC_read_header( mps, TRUE );			if (status == MPEGDEC_ERR_NONE) {				if ((mph->ID == id) && (mph->layer == layer) &&				   (mps->sfreq == sfreq) ) {					int err;					err = BSTR_seek(mps->bitstream, mph->header_pos);					if (err)						return(MPEGDEC_ERR_BADFRAME);					err = MPEGDEC_read_header(mps, TRUE);					return(err);				}			} else if (status == MPEGDEC_ERR_EOF) {				return(status);			}		}	}	return(MPEGDEC_ERR_BADFRAME);}/****************************************************************************//* *	Fill the current MPEG Audio stream information */static void fill_info(MPEGDEC_STREAM *mpds){	MPA_STREAM *mps;	mps = (MPA_STREAM *) mpds->handle;	mpds->norm = (mps->header.ID == MPA_ID_1) ? 1 : 2;	mpds->layer = mps->header.layer;	mpds->mode = mps->header.mode;	mpds->bitrate = mps->bitrate;	mpds->frequency = mps->sfreq;	mpds->channels = mps->channels;	if (mps->bitrate)		mpds->ms_duration = mps->stream_size / (mps->bitrate>>3);	else		mpds->ms_duration = 0;	mpds->private_bit = (INT16) mps->header.private_bit;	mpds->copyright = (INT16) mps->header.copyright;	mpds->original = (INT16) mps->header.original;	mpds->dec_frequency = mps->sfreq / mps->freq_div;	mpds->dec_channels = (mps->force_mono) ? 1 : mpds->channels;	mpds->dec_quality = mps->quality;}/****************************************************************************//* *	Set the output scale for the current stream *	Inputs:  mpds = mpeg audio stream ptr returned by MPEGDEC_open *		 scale_percent = scale factor in % to apply to decoded output *				 100 is the nominal value *	Return 0 if Ok, MPEGDEC_ERR_BADVALUE if invalid scale */int MPEGDEC_scale(MPEGDEC_STREAM *mpds, INT32 scale_percent){	MPA_STREAM *mps;	mps = (MPA_STREAM *) mpds->handle;	if (MPEGSUB_scale(mps->mpegsub, scale_percent))		return(MPEGDEC_ERR_BADVALUE);	return(MPEGDEC_ERR_NONE);}/****************************************************************************/

⌨️ 快捷键说明

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