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

📄 libmpg123.c

📁 mips上编译过的mpg 运行正常 环境:AU12
💻 C
📖 第 1 页 / 共 2 页
字号:
	{		/* decode if possible */		if(mh->to_decode)		{			if(mh->new_format)			{				mh->new_format = 0;				return MPG123_NEW_FORMAT;			}			*num = mh->num;			debug("decoding");			mh->clip += (mh->do_layer)(mh);			mh->to_decode = mh->to_ignore = FALSE;			mh->buffer.p = mh->buffer.data;#ifdef GAPLESS			/* This checks for individual samples to skip, for gapless mode or sample-accurate seek. */			frame_buffercheck(mh);#endif			*audio = mh->buffer.p;			*bytes = mh->buffer.fill;			return MPG123_OK;		}		else		{			int b = get_next_frame(mh);			if(b < 0) return b;			debug1("got next frame, %i", mh->to_decode);		}	}	return MPG123_ERR;}int mpg123_read(mpg123_handle *mh, unsigned char *out, size_t size, size_t *done){	return mpg123_decode(mh, NULL, 0, out, size, done);}/*	The old picture:	while(1) {		len = read(0,buf,16384);		if(len <= 0)			break;		ret = decodeMP3(&mp,buf,len,out,8192,&size);		while(ret == MP3_OK) {			write(1,out,size);			ret = decodeMP3(&mp,NULL,0,out,8192,&size);		}	}*/int mpg123_decode(mpg123_handle *mh,unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done){	int ret = MPG123_OK;	size_t mdone = 0;	if(done != NULL) *done = 0;	if(mh == NULL) return MPG123_ERR;	if(inmemsize > 0)	if(feed_more(mh, inmemory, inmemsize) == -1){ ret = MPG123_ERR; goto decodeend; }	if(outmemory == NULL) outmemsize = 0; /* Not just give error, give chance to get a status message. */	while(ret == MPG123_OK)	{		debug3("decode loop, fill %i (%li vs. %li)", (int)mh->buffer.fill, (long)mh->num, (long)mh->firstframe);		/* Decode a frame that has been read before.		   This only happens when buffer is empty! */		if(mh->to_decode)		{			if(mh->new_format)			{				mh->new_format = 0;				return MPG123_NEW_FORMAT;			}			if(mh->buffer.size - mh->buffer.fill < mh->outblock)			{				ret = MPG123_NO_SPACE;				goto decodeend;			}			mh->clip += (mh->do_layer)(mh);			mh->to_decode = mh->to_ignore = FALSE;			mh->buffer.p = mh->buffer.data;			debug2("decoded frame %li, got %li samples in buffer", (long)mh->num, (long)(mh->buffer.fill / (samples_to_bytes(mh, 1))));#ifdef GAPLESS			frame_buffercheck(mh); /* Seek & gapless. */#endif		}		if(mh->buffer.fill) /* Copy (part of) the decoded data to the caller's buffer. */		{			/* get what is needed - or just what is there */			int a = mh->buffer.fill > (outmemsize - mdone) ? outmemsize - mdone : mh->buffer.fill;			debug4("buffer fill: %i; copying %i (%i - %li)", (int)mh->buffer.fill, a, (int)outmemsize, (long)*done);			memcpy(outmemory, mh->buffer.p, a);			/* less data in frame buffer, less needed, output pointer increase, more data given... */			mh->buffer.fill -= a;			outmemory  += a;			mdone += a;			mh->buffer.p += a;			if(!(outmemsize > mdone)) goto decodeend;		}		else /* If we didn't have data, get a new frame. */		{			int b = get_next_frame(mh);			if(b < 0){ ret = b; goto decodeend; }		}	}decodeend:	if(done != NULL) *done = mdone;	return ret;}long mpg123_clip(mpg123_handle *mh){	long ret = 0;	if(mh != NULL)	{		ret = mh->clip;		mh->clip = 0;	}	return ret;}#define track_need_init(mh) (!(mh)->to_decode && (mh)->fresh)static int init_track(mpg123_handle *mh){	if(track_need_init(mh))	{		/* Fresh track, need first frame for basic info. */		int b = get_next_frame(mh);		if(b < 0) return b;	}	return 0;}int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding){	if(mh == NULL) return MPG123_ERR;	if(init_track(mh) == MPG123_ERR) return MPG123_ERR;	*rate = mh->af.rate;	*channels = mh->af.channels;	*encoding = mh->af.encoding;	mh->new_format = 0;	return MPG123_OK;}off_t mpg123_timeframe(mpg123_handle *mh, double seconds){	off_t b;	if(mh == NULL) return MPG123_ERR;	b = init_track(mh);	if(b<0) return b;	return (off_t)(seconds/mpg123_tpf(mh));}/*	Now, where are we? We need to know the last decoded frame... and what's left of it in buffer.	The current frame number can mean the last decoded frame or the to-be-decoded frame.	If mh->to_decode, then mh->num frames have been decoded, the frame mh->num now coming next.	If not, we have the possibility of mh->num+1 frames being decoded or nothing at all.	Then, there is firstframe...when we didn't reach it yet, then the next data will come from there.	mh->num starts with -1*/off_t mpg123_tell(mpg123_handle *mh){	if(mh == NULL) return MPG123_ERR;	if(track_need_init(mh)) return 0;	/* Now we have all the info at hand. */	debug4("tell: %li/%i first %li buffer %lu", (long)mh->num, mh->to_decode, (long)mh->firstframe, (unsigned long)mh->buffer.fill);	if((mh->num < mh->firstframe) || (mh->num == mh->firstframe && mh->to_decode)) return SAMPLE_ADJUST(frame_tell_seek(mh));	else if(mh->to_decode) return SAMPLE_ADJUST(frame_outs(mh, mh->num) - mh->buffer.fill);	else return SAMPLE_ADJUST(frame_outs(mh, mh->num+1) - mh->buffer.fill);}off_t mpg123_tellframe(mpg123_handle *mh){	if(mh == NULL) return MPG123_ERR;	if(mh->num < mh->firstframe) return mh->firstframe;	if(mh->to_decode) return mh->num;	/* Consider firstoff? */	return mh->buffer.fill ? mh->num : mh->num + 1;}static int do_the_seek(mpg123_handle *mh){	int b;	off_t fnum = SEEKFRAME(mh);	mh->buffer.fill = 0;	if(mh->num < mh->firstframe) mh->to_decode = FALSE;	if(mh->num == fnum && mh->to_decode) return MPG123_OK;	if(mh->num == fnum-1)	{		mh->to_decode = FALSE;		return MPG123_OK;	}	/*frame_buffers_reset(mh);*/	b = mh->rd->seek_frame(mh, fnum);	if(b<0) return b;	/* Only mh->to_ignore is TRUE. */	if(mh->num < mh->firstframe) mh->to_decode = FALSE;	return 0;}off_t mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence){	int b;	off_t pos = mpg123_tell(mh); /* adjusted samples */debug1("pos=%li", (long)pos);	if(pos < 0) return pos; /* mh == NULL is covered in mpg123_tell() */	if((b=init_track(mh)) < 0) return b;	switch(whence)	{		case SEEK_CUR: pos += sampleoff; break;		case SEEK_SET: pos  = sampleoff; break;		case SEEK_END:#ifdef GAPLESS			if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff;#else			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff;#endif			else			{				mh->err = MPG123_NO_SEEK_FROM_END;				return MPG123_ERR;			}		break;		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;	}	if(pos < 0) pos = 0;	/* pos now holds the wanted sample offset in adjusted samples */	frame_set_seek(mh, SAMPLE_UNADJUST(pos));	pos = do_the_seek(mh);	if(pos < 0) return pos;	return mpg123_tell(mh);}/*	A bit more tricky... libmpg123 does not do the seeking itself.	All it can do is to ignore frames until the wanted one is there.	The caller doesn't know where a specific frame starts and mpg123 also only knows the general region after it scanned the file.	Well, it is tricky...*/off_t mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset){	int b;	off_t pos = mpg123_tell(mh); /* adjusted samples */	debug3("seek from %li to %li (whence=%i)", (long)pos, (long)sampleoff, whence);	if(pos < 0) return pos; /* mh == NULL is covered in mpg123_tell() */	if((b=init_track(mh)) < 0) return b; /* May need more to do anything at all. */	switch(whence)	{		case SEEK_CUR: pos += sampleoff; break;		case SEEK_SET: pos  = sampleoff; break;		case SEEK_END:#ifdef GAPLESS			if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff;#else			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff;#endif			else			{				mh->err = MPG123_NO_SEEK_FROM_END;				return MPG123_ERR;			}		break;		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;	}	if(pos < 0) pos = 0;	frame_set_seek(mh, SAMPLE_UNADJUST(pos));	pos = SEEKFRAME(mh);	mh->buffer.fill = 0;	/* Shortcuts without modifying input stream. */	*input_offset = mh->rdat.buffer.fileoff + mh->rdat.buffer.size;	if(mh->num < mh->firstframe) mh->to_decode = FALSE;	if(mh->num == pos && mh->to_decode) goto feedseekend;	if(mh->num == pos-1) goto feedseekend;	/* Whole way. */	*input_offset = feed_set_pos(mh, frame_index_find(mh, SEEKFRAME(mh), &pos));	mh->num = pos-1; /* The next read frame will have num = pos. */	if(*input_offset < 0) return MPG123_ERR;feedseekend:	return mpg123_tell(mh);}off_t mpg123_seek_frame(mpg123_handle *mh, off_t offset, int whence){	int b;	off_t pos = 0;	if(mh == NULL) return MPG123_ERR;	if((b=init_track(mh)) < 0) return b;	/* Could play games here with to_decode... */	pos = mh->num;	switch(whence)	{		case SEEK_CUR: pos += offset; break;		case SEEK_SET: pos  = offset; break;		case SEEK_END:			if(mh->track_frames > 0) pos = mh->track_frames - offset;			else			{				mh->err = MPG123_NO_SEEK_FROM_END;				return MPG123_ERR;			}		break;		default:			mh->err = MPG123_BAD_WHENCE;			return MPG123_ERR;	}	if(pos < 0) pos = 0;	/* Hm, do we need to seek right past the end? */	else if(mh->track_frames > 0 && pos >= mh->track_frames) pos = mh->track_frames;	frame_set_frameseek(mh, pos);	pos = do_the_seek(mh);	if(pos < 0) return pos;	return mpg123_tellframe(mh);}off_t mpg123_length(mpg123_handle *mh){	int b;	off_t length;	if(mh == NULL) return MPG123_ERR;	b = init_track(mh);	if(b<0) return b;	if(mh->track_samples > -1) length = mh->track_samples;	else if(mh->track_frames > 0) length = mh->track_frames*spf(mh);	else	{		/* A bad estimate. Ignoring tags 'n stuff. */		double bpf = mh->mean_framesize ? mh->mean_framesize : compute_bpf(mh);		length = (off_t)((double)(mh->rdat.filelen)/bpf*spf(mh));	}	length = frame_ins2outs(mh, length);#ifdef GAPLESS	if(mh->end_os > 0 && length > mh->end_os) length = mh->end_os;	length -= mh->begin_os;#endif	return length;}int mpg123_scan(mpg123_handle *mh){	int b;	off_t backframe;	int to_decode, to_ignore;	if(mh == NULL) return MPG123_ERR;	if(!(mh->rdat.flags & READER_SEEKABLE)){ mh->err = MPG123_NO_SEEK; return MPG123_ERR; }	/* Scan through the _whole_ file, since the current position is no count but computed assuming constant samples per frame. */	/* Also, we can just keep the current buffer and seek settings. Just operate on input frames here. */	b = init_track(mh); /* mh->num >= 0 !! */	if(b<0)	{		if(b == MPG123_DONE) return MPG123_OK;		else return MPG123_ERR; /* Must be error here, NEED_MORE is not for seekable streams. */	}	backframe = mh->num;	to_decode = mh->to_decode;	to_ignore = mh->to_ignore;	b = mh->rd->seek_frame(mh, 0);	if(b<0 || mh->num != 0) return MPG123_ERR;	/* One frame must be there now. */	mh->track_frames = 1;	mh->track_samples = spf(mh); /* Internal samples. */	while(read_frame(mh) == 1)	{		++mh->track_frames;		mh->track_samples += spf(mh);	}	b = mh->rd->seek_frame(mh, backframe);	if(b<0 || mh->num != backframe) return MPG123_ERR;	mh->to_decode = to_decode;	mh->to_ignore = to_ignore;	return MPG123_OK;}int mpg123_meta_check(mpg123_handle *mh){	if(mh != NULL) return mh->metaflags;	else return 0;}int mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2){	if(v1 != NULL) *v1 = NULL;	if(v2 != NULL) *v2 = NULL;	if(mh == NULL) return MPG123_ERR;	if(mh->metaflags & MPG123_ID3)	{		id3_link(mh);		if(v1 != NULL && mh->rdat.flags & READER_ID3TAG) *v1 = (mpg123_id3v1*) mh->id3buf;		if(v2 != NULL) *v2 = &mh->id3v2;		mh->metaflags |= MPG123_ID3;		mh->metaflags &= ~MPG123_NEW_ID3;	}	return MPG123_OK;}int mpg123_icy(mpg123_handle *mh, char **icy_meta){	*icy_meta = NULL;	if(mh == NULL) return MPG123_ERR;	if(mh->metaflags & MPG123_ICY)	{		*icy_meta = mh->icy.data;		mh->metaflags |= MPG123_ICY;		mh->metaflags &= ~MPG123_NEW_ICY;	}	return MPG123_OK;}int mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill){	if(mh == NULL) return MPG123_ERR;	if(offsets == NULL || step == NULL || fill == NULL) return MPG123_BAD_INDEX_PAR;	*offsets = mh->index.data;	*step    = mh->index.step;	*fill    = mh->index.fill;	return MPG123_OK;}int mpg123_close(mpg123_handle *mh){	if(mh == NULL) return MPG123_ERR;	if(mh->rd != NULL && mh->rd->close != NULL) mh->rd->close(mh);	mh->rd = NULL;	return MPG123_OK;}void mpg123_delete(mpg123_handle *mh){	if(mh != NULL)	{		mpg123_close(mh);		frame_exit(mh); /* free buffers in frame */		free(mh); /* free struct; cast? */	}}static const char *mpg123_error[] ={	"No error... (code 0)",	"Unable to set up output format! (code 1)",	"Invalid channel number specified. (code 2)",	"Invalid sample rate specified. (code 3)",	"Unable to allocate memory for 16 to 8 converter table! (code 4)",	"Bad parameter id! (code 5)",	"Bad buffer given -- invalid pointer or too small size. (code 6)",	"Out of memory -- some malloc() failed. (code 7)",	"You didn't initialize the library! (code 8)",	"Invalid decoder choice. (code 9)",	"Invalid mpg123 handle. (code 10)",	"Unable to initialize frame buffers (out of memory?)! (code 11)",	"Invalid RVA mode. (code 12)",	"This build doesn't support gapless decoding. (code 13)",	"Not enough buffer space. (code 14)",	"Incompatible numeric data types. (code 15)",	"Bad equalizer band. (code 16)",	"Null pointer given where valid storage address needed. (code 17)",	"Error reading the stream. (code 18)",	"Cannot seek from end (end is not known). (code 19)",	"Invalid 'whence' for seek function. (code 20)",	"Build does not support stream timeouts. (code 21)",	"File access error. (code 22)",	"Seek not supported by stream. (code 23)",	"No stream opened. (code 24)",	"Bad parameter handle. (code 25)",	"Invalid parameter addresses for index retrieval. (code 26)",	"Lost track in the bytestream and did not attempt resync. (code 27)",	"Failed to find valid MPEG data within limit on resync. (code 28)"};const char* mpg123_plain_strerror(int errcode){	if(errcode >= 0 && errcode < sizeof(mpg123_error)/sizeof(char*))	return mpg123_error[errcode];	else switch(errcode)	{		case MPG123_ERR:			return "A generic mpg123 error.";		case MPG123_DONE:			return "Message: I am done with this track.";		case MPG123_NEED_MORE:			return "Message: Feed me more input data!";		case MPG123_NEW_FORMAT:			return "Message: Prepare for a changed audio format!";		default:			return "I have no idea - an unknown error code!";	}}int mpg123_errcode(mpg123_handle *mh){	if(mh != NULL) return mh->err;	return MPG123_BAD_HANDLE;}const char* mpg123_strerror(mpg123_handle *mh){	return mpg123_plain_strerror(mpg123_errcode(mh));}

⌨️ 快捷键说明

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