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

📄 frame.c

📁 mips上编译过的mpg 运行正常 环境:AU12
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	frame: Heap of routines dealing with the core mpg123 data structure.	copyright 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	initially written by Thomas Orgis*/#include "mpg123lib_intern.h"#include "getcpuflags.h"#include "debug.h"#define IGNORESHIFT 2static void frame_fixed_reset(mpg123_handle *fr);/* that's doubled in decode_ntom.c */#define NTOM_MUL (32768)#define aligned_pointer(p,type,alignment) \	(((char*)(p)-(char*)NULL) % (alignment)) \	? (type*)((char*)(p) + (alignment) - (((char*)(p)-(char*)NULL) % (alignment))) \	: (type*)(p)void frame_default_pars(mpg123_pars *mp){	mp->outscale = MAXOUTBURST;#ifdef GAPLESS	mp->flags = MPG123_GAPLESS;#else	mp->flags = 0;#endif	mp->force_rate = 0;	mp->down_sample = 0;	mp->rva = 0;	mp->halfspeed = 0;	mp->doublespeed = 0;	mp->verbose = 0;	mp->icy_interval = 0;#ifndef WIN32	mp->timeout = 0;#endif	mp->resync_limit = 1024;	mpg123_fmt_all(mp);}void frame_init(mpg123_handle *fr){	frame_init_par(fr, NULL);}void frame_init_par(mpg123_handle *fr, mpg123_pars *mp){	fr->own_buffer = FALSE;	fr->buffer.data = NULL;	fr->rawbuffs = NULL;	fr->rawdecwin = NULL;	fr->conv16to8_buf = NULL;	fr->cpu_opts.type = defopt;	fr->cpu_opts.class = (defopt == mmx || defopt == sse || defopt == dreidnowext) ? mmxsse : normal;	/* these two look unnecessary, check guarantee for synth_ntom_set_step (in control_generic, even)! */	fr->ntom_val[0] = NTOM_MUL>>1;	fr->ntom_val[1] = NTOM_MUL>>1;	fr->ntom_step = NTOM_MUL;	/* unnecessary: fr->buffer.size = fr->buffer.fill = 0; */	mpg123_reset_eq(fr);	init_icy(&fr->icy);	init_id3(fr);	/* frame_outbuffer is missing... */	/* frame_buffers is missing... that one needs cpu opt setting! */	/* after these... frame_reset is needed before starting full decode */	fr->af.encoding = 0;	fr->af.rate = 0;	fr->af.channels = 0;	fr->rdat.r_read = NULL;	fr->rdat.r_lseek = NULL;	fr->decoder_change = 1;	fr->err = MPG123_OK;	if(mp == NULL) frame_default_pars(&fr->p);	else memcpy(&fr->p, mp, sizeof(struct mpg123_pars_struct));	frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */}mpg123_pars *mpg123_new_pars(int *error){	mpg123_pars *mp = malloc(sizeof(struct mpg123_pars_struct));	if(mp != NULL){ frame_default_pars(mp); if(error != NULL) *error = MPG123_OK; }	else if(error != NULL) *error = MPG123_OUT_OF_MEM;	return mp;}void mpg123_delete_pars(mpg123_pars* mp){	if(mp != NULL) free(mp);}int mpg123_reset_eq(mpg123_handle *mh){	int i;	mh->have_eq_settings = 0;	for(i=0; i < 32; ++i) mh->equalizer[0][i] = mh->equalizer[1][i] = DOUBLE_TO_REAL(1.0);	return MPG123_OK;}int frame_outbuffer(mpg123_handle *fr){	size_t size = mpg123_safe_buffer()*AUDIOBUFSIZE;	if(!fr->own_buffer) fr->buffer.data = NULL;	if(fr->buffer.data != NULL && fr->buffer.size != size)	{		free(fr->buffer.data);		fr->buffer.data = NULL;	}	fr->buffer.size = size;	if(fr->buffer.data == NULL) fr->buffer.data = (unsigned char*) malloc(fr->buffer.size);	if(fr->buffer.data == NULL)	{		fr->err = MPG123_OUT_OF_MEM;		return -1;	}	fr->own_buffer = TRUE;	fr->buffer.fill = 0;	return 0;}int mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size){	if(data == NULL || size < mpg123_safe_buffer())	{		mh->err = MPG123_BAD_BUFFER;		return MPG123_ERR;	}	if(mh->own_buffer && mh->buffer.data != NULL) free(mh->buffer.data);	mh->own_buffer = FALSE;	mh->buffer.data = data;	mh->buffer.size = size;	mh->buffer.fill = 0;	return MPG123_OK;}int frame_buffers(mpg123_handle *fr){	int buffssize = 0;	debug1("frame %p buffer", (void*)fr);/*	the used-to-be-static buffer of the synth functions, has some subtly different types/sizes	2to1, 4to1, ntom, generic, i386: real[2][2][0x110]	mmx, sse: short[2][2][0x110]	i586(_dither): 4352 bytes; int/long[2][2][0x110]	i486: int[2][2][17*FIR_BUFFER_SIZE]	altivec: static real __attribute__ ((aligned (16))) buffs[4][4][0x110]	Huh, altivec looks like fun. Well, let it be large... then, the 16 byte alignment seems to be implicit on MacOSX malloc anyway.	Let's make a reasonable attempt to allocate enough memory...	Keep in mind: biggest ones are i486 and altivec (mutually exclusive!), then follows i586 and normal real.	mmx/sse use short but also real for resampling.	Thus, minimum is 2*2*0x110*sizeof(real).*/	if(fr->cpu_opts.type == altivec) buffssize = 4*4*0x110*sizeof(real);#ifdef OPT_I486	else if(fr->cpu_opts.type == ivier) buffssize = 2*2*17*FIR_BUFFER_SIZE*sizeof(int);#endif	else if(fr->cpu_opts.type == ifuenf || fr->cpu_opts.type == ifuenf_dither || fr->cpu_opts.type == dreidnow)	buffssize = 2*2*0x110*4; /* don't rely on type real, we need 4352 bytes */	if(2*2*0x110*sizeof(real) > buffssize)	buffssize = 2*2*0x110*sizeof(real);	buffssize += 15; /* For 16-byte alignment (SSE likes that). */	if(fr->rawbuffs != NULL && fr->rawbuffss != buffssize)	{		free(fr->rawbuffs);		fr->rawbuffs = NULL;	}	if(fr->rawbuffs == NULL) fr->rawbuffs = (unsigned char*) malloc(buffssize);	if(fr->rawbuffs == NULL) return -1;	fr->rawbuffss = buffssize;	fr->short_buffs[0][0] = aligned_pointer(fr->rawbuffs,short,16);	fr->short_buffs[0][1] = fr->short_buffs[0][0] + 0x110;	fr->short_buffs[1][0] = fr->short_buffs[0][1] + 0x110;	fr->short_buffs[1][1] = fr->short_buffs[1][0] + 0x110;	fr->real_buffs[0][0] = aligned_pointer(fr->rawbuffs,real,16);	fr->real_buffs[0][1] = fr->real_buffs[0][0] + 0x110;	fr->real_buffs[1][0] = fr->real_buffs[0][1] + 0x110;	fr->real_buffs[1][1] = fr->real_buffs[1][0] + 0x110;#ifdef OPT_I486	if(fr->cpu_opts.type == ivier)	{		fr->int_buffs[0][0] = (int*) fr->rawbuffs;		fr->int_buffs[0][1] = fr->int_buffs[0][0] + 17*FIR_BUFFER_SIZE;		fr->int_buffs[1][0] = fr->int_buffs[0][1] + 17*FIR_BUFFER_SIZE;		fr->int_buffs[1][1] = fr->int_buffs[1][0] + 17*FIR_BUFFER_SIZE;	}#endif#ifdef OPT_ALTIVEC	if(fr->cpu_opts.type == altivec)	{		int i,j;		fr->areal_buffs[0][0] = (real*) fr->rawbuffs;		for(i=0; i<4; ++i) for(j=0; j<4; ++j)		fr->areal_buffs[i][j] = fr->areal_buffs[0][0] + (i*4+j)*0x110;	}#endif	/* now the different decwins... all of the same size, actually */	/* The MMX ones want 32byte alignment, which I'll try to ensure manually */	{		int decwin_size = (512+32)*sizeof(real);		if(fr->rawdecwin != NULL) free(fr->rawdecwin);#ifdef OPT_MMXORSSE#ifdef OPT_MULTI		if(fr->cpu_opts.class == mmxsse)		{#endif			/* decwin_mmx will share, decwins will be appended ... sizeof(float)==4 */			if(decwin_size < (512+32)*4) decwin_size = (512+32)*4;			decwin_size += (512+32)*4 + 31; /* the second window + alignment zone */			/* (512+32)*4/32 == 2176/32 == 68, so one decwin block retains alignment */#ifdef OPT_MULTI		}#endif#endif		fr->rawdecwin = (unsigned char*) malloc(decwin_size);		if(fr->rawdecwin == NULL) return -1;		fr->decwin = (real*) fr->rawdecwin;#ifdef OPT_MMXORSSE#ifdef OPT_MULTI		if(fr->cpu_opts.class == mmxsse)		{#endif			/* align decwin, assign that to decwin_mmx, append decwins */			/* I need to add to decwin what is missing to the next full 32 byte -- also I want to make gcc -pedantic happy... */			fr->decwin = aligned_pointer(fr->rawdecwin,real,32);			debug1("aligned decwin: %p", (void*)fr->decwin);			fr->decwin_mmx = (float*)fr->decwin;			fr->decwins = fr->decwin_mmx+512+32;#ifdef OPT_MULTI		}		else debug("no decwins/decwin_mmx for that class");#endif#endif	}	frame_buffers_reset(fr);	debug1("frame %p buffer done", (void*)fr);	return 0;}int frame_buffers_reset(mpg123_handle *fr){	fr->buffer.fill = 0; /* hm, reset buffer fill... did we do a flush? */	fr->bsnum = 0;	/* Wondering: could it be actually _wanted_ to retain buffer contents over different files? (special gapless / cut stuff) */	fr->bsbuf = fr->bsspace[1];	fr->bsbufold = fr->bsbuf;	memset(fr->bsspace, 0, 2*(MAXFRAMESIZE+512));	memset(fr->ssave, 0, 34);	memset(fr->rawbuffs, 0, fr->rawbuffss);	fr->hybrid_blc[0] = fr->hybrid_blc[1] = 0;	memset(fr->hybrid_block, 0, sizeof(real)*2*2*SBLIMIT*SSLIMIT);	/* Not totally, but quite, sure that decwin(s) doesn't need cleaning. */	return 0;}void frame_icy_reset(mpg123_handle* fr){	if(fr->icy.data != NULL) free(fr->icy.data);	fr->icy.data = NULL;	fr->icy.interval = 0;	fr->icy.next = 0;}/* Prepare the handle for a new track.   Reset variables, buffers... */int frame_reset(mpg123_handle* fr){	frame_buffers_reset(fr);	frame_fixed_reset(fr);	return 0;}/* Reset everythign except dynamic memory. */static void frame_fixed_reset(mpg123_handle *fr){	frame_icy_reset(fr);	open_bad(fr);	fr->to_decode = FALSE;	fr->to_ignore = FALSE;	fr->metaflags = 0;	fr->outblock = mpg123_safe_buffer();	fr->num = -1;	fr->clip = 0;	fr->oldhead = 0;	fr->firsthead = 0;	fr->vbr = MPG123_CBR;	fr->abr_rate = 0;	fr->track_frames = 0;	fr->track_samples = -1;	fr->framesize=0; 	fr->mean_frames = 0;	fr->mean_framesize = 0;	fr->freesize = 0;	fr->lastscale = -1;	fr->rva.level[0] = -1;	fr->rva.level[1] = -1;	fr->rva.gain[0] = 0;	fr->rva.gain[1] = 0;	fr->rva.peak[0] = 0;	fr->rva.peak[1] = 0;	fr->index.fill = 0;	fr->index.step = 1;	fr->fsizeold = 0;	fr->do_recover = 0;	fr->firstframe = 0;	fr->ignoreframe = fr->firstframe-IGNORESHIFT;	fr->lastframe = -1;	fr->fresh = 1;	fr->new_format = 0;#ifdef GAPLESS	frame_gapless_init(fr,0,0);	fr->lastoff = 0;	fr->firstoff = 0;#endif	fr->bo[0] = 1; /* the usual bo */	fr->bo[1] = 0; /* ditherindex */#ifdef OPT_I486	fr->bo[0] = fr->bo[1] = FIR_SIZE-1;#endif	reset_id3(fr);	reset_icy(&fr->icy);	/* ICY stuff should go into icy.c, eh? */	fr->icy.interval = 0;	fr->icy.next = 0;	fr->halfphase = 0; /* here or indeed only on first-time init? */}void frame_free_buffers(mpg123_handle *fr){	if(fr->rawbuffs != NULL) free(fr->rawbuffs);	fr->rawbuffs = NULL;	if(fr->rawdecwin != NULL) free(fr->rawdecwin);	fr->rawdecwin = NULL;	if(fr->conv16to8_buf != NULL) free(fr->conv16to8_buf);	fr->conv16to8_buf = NULL;}void frame_exit(mpg123_handle *fr){	if(fr->own_buffer && fr->buffer.data != NULL) free(fr->buffer.data);	fr->buffer.data = NULL;	frame_free_buffers(fr);	exit_id3(fr);	clear_icy(&fr->icy);}int mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi){	if(mh == NULL) return MPG123_ERR;	if(mi == NULL)	{		mh->err = MPG123_ERR_NULL;		return MPG123_ERR;	}	mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0);	mi->layer = mh->lay;	mi->rate = frame_freq(mh);	switch(mh->mode)	{		case 0: mi->mode = MPG123_M_STEREO; break;		case 1: mi->mode = MPG123_M_JOINT;  break;		case 2: mi->mode = MPG123_M_DUAL;   break;		case 3: mi->mode = MPG123_M_MONO;   break;		default: error("That mode cannot be!");	}	mi->mode_ext = mh->mode_ext;	mi->framesize = mh->framesize+4; /* Include header. */	mi->flags = 0;	if(mh->error_protection) mi->flags |= MPG123_CRC;	if(mh->copyright)        mi->flags |= MPG123_COPYRIGHT;	if(mh->extension)        mi->flags |= MPG123_PRIVATE;	if(mh->original)         mi->flags |= MPG123_ORIGINAL;	mi->emphasis = mh->emphasis;	mi->bitrate  = frame_bitrate(mh);	mi->abr_rate = mh->abr_rate;	mi->vbr = mh->vbr;	return MPG123_OK;}/*	find the best frame in index just before the wanted one, seek to there	then step to just before wanted one with read_frame	do not care tabout the stuff that was in buffer but not played back	everything that left the decoder is counted as played		Decide if you want low latency reaction and accurate timing info or stable long-time playback with buffer!*/off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame){	/* default is file start if no index position */	off_t gopos = 0;	*get_frame = 0;	if(fr->index.fill)	{		/* find in index */		size_t fi;		/* at index fi there is frame step*fi... */		fi = want_frame/fr->index.step;		if(fi >= fr->index.fill) fi = fr->index.fill - 1;		*get_frame = fi*fr->index.step;		gopos = fr->index.data[fi];	}	debug2("index: 0x%lx for frame %li", (unsigned long)gopos, (long) *get_frame);	return gopos;}off_t frame_ins2outs(mpg123_handle *fr, off_t ins){		off_t outs = 0;	switch(fr->down_sample)	{		case 0:		case 1:		case 2: outs = ins>>fr->down_sample; break;		case 3: outs = ntom_ins2outs(fr, ins); break;		default: error("Bad down_sample ... should not be possible!!");	}	return outs;}off_t frame_outs(mpg123_handle *fr, off_t num){	off_t outs = 0;	switch(fr->down_sample)	{		case 0:		case 1:		case 2: outs = (spf(fr)>>fr->down_sample)*num; break;		case 3: outs = ntom_frmouts(fr, num); break;		default: error("Bad down_sample ... should not be possible!!");	}	return outs;}off_t frame_offset(mpg123_handle *fr, off_t outs){	off_t num = 0;	switch(fr->down_sample)	{		case 0:		case 1:		case 2: num = outs/(spf(fr)>>fr->down_sample); break;		case 3: num = ntom_frameoff(fr, outs); break;		default: error("Bad down_sample ... should not be possible!!");	}	return num;}#ifdef GAPLESS/* input in _input_ samples */void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e){	fr->begin_s = b;	fr->end_s = e;	/* These will get proper values later, from above plus resampling info. */	fr->begin_os = 0;	fr->end_os = 0;	debug2("frame_gapless_init: from %lu to %lu samples", (long unsigned)fr->begin_s, (long unsigned)fr->end_s);}void frame_gapless_realinit(mpg123_handle *fr){

⌨️ 快捷键说明

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