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

📄 libmpg123.c

📁 mips上编译过的mpg 运行正常 环境:AU12
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	libmpg123: MPEG Audio Decoder library	copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1	see COPYING and AUTHORS files in distribution or http://mpg123.org*/#include "mpg123lib_intern.h"#include "getbits.h"#include "debug.h"#ifdef GAPLESS#define SAMPLE_ADJUST(x)   ((x) - ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0))#define SAMPLE_UNADJUST(x) ((x) + ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0))#else#define SAMPLE_ADJUST(x)   (x)#define SAMPLE_UNADJUST(x) (x)#endif#define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)static int initialized = 0;#ifdef GAPLESS/*	Take the buffer after a frame decode (strictly: it is the data from frame fr->num!) and cut samples out.	fr->buffer.fill may then be smaller than before...*/static void frame_buffercheck(mpg123_handle *fr){	/* The first interesting frame: Skip some leading samples. */	if(fr->firstoff && fr->num == fr->firstframe)	{		off_t byteoff = samples_to_bytes(fr, fr->firstoff);		if(fr->buffer.fill > byteoff)		{			fr->buffer.fill -= byteoff;			/* buffer.p != buffer.data only for own buffer */			debug6("cutting %li samples/%li bytes on begin, own_buffer=%i at %p=%p, buf[1]=%i",			        (long)fr->firstoff, (long)byteoff, fr->own_buffer, (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);			if(fr->own_buffer) fr->buffer.p = fr->buffer.data + byteoff;			else memmove(fr->buffer.data, fr->buffer.data + byteoff, fr->buffer.fill);			debug3("done cutting, buffer at %p =? %p, buf[1]=%i",			        (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);		}		else fr->buffer.fill = 0;		fr->firstoff = 0; /* Only enter here once... when you seek, firstoff should be reset. */	}	/* The last interesting (planned) frame: Only use some leading samples. */	if(fr->lastoff && fr->num == fr->lastframe)	{		off_t byteoff = samples_to_bytes(fr, fr->lastoff);		if(fr->buffer.fill > byteoff)		{			fr->buffer.fill = byteoff;		}		fr->lastoff = 0; /* Only enter here once... when you seek, lastoff should be reset. */	}}#endifint mpg123_init(void){	if((sizeof(short) != 2) || (sizeof(long) < 4)) return MPG123_BAD_TYPES;	init_layer2(); /* inits also shared tables with layer1 */	init_layer3();#ifndef OPT_MMX_ONLY	prepare_decode_tables();#endif	check_decoders();	initialized = 1;	return MPG123_OK;}void mpg123_exit(void){	/* nothing yet, but something later perhaps */	if(initialized) return;}/* create a new handle with specified decoder, decoder can be "", "auto" or NULL for auto-detection */mpg123_handle *mpg123_new(const char* decoder, int *error){	return mpg123_parnew(NULL, decoder, error);}/* ...the full routine with optional initial parameters to override defaults. */mpg123_handle *mpg123_parnew(mpg123_pars *mp, const char* decoder, int *error){	mpg123_handle *fr = NULL;	int err = MPG123_OK;	if(initialized) fr = (mpg123_handle*) malloc(sizeof(mpg123_handle));	else err = MPG123_NOT_INITIALIZED;	if(fr != NULL)	{		frame_init_par(fr, mp);		debug("cpu opt setting");		if(frame_cpu_opt(fr, decoder) != 1)		{			err = MPG123_BAD_DECODER;			frame_exit(fr);			free(fr);			fr = NULL;		}	}	if(fr != NULL)	{		if((frame_outbuffer(fr) != 0) || (frame_buffers(fr) != 0))		{			err = MPG123_NO_BUFFERS;			frame_exit(fr);			free(fr);			fr = NULL;		}		else		{			opt_make_decode_tables(fr);			fr->decoder_change = 1;			/* happening on frame change instead:			init_layer3_stuff(fr);			init_layer2_stuff(fr); */		}	}	else if(err == MPG123_OK) err = MPG123_OUT_OF_MEM;	if(error != NULL) *error = err;	return fr;}int mpg123_decoder(mpg123_handle *mh, const char* decoder){	enum optdec dt = dectype(decoder);	if(mh == NULL) return MPG123_ERR;	if(dt == nodec)	{		mh->err = MPG123_BAD_DECODER;		return MPG123_ERR;	}	if(dt == mh->cpu_opts.type) return MPG123_OK;	/* Now really change. */	/* frame_exit(mh);	frame_init(mh); */	debug("cpu opt setting");	if(frame_cpu_opt(mh, decoder) != 1)	{		mh->err = MPG123_BAD_DECODER;		frame_exit(mh);		return MPG123_ERR;	}	/* New buffers for decoder are created in frame_buffers() */	if((frame_outbuffer(mh) != 0) || (frame_buffers(mh) != 0))	{		mh->err = MPG123_NO_BUFFERS;		frame_exit(mh);		return MPG123_ERR;	}	opt_make_decode_tables(mh);	mh->decoder_change = 1;	return MPG123_OK;}int mpg123_param(mpg123_handle *mh, enum mpg123_parms key, long val, double fval){	int r;	if(mh == NULL) return MPG123_ERR;	r = mpg123_par(&mh->p, key, val, fval);	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }	return r;}int mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long val, double fval){	int ret = MPG123_OK;	if(mp == NULL) return MPG123_BAD_PARS;	switch(key)	{		case MPG123_VERBOSE:			mp->verbose = val;		break;		case MPG123_FLAGS:#ifndef GAPLESS			if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS;			else#endif			mp->flags = val;			debug1("set flags to 0x%lx", (unsigned long) mp->flags);		break;		case MPG123_ADD_FLAGS:#ifndef GAPLESS			/* Enabling of gapless mode doesn't work when it's not there, but disabling (below) is no problem. */			if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS;			else#endif			mp->flags |= val;			debug1("set flags to 0x%lx", (unsigned long) mp->flags);		break;		case MPG123_REMOVE_FLAGS:			mp->flags &= ~val;			debug1("set flags to 0x%lx", (unsigned long) mp->flags);		break;		case MPG123_FORCE_RATE: /* should this trigger something? */			if(val > 96000) ret = MPG123_BAD_RATE;			else mp->force_rate = val < 0 ? 0 : val; /* >0 means enable, 0 disable */		break;		case MPG123_DOWN_SAMPLE:			if(val < 0 || val > 2) ret = MPG123_BAD_RATE;			else mp->down_sample = (int)val;		break;		case MPG123_RVA:			if(val < 0 || val > MPG123_RVA_MAX) ret = MPG123_BAD_RVA;			else mp->rva = (int)val;		break;		case MPG123_DOWNSPEED:			mp->halfspeed = val < 0 ? 0 : val;		break;		case MPG123_UPSPEED:			mp->doublespeed = val < 0 ? 0 : val;		break;		case MPG123_ICY_INTERVAL:			mp->icy_interval = val > 0 ? val : 0;		break;		case MPG123_OUTSCALE:#ifdef FLOATOUT			mp->outscale = fval;#else			mp->outscale = val;#endif		break;		case MPG123_TIMEOUT:#ifndef WIN32			mp->timeout = val >= 0 ? val : 0;#else			ret = MPG123_NO_TIMEOUT;#endif		break;		case MPG123_RESYNC_LIMIT:			mp->resync_limit = val;		break;		default:			ret = MPG123_BAD_PARAM;	}	return ret;}int mpg123_getparam(mpg123_handle *mh, enum mpg123_parms key, long *val, double *fval){	int r;	if(mh == NULL) return MPG123_ERR;	r = mpg123_getpar(&mh->p, key, val, fval);	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }	return r;}int mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, long *val, double *fval){	int ret = 0;	if(mp == NULL) return MPG123_BAD_PARS;	switch(key)	{		case MPG123_VERBOSE:			if(val) *val = mp->verbose;		break;		case MPG123_FLAGS:		case MPG123_ADD_FLAGS:			if(val) *val = mp->flags;		break;		case MPG123_FORCE_RATE:			if(val) *val = mp->force_rate;		break;		case MPG123_DOWN_SAMPLE:			if(val) *val = mp->down_sample;		break;		case MPG123_RVA:			if(val) *val = mp->rva;		break;		case MPG123_DOWNSPEED:			if(val) *val = mp->halfspeed;		break;		case MPG123_UPSPEED:			if(val) *val = mp->doublespeed;		break;		case MPG123_ICY_INTERVAL:			if(val) *val = (long)mp->icy_interval;		break;		case MPG123_OUTSCALE:#ifdef FLOATOUT			if(fval) *fval = mp->outscale;#else			if(val) *val = mp->outscale;#endif		break;		case MPG123_RESYNC_LIMIT:			if(val) *val = mp->resync_limit;		break;		default:			ret = MPG123_BAD_PARAM;	}	return ret;}int mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val){	if(mh == NULL) return MPG123_ERR;	if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }	switch(channel)	{		case MPG123_LEFT|MPG123_RIGHT:			mh->equalizer[0][band] = mh->equalizer[1][band] = DOUBLE_TO_REAL(val);		break;		case MPG123_LEFT:  mh->equalizer[0][band] = DOUBLE_TO_REAL(val); break;		case MPG123_RIGHT: mh->equalizer[1][band] = DOUBLE_TO_REAL(val); break;		default:			mh->err=MPG123_BAD_CHANNEL;			return MPG123_ERR;	}	mh->have_eq_settings = TRUE;	return MPG123_OK;}/* plain file access, no http! */int mpg123_open(mpg123_handle *mh, char *path){	if(mh == NULL) return MPG123_ERR;	mpg123_close(mh);	frame_reset(mh);	return open_stream(mh, path, -1);}int mpg123_open_fd(mpg123_handle *mh, int fd){	if(mh == NULL) return MPG123_ERR;	mpg123_close(mh);	frame_reset(mh);	return open_stream(mh, NULL, fd);}int mpg123_open_feed(mpg123_handle *mh){	if(mh == NULL) return MPG123_ERR;	mpg123_close(mh);	frame_reset(mh);	return open_feed(mh);}int mpg123_replace_reader( mpg123_handle *mh,                           ssize_t (*r_read) (int, void *, size_t),                           off_t   (*r_lseek)(int, off_t, int) ){	if(mh == NULL) return MPG123_ERR;	mh->rdat.r_read = r_read;	mh->rdat.r_lseek = r_lseek;	return MPG123_OK;}int decode_update(mpg123_handle *mh){	long native_rate = frame_freq(mh);	debug2("updating decoder structure with native rate %li and af.rate %li", native_rate, mh->af.rate);	if(mh->af.rate == native_rate) mh->down_sample = 0;	else if(mh->af.rate == native_rate>>1) mh->down_sample = 1;	else if(mh->af.rate == native_rate>>2) mh->down_sample = 2;	else mh->down_sample = 3; /* flexible (fixed) rate */	switch(mh->down_sample)	{		case 0:		case 1:		case 2:			mh->down_sample_sblimit = SBLIMIT>>(mh->down_sample);			/* With downsampling I get less samples per frame */			mh->outblock = sizeof(sample_t)*mh->af.channels*(spf(mh)>>mh->down_sample);		break;		case 3:		{			if(synth_ntom_set_step(mh) != 0) return -1;			if(frame_freq(mh) > mh->af.rate)			{				mh->down_sample_sblimit = SBLIMIT * mh->af.rate;				mh->down_sample_sblimit /= frame_freq(mh);			}			else mh->down_sample_sblimit = SBLIMIT;			mh->outblock = sizeof(sample_t) * mh->af.channels *			               ( ( NTOM_MUL-1+spf(mh)			                   * (((size_t)NTOM_MUL*mh->af.rate)/frame_freq(mh))			                 )/NTOM_MUL );		}		break;	}	if(!(mh->p.flags & MPG123_FORCE_MONO))	{		if(mh->af.channels == 1) mh->single = SINGLE_MIX;		else mh->single = SINGLE_STEREO;	}	else mh->single = (mh->p.flags & MPG123_FORCE_MONO)-1;	if(set_synth_functions(mh) != 0) return -1;;	init_layer3_stuff(mh);	init_layer2_stuff(mh);	do_rva(mh);	debug3("done updating decoder structure with native rate %li and af.rate %li and down_sample %i", frame_freq(mh), mh->af.rate, mh->down_sample);	return 0;}size_t mpg123_safe_buffer(){	return sizeof(sample_t)*2*1152*NTOM_MAX;}size_t mpg123_outblock(mpg123_handle *mh){	if(mh != NULL) return mh->outblock;	else return mpg123_safe_buffer();}static int get_next_frame(mpg123_handle *mh){	int change = mh->decoder_change;	do	{		int b;		/* Decode & discard some frame(s) before beginning. */		if(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe)		{			debug1("ignoring frame %li", (long)mh->num);			/* Decoder structure must be current! decode_update has been called before... */			(mh->do_layer)(mh); mh->buffer.fill = 0;			mh->to_ignore = mh->to_decode = FALSE;		}		/* Read new frame data; possibly breaking out here for MPG123_NEED_MORE. */		debug("read frame");		mh->to_decode = FALSE;		b = read_frame(mh); /* That sets to_decode only if a full frame was read. */		debug3("read of frame %li returned %i (to_decode=%i)", (long)mh->num, b, mh->to_decode);		if(b == MPG123_NEED_MORE) return MPG123_NEED_MORE; /* need another call with data */		else if(b <= 0)		{			/* More sophisticated error control? */			if(b==0 || mh->rdat.filepos == mh->rdat.filelen)			{ /* We simply reached the end. */				mh->track_frames = mh->num + 1;				return MPG123_DONE;			}			else return MPG123_ERR; /* Some real error. */		}		/* Now, there should be new data to decode ... and also possibly new stream properties */		if(mh->header_change > 1)		{			debug("big header change");			change = 1;		}	} while(mh->num < mh->firstframe);	/* When we start actually using the CRC, this could move into the loop... */	/* A question of semantics ... should I fold start_frame and frame_number into firstframe/lastframe? */	if(mh->lastframe >= 0 && mh->num > mh->lastframe)	{		mh->to_decode = mh->to_ignore = FALSE;		return MPG123_DONE;	}	if(change)	{		int b = frame_output_format(mh); /* Select the new output format based on given constraints. */		if(b < 0) return MPG123_ERR; /* not nice to fail here... perhaps once should add possibility to repeat this step */		if(decode_update(mh) < 0) return MPG123_ERR; /* dito... */		mh->decoder_change = 0;		if(b == 1) mh->new_format = 1; /* Store for later... */#ifdef GAPLESS		if(mh->fresh)		{			b=0;			/* Prepare offsets for gapless decoding. */			debug1("preparing gapless stuff with native rate %li", frame_freq(mh));			frame_gapless_realinit(mh);			frame_set_frameseek(mh, mh->num);			mh->fresh = 0;			/* Could this possibly happen? With a real big gapless offset... */			if(mh->num < mh->firstframe) b = get_next_frame(mh);			if(b < 0) return b; /* Could be error, need for more, new format... */		}#endif	}	return MPG123_OK;}/*	Put _one_ decoded frame into the frame structure's buffer, accessible at the location stored in <audio>, with <bytes> bytes available.	The buffer contents will be lost on next call to mpg123_decode_frame.	MPG123_OK -- successfully decoded the frame, you get your output data	MPg123_DONE -- This is it. End.	MPG123_ERR -- some error occured...	MPG123_NEW_FORMAT -- new frame was read, it results in changed output format -> will be decoded on next call	MPG123_NEED_MORE  -- that should not happen as this function is intended for in-library stream reader but if you force it...	MPG123_NO_SPACE   -- not enough space in buffer for safe decoding, also should not happen	num will be updated to the last decoded frame number (may possibly _not_ increase, p.ex. when format changed).*/int mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes){	if(bytes != NULL) *bytes = 0;	if(mh == NULL) return MPG123_ERR;	if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;	mh->buffer.fill = 0; /* always start fresh */	*bytes = 0;	while(TRUE)

⌨️ 快捷键说明

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