Blame src/libmpg123/libmpg123.c

Packit c32a2d
/*
Packit c32a2d
	libmpg123: MPEG Audio Decoder library
Packit c32a2d
Packit c32a2d
	copyright 1995-2014 by the mpg123 project - free software under the terms of the LGPL 2.1
Packit c32a2d
	see COPYING and AUTHORS files in distribution or http://mpg123.org
Packit c32a2d
Packit c32a2d
*/
Packit c32a2d
Packit c32a2d
#include "mpg123lib_intern.h"
Packit c32a2d
#include "icy2utf8.h"
Packit c32a2d
#include "debug.h"
Packit c32a2d
Packit c32a2d
#include "gapless.h"
Packit c32a2d
/* Want accurate rounding function regardless of decoder setup. */
Packit c32a2d
#define FORCE_ACCURATE
Packit c32a2d
#include "sample.h"
Packit c32a2d
Packit c32a2d
#define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)
Packit c32a2d
Packit c32a2d
static int initialized = 0;
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_init(void)
Packit c32a2d
{
Packit c32a2d
	if((sizeof(short) != 2) || (sizeof(long) < 4)) return MPG123_BAD_TYPES;
Packit c32a2d
Packit c32a2d
	if(initialized) return MPG123_OK; /* no need to initialize twice */
Packit c32a2d
Packit c32a2d
#ifndef NO_LAYER12
Packit c32a2d
	init_layer12(); /* inits also shared tables with layer1 */
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_LAYER3
Packit c32a2d
	init_layer3();
Packit c32a2d
#endif
Packit c32a2d
	prepare_decode_tables();
Packit c32a2d
	check_decoders();
Packit c32a2d
	initialized = 1;
Packit c32a2d
#if (defined REAL_IS_FLOAT) && (defined IEEE_FLOAT)
Packit c32a2d
	/* This is rather pointless but it eases my mind to check that we did
Packit c32a2d
	   not enable the special rounding on a VAX or something. */
Packit c32a2d
	if(12346 != REAL_TO_SHORT_ACCURATE(12345.67f))
Packit c32a2d
	{
Packit c32a2d
		error("Bad IEEE 754 rounding. Re-build libmpg123 properly.");
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
#endif
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
void attribute_align_arg mpg123_exit(void)
Packit c32a2d
{
Packit c32a2d
	/* nothing yet, but something later perhaps */
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* create a new handle with specified decoder, decoder can be "", "auto" or NULL for auto-detection */
Packit c32a2d
mpg123_handle attribute_align_arg *mpg123_new(const char* decoder, int *error)
Packit c32a2d
{
Packit c32a2d
	return mpg123_parnew(NULL, decoder, error);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* ...the full routine with optional initial parameters to override defaults. */
Packit c32a2d
mpg123_handle attribute_align_arg *mpg123_parnew(mpg123_pars *mp, const char* decoder, int *error)
Packit c32a2d
{
Packit c32a2d
	mpg123_handle *fr = NULL;
Packit c32a2d
	int err = MPG123_OK;
Packit c32a2d
Packit c32a2d
	if(initialized) fr = (mpg123_handle*) malloc(sizeof(mpg123_handle));
Packit c32a2d
	else err = MPG123_NOT_INITIALIZED;
Packit c32a2d
	if(fr != NULL)
Packit c32a2d
	{
Packit c32a2d
		frame_init_par(fr, mp);
Packit c32a2d
		debug("cpu opt setting");
Packit c32a2d
		if(frame_cpu_opt(fr, decoder) != 1)
Packit c32a2d
		{
Packit c32a2d
			err = MPG123_BAD_DECODER;
Packit c32a2d
			frame_exit(fr);
Packit c32a2d
			free(fr);
Packit c32a2d
			fr = NULL;
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
	if(fr != NULL)
Packit c32a2d
	{
Packit c32a2d
		fr->decoder_change = 1;
Packit c32a2d
	}
Packit c32a2d
	else if(err == MPG123_OK) err = MPG123_OUT_OF_MEM;
Packit c32a2d
Packit c32a2d
	if(error != NULL) *error = err;
Packit c32a2d
	return fr;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_decoder(mpg123_handle *mh, const char* decoder)
Packit c32a2d
{
Packit c32a2d
	enum optdec dt = dectype(decoder);
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	if(dt == nodec)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_BAD_DECODER;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	if(dt == mh->cpu_opts.type) return MPG123_OK;
Packit c32a2d
Packit c32a2d
	/* Now really change. */
Packit c32a2d
	/* frame_exit(mh);
Packit c32a2d
	frame_init(mh); */
Packit c32a2d
	debug("cpu opt setting");
Packit c32a2d
	if(frame_cpu_opt(mh, decoder) != 1)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_BAD_DECODER;
Packit c32a2d
		frame_exit(mh);
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	/* New buffers for decoder are created in frame_buffers() */
Packit c32a2d
	if((frame_outbuffer(mh) != 0))
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_NO_BUFFERS;
Packit c32a2d
		frame_exit(mh);
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	/* Do _not_ call decode_update here! That is only allowed after a first MPEG frame has been met. */
Packit c32a2d
	mh->decoder_change = 1;
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_param(mpg123_handle *mh, enum mpg123_parms key, long val, double fval)
Packit c32a2d
{
Packit c32a2d
	int r;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	r = mpg123_par(&mh->p, key, val, fval);
Packit c32a2d
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
Packit c32a2d
	else
Packit c32a2d
	{ /* Special treatment for some settings. */
Packit c32a2d
#ifdef FRAME_INDEX
Packit c32a2d
		if(key == MPG123_INDEX_SIZE)
Packit c32a2d
		{ /* Apply frame index size and grow property on the fly. */
Packit c32a2d
			r = frame_index_setup(mh);
Packit c32a2d
			if(r != MPG123_OK) mh->err = MPG123_INDEX_FAIL;
Packit c32a2d
		}
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
		/* Feeder pool size is applied right away, reader will react to that. */
Packit c32a2d
		if(key == MPG123_FEEDPOOL || key == MPG123_FEEDBUFFER)
Packit c32a2d
		bc_poolsize(&mh->rdat.buffer, mh->p.feedpool, mh->p.feedbuffer);
Packit c32a2d
#endif
Packit c32a2d
	}
Packit c32a2d
	return r;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long val, double fval)
Packit c32a2d
{
Packit c32a2d
	int ret = MPG123_OK;
Packit c32a2d
Packit c32a2d
	if(mp == NULL) return MPG123_BAD_PARS;
Packit c32a2d
	switch(key)
Packit c32a2d
	{
Packit c32a2d
		case MPG123_VERBOSE:
Packit c32a2d
			mp->verbose = val;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FLAGS:
Packit c32a2d
#ifndef GAPLESS
Packit c32a2d
			if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS;
Packit c32a2d
#endif
Packit c32a2d
			if(ret == MPG123_OK) mp->flags = val;
Packit c32a2d
			debug1("set flags to 0x%lx", (unsigned long) mp->flags);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ADD_FLAGS:
Packit c32a2d
#ifndef GAPLESS
Packit c32a2d
			/* Enabling of gapless mode doesn't work when it's not there, but disabling (below) is no problem. */
Packit c32a2d
			if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS;
Packit c32a2d
			else
Packit c32a2d
#endif
Packit c32a2d
			mp->flags |= val;
Packit c32a2d
			debug1("set flags to 0x%lx", (unsigned long) mp->flags);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_REMOVE_FLAGS:
Packit c32a2d
			mp->flags &= ~val;
Packit c32a2d
			debug1("set flags to 0x%lx", (unsigned long) mp->flags);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FORCE_RATE: /* should this trigger something? */
Packit c32a2d
#ifdef NO_NTOM
Packit c32a2d
			if(val > 0)
Packit c32a2d
			ret = MPG123_BAD_RATE;
Packit c32a2d
#else
Packit c32a2d
			if(val > 96000) ret = MPG123_BAD_RATE;
Packit c32a2d
			else mp->force_rate = val < 0 ? 0 : val; /* >0 means enable, 0 disable */
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_DOWN_SAMPLE:
Packit c32a2d
#ifdef NO_DOWNSAMPLE
Packit c32a2d
			if(val != 0) ret = MPG123_BAD_RATE;
Packit c32a2d
#else
Packit c32a2d
			if(val < 0 || val > 2) ret = MPG123_BAD_RATE;
Packit c32a2d
			else mp->down_sample = (int)val;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_RVA:
Packit c32a2d
			if(val < 0 || val > MPG123_RVA_MAX) ret = MPG123_BAD_RVA;
Packit c32a2d
			else mp->rva = (int)val;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_DOWNSPEED:
Packit c32a2d
			mp->halfspeed = val < 0 ? 0 : val;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_UPSPEED:
Packit c32a2d
			mp->doublespeed = val < 0 ? 0 : val;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ICY_INTERVAL:
Packit c32a2d
#ifndef NO_ICY
Packit c32a2d
			mp->icy_interval = val > 0 ? val : 0;
Packit c32a2d
#else
Packit c32a2d
			if(val > 0) ret = MPG123_BAD_PARAM;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_OUTSCALE:
Packit c32a2d
			/* Choose the value that is non-zero, if any.
Packit c32a2d
			   Downscaling integers to 1.0 . */
Packit c32a2d
			mp->outscale = val == 0 ? fval : (double)val/SHORT_SCALE;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_TIMEOUT:
Packit c32a2d
#ifdef TIMEOUT_READ
Packit c32a2d
			mp->timeout = val >= 0 ? val : 0;
Packit c32a2d
#else
Packit c32a2d
			if(val > 0) ret = MPG123_NO_TIMEOUT;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_RESYNC_LIMIT:
Packit c32a2d
			mp->resync_limit = val;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_INDEX_SIZE:
Packit c32a2d
#ifdef FRAME_INDEX
Packit c32a2d
			mp->index_size = val;
Packit c32a2d
#else
Packit c32a2d
			ret = MPG123_NO_INDEX;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_PREFRAMES:
Packit c32a2d
			if(val >= 0) mp->preframes = val;
Packit c32a2d
			else ret = MPG123_BAD_VALUE;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FEEDPOOL:
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
			if(val >= 0) mp->feedpool = val;
Packit c32a2d
			else ret = MPG123_BAD_VALUE;
Packit c32a2d
#else
Packit c32a2d
			ret = MPG123_MISSING_FEATURE;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FEEDBUFFER:
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
			if(val > 0) mp->feedbuffer = val;
Packit c32a2d
			else ret = MPG123_BAD_VALUE;
Packit c32a2d
#else
Packit c32a2d
			ret = MPG123_MISSING_FEATURE;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		default:
Packit c32a2d
			ret = MPG123_BAD_PARAM;
Packit c32a2d
	}
Packit c32a2d
	return ret;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_getparam(mpg123_handle *mh, enum mpg123_parms key, long *val, double *fval)
Packit c32a2d
{
Packit c32a2d
	int r;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	r = mpg123_getpar(&mh->p, key, val, fval);
Packit c32a2d
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
Packit c32a2d
	return r;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, long *val, double *fval)
Packit c32a2d
{
Packit c32a2d
	int ret = 0;
Packit c32a2d
Packit c32a2d
	if(mp == NULL) return MPG123_BAD_PARS;
Packit c32a2d
	switch(key)
Packit c32a2d
	{
Packit c32a2d
		case MPG123_VERBOSE:
Packit c32a2d
			if(val) *val = mp->verbose;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FLAGS:
Packit c32a2d
		case MPG123_ADD_FLAGS:
Packit c32a2d
			if(val) *val = mp->flags;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FORCE_RATE:
Packit c32a2d
			if(val) 
Packit c32a2d
#ifdef NO_NTOM
Packit c32a2d
			*val = 0;
Packit c32a2d
#else
Packit c32a2d
			*val = mp->force_rate;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_DOWN_SAMPLE:
Packit c32a2d
			if(val) *val = mp->down_sample;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_RVA:
Packit c32a2d
			if(val) *val = mp->rva;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_DOWNSPEED:
Packit c32a2d
			if(val) *val = mp->halfspeed;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_UPSPEED:
Packit c32a2d
			if(val) *val = mp->doublespeed;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ICY_INTERVAL:
Packit c32a2d
#ifndef NO_ICY
Packit c32a2d
			if(val) *val = (long)mp->icy_interval;
Packit c32a2d
#else
Packit c32a2d
			if(val) *val = 0;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_OUTSCALE:
Packit c32a2d
			if(fval) *fval = mp->outscale;
Packit c32a2d
			if(val) *val = (long)(mp->outscale*SHORT_SCALE);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_RESYNC_LIMIT:
Packit c32a2d
			if(val) *val = mp->resync_limit;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_INDEX_SIZE:
Packit c32a2d
			if(val)
Packit c32a2d
#ifdef FRAME_INDEX
Packit c32a2d
			*val = mp->index_size;
Packit c32a2d
#else
Packit c32a2d
			*val = 0; /* graceful fallback: no index is index of zero size */
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_PREFRAMES:
Packit c32a2d
			*val = mp->preframes;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FEEDPOOL:
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
			*val = mp->feedpool;
Packit c32a2d
#else
Packit c32a2d
			ret = MPG123_MISSING_FEATURE;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FEEDBUFFER:
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
			*val = mp->feedbuffer;
Packit c32a2d
#else
Packit c32a2d
			ret = MPG123_MISSING_FEATURE;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		default:
Packit c32a2d
			ret = MPG123_BAD_PARAM;
Packit c32a2d
	}
Packit c32a2d
	return ret;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key, long *val, double *fval)
Packit c32a2d
{
Packit c32a2d
	int ret = MPG123_OK;
Packit c32a2d
	long theval = 0;
Packit c32a2d
	double thefval = 0.;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	switch(key)
Packit c32a2d
	{
Packit c32a2d
		case MPG123_ACCURATE:
Packit c32a2d
			theval = mh->state_flags & FRAME_ACCURATE;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FRANKENSTEIN:
Packit c32a2d
			theval = mh->state_flags & FRAME_FRANKENSTEIN;
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_BUFFERFILL:
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
		{
Packit c32a2d
			size_t sval = bc_fill(&mh->rdat.buffer);
Packit c32a2d
			theval = (long)sval;
Packit c32a2d
			if(theval < 0 || (size_t)theval != sval)
Packit c32a2d
			{
Packit c32a2d
				mh->err = MPG123_INT_OVERFLOW;
Packit c32a2d
				ret = MPG123_ERR;
Packit c32a2d
			}
Packit c32a2d
		}
Packit c32a2d
#else
Packit c32a2d
			mh->err = MPG123_MISSING_FEATURE;
Packit c32a2d
			ret = MPG123_ERR;
Packit c32a2d
#endif
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_FRESH_DECODER:
Packit c32a2d
			theval = mh->state_flags & FRAME_FRESH_DECODER;
Packit c32a2d
			mh->state_flags &= ~FRAME_FRESH_DECODER;
Packit c32a2d
		break;
Packit c32a2d
		default:
Packit c32a2d
			mh->err = MPG123_BAD_KEY;
Packit c32a2d
			ret = MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	if(val  != NULL) *val  = theval;
Packit c32a2d
	if(fval != NULL) *fval = thefval;
Packit c32a2d
Packit c32a2d
	return ret;
Packit c32a2d
}
Packit c32a2d
int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
Packit c32a2d
{
Packit c32a2d
#ifndef NO_EQUALIZER
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }
Packit c32a2d
	switch(channel)
Packit c32a2d
	{
Packit c32a2d
		case MPG123_LEFT|MPG123_RIGHT:
Packit c32a2d
			mh->equalizer[0][band] = mh->equalizer[1][band] = DOUBLE_TO_REAL(val);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_LEFT:  mh->equalizer[0][band] = DOUBLE_TO_REAL(val); break;
Packit c32a2d
		case MPG123_RIGHT: mh->equalizer[1][band] = DOUBLE_TO_REAL(val); break;
Packit c32a2d
		default:
Packit c32a2d
			mh->err=MPG123_BAD_CHANNEL;
Packit c32a2d
			return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	mh->have_eq_settings = TRUE;
Packit c32a2d
#endif
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band)
Packit c32a2d
{
Packit c32a2d
	double ret = 0.;
Packit c32a2d
#ifndef NO_EQUALIZER
Packit c32a2d
Packit c32a2d
	/* Handle this gracefully. When there is no band, it has no volume. */
Packit c32a2d
	if(mh != NULL && band > -1 && band < 32)
Packit c32a2d
	switch(channel)
Packit c32a2d
	{
Packit c32a2d
		case MPG123_LEFT|MPG123_RIGHT:
Packit c32a2d
			ret = 0.5*(REAL_TO_DOUBLE(mh->equalizer[0][band])+REAL_TO_DOUBLE(mh->equalizer[1][band]));
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_LEFT:  ret = REAL_TO_DOUBLE(mh->equalizer[0][band]); break;
Packit c32a2d
		case MPG123_RIGHT: ret = REAL_TO_DOUBLE(mh->equalizer[1][band]); break;
Packit c32a2d
		/* Default case is already handled: ret = 0 */
Packit c32a2d
	}
Packit c32a2d
#endif
Packit c32a2d
	return ret;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* plain file access, no http! */
Packit c32a2d
int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mpg123_close(mh);
Packit c32a2d
	return open_stream(mh, path, -1);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mpg123_close(mh);
Packit c32a2d
	return open_stream(mh, NULL, fd);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_open_handle(mpg123_handle *mh, void *iohandle)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mpg123_close(mh);
Packit c32a2d
	if(mh->rdat.r_read_handle == NULL)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_BAD_CUSTOM_IO;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	return open_stream_handle(mh, iohandle);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_open_feed(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mpg123_close(mh);
Packit c32a2d
	return open_feed(mh);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_replace_reader( mpg123_handle *mh,
Packit c32a2d
                           ssize_t (*r_read) (int, void *, size_t),
Packit c32a2d
                           off_t   (*r_lseek)(int, off_t, int) )
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mpg123_close(mh);
Packit c32a2d
	mh->rdat.r_read = r_read;
Packit c32a2d
	mh->rdat.r_lseek = r_lseek;
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_replace_reader_handle( mpg123_handle *mh,
Packit c32a2d
                           ssize_t (*r_read) (void*, void *, size_t),
Packit c32a2d
                           off_t   (*r_lseek)(void*, off_t, int),
Packit c32a2d
                           void    (*cleanup)(void*)  )
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mpg123_close(mh);
Packit c32a2d
	mh->rdat.r_read_handle = r_read;
Packit c32a2d
	mh->rdat.r_lseek_handle = r_lseek;
Packit c32a2d
	mh->rdat.cleanup_handle = cleanup;
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Update decoding engine for
Packit c32a2d
   a) a new choice of decoder
Packit c32a2d
   b) a changed native format of the MPEG stream
Packit c32a2d
   ... calls are only valid after parsing some MPEG frame! */
Packit c32a2d
int decode_update(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	long native_rate;
Packit c32a2d
	int b;
Packit c32a2d
Packit c32a2d
	if(mh->num < 0)
Packit c32a2d
	{
Packit c32a2d
		if(!(mh->p.flags & MPG123_QUIET)) error("decode_update() has been called before reading the first MPEG frame! Internal programming error.");
Packit c32a2d
Packit c32a2d
		mh->err = MPG123_BAD_DECODER_SETUP;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	mh->state_flags |= FRAME_FRESH_DECODER;
Packit c32a2d
	native_rate = frame_freq(mh);
Packit c32a2d
Packit c32a2d
	b = frame_output_format(mh); /* Select the new output format based on given constraints. */
Packit c32a2d
	if(b < 0) return MPG123_ERR;
Packit c32a2d
Packit c32a2d
	if(b == 1) mh->new_format = 1; /* Store for later... */
Packit c32a2d
Packit c32a2d
	debug3("updating decoder structure with native rate %li and af.rate %li (new format: %i)", native_rate, mh->af.rate, mh->new_format);
Packit c32a2d
	if(mh->af.rate == native_rate) mh->down_sample = 0;
Packit c32a2d
	else if(mh->af.rate == native_rate>>1) mh->down_sample = 1;
Packit c32a2d
	else if(mh->af.rate == native_rate>>2) mh->down_sample = 2;
Packit c32a2d
	else mh->down_sample = 3; /* flexible (fixed) rate */
Packit c32a2d
	switch(mh->down_sample)
Packit c32a2d
	{
Packit c32a2d
		case 0:
Packit c32a2d
		case 1:
Packit c32a2d
		case 2:
Packit c32a2d
			mh->down_sample_sblimit = SBLIMIT>>(mh->down_sample);
Packit c32a2d
			/* With downsampling I get less samples per frame */
Packit c32a2d
			mh->outblock = outblock_bytes(mh, (mh->spf>>mh->down_sample));
Packit c32a2d
		break;
Packit c32a2d
#ifndef NO_NTOM
Packit c32a2d
		case 3:
Packit c32a2d
		{
Packit c32a2d
			if(synth_ntom_set_step(mh) != 0) return -1;
Packit c32a2d
			if(frame_freq(mh) > mh->af.rate)
Packit c32a2d
			{
Packit c32a2d
				mh->down_sample_sblimit = SBLIMIT * mh->af.rate;
Packit c32a2d
				mh->down_sample_sblimit /= frame_freq(mh);
Packit c32a2d
			}
Packit c32a2d
			else mh->down_sample_sblimit = SBLIMIT;
Packit c32a2d
			mh->outblock = outblock_bytes(mh,
Packit c32a2d
			                 ( ( NTOM_MUL-1+mh->spf
Packit c32a2d
			                   * (((size_t)NTOM_MUL*mh->af.rate)/frame_freq(mh))
Packit c32a2d
			                 )/NTOM_MUL ));
Packit c32a2d
		}
Packit c32a2d
		break;
Packit c32a2d
#endif
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	if(!(mh->p.flags & MPG123_FORCE_MONO))
Packit c32a2d
	{
Packit c32a2d
		if(mh->af.channels == 1) mh->single = SINGLE_MIX;
Packit c32a2d
		else mh->single = SINGLE_STEREO;
Packit c32a2d
	}
Packit c32a2d
	else mh->single = (mh->p.flags & MPG123_FORCE_MONO)-1;
Packit c32a2d
	if(set_synth_functions(mh) != 0) return -1;;
Packit c32a2d
Packit c32a2d
	/* The needed size of output buffer may have changed. */
Packit c32a2d
	if(frame_outbuffer(mh) != MPG123_OK) return -1;
Packit c32a2d
Packit c32a2d
	do_rva(mh);
Packit c32a2d
	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);
Packit c32a2d
Packit c32a2d
	return 0;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
size_t attribute_align_arg mpg123_safe_buffer(void)
Packit c32a2d
{
Packit c32a2d
	/* real is the largest possible output (it's 32bit float, 32bit int or 64bit double). */
Packit c32a2d
	return sizeof(real)*2*1152*NTOM_MAX;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
size_t attribute_align_arg mpg123_outblock(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	/* Try to be helpful and never return zero output block size. */
Packit c32a2d
	if(mh != NULL && mh->outblock > 0) return mh->outblock;
Packit c32a2d
	else return mpg123_safe_buffer();
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Read in the next frame we actually want for decoding.
Packit c32a2d
   This includes skipping/ignoring frames, in additon to skipping junk in the parser. */
Packit c32a2d
static int get_next_frame(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int change = mh->decoder_change;
Packit c32a2d
	/* Ensure we got proper decoder for ignoring frames.
Packit c32a2d
	   Header can be changed from seeking around. But be careful: Only after at
Packit c32a2d
	   least one frame got read, decoder update makes sense. */
Packit c32a2d
	if(mh->header_change > 1 && mh->num >= 0)
Packit c32a2d
	{
Packit c32a2d
		change = 1;
Packit c32a2d
		mh->header_change = 0;
Packit c32a2d
		debug("starting with big header change");
Packit c32a2d
		if(decode_update(mh) < 0)
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	do
Packit c32a2d
	{
Packit c32a2d
		int b;
Packit c32a2d
		/* Decode & discard some frame(s) before beginning. */
Packit c32a2d
		if(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe)
Packit c32a2d
		{
Packit c32a2d
			debug1("ignoring frame %li", (long)mh->num);
Packit c32a2d
			/* Decoder structure must be current! decode_update has been called before... */
Packit c32a2d
			(mh->do_layer)(mh); mh->buffer.fill = 0;
Packit c32a2d
#ifndef NO_NTOM
Packit c32a2d
			/* The ignored decoding may have failed. Make sure ntom stays consistent. */
Packit c32a2d
			if(mh->down_sample == 3) ntom_set_ntom(mh, mh->num+1);
Packit c32a2d
#endif
Packit c32a2d
			mh->to_ignore = mh->to_decode = FALSE;
Packit c32a2d
		}
Packit c32a2d
		/* Read new frame data; possibly breaking out here for MPG123_NEED_MORE. */
Packit c32a2d
		debug("read frame");
Packit c32a2d
		mh->to_decode = FALSE;
Packit c32a2d
		b = read_frame(mh); /* That sets to_decode only if a full frame was read. */
Packit c32a2d
		debug4("read of frame %li returned %i (to_decode=%i) at sample %li", (long)mh->num, b, mh->to_decode, (long)mpg123_tell(mh));
Packit c32a2d
		if(b == MPG123_NEED_MORE) return MPG123_NEED_MORE; /* need another call with data */
Packit c32a2d
		else if(b <= 0)
Packit c32a2d
		{
Packit c32a2d
			/* More sophisticated error control? */
Packit c32a2d
			if(b==0 || (mh->rdat.filelen >= 0 && mh->rdat.filepos == mh->rdat.filelen))
Packit c32a2d
			{ /* We simply reached the end. */
Packit c32a2d
				mh->track_frames = mh->num + 1;
Packit c32a2d
				debug("What about updating/checking gapless sample count here?");
Packit c32a2d
				return MPG123_DONE;
Packit c32a2d
			}
Packit c32a2d
			else return MPG123_ERR; /* Some real error. */
Packit c32a2d
		}
Packit c32a2d
		/* Now, there should be new data to decode ... and also possibly new stream properties */
Packit c32a2d
		if(mh->header_change > 1)
Packit c32a2d
		{
Packit c32a2d
			debug("big header change");
Packit c32a2d
			change = 1;
Packit c32a2d
			mh->header_change = 0;
Packit c32a2d
			/* Need to update decoder structure right away since frame might need to
Packit c32a2d
			   be decoded on next loop iteration for properly ignoring its output. */
Packit c32a2d
			if(decode_update(mh) < 0)
Packit c32a2d
			return MPG123_ERR;
Packit c32a2d
		}
Packit c32a2d
		/* Now some accounting: Look at the numbers and decide if we want this frame. */
Packit c32a2d
		++mh->playnum;
Packit c32a2d
		/* Plain skipping without decoding, only when frame is not ignored on next cycle. */
Packit c32a2d
		if(mh->num < mh->firstframe || (mh->p.doublespeed && (mh->playnum % mh->p.doublespeed)))
Packit c32a2d
		{
Packit c32a2d
			if(!(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe))
Packit c32a2d
			{
Packit c32a2d
				frame_skip(mh);
Packit c32a2d
				/* Should one fix NtoM here or not?
Packit c32a2d
				   It is not work the trouble for doublespeed, but what with leading frames? */
Packit c32a2d
			}
Packit c32a2d
		}
Packit c32a2d
		/* Or, we are finally done and have a new frame. */
Packit c32a2d
		else break;
Packit c32a2d
	} while(1);
Packit c32a2d
Packit c32a2d
	/* If we reach this point, we got a new frame ready to be decoded.
Packit c32a2d
	   All other situations resulted in returns from the loop. */
Packit c32a2d
	if(change)
Packit c32a2d
	{
Packit c32a2d
		mh->decoder_change = 0;
Packit c32a2d
		if(mh->fresh)
Packit c32a2d
		{
Packit c32a2d
#ifdef GAPLESS
Packit c32a2d
			int b=0;
Packit c32a2d
			/* Prepare offsets for gapless decoding. */
Packit c32a2d
			debug1("preparing gapless stuff with native rate %li", frame_freq(mh));
Packit c32a2d
			frame_gapless_realinit(mh);
Packit c32a2d
			frame_set_frameseek(mh, mh->num);
Packit c32a2d
#endif
Packit c32a2d
			mh->fresh = 0;
Packit c32a2d
#ifdef GAPLESS
Packit c32a2d
			/* Could this possibly happen? With a real big gapless offset... */
Packit c32a2d
			if(mh->num < mh->firstframe) b = get_next_frame(mh);
Packit c32a2d
			if(b < 0) return b; /* Could be error, need for more, new format... */
Packit c32a2d
#endif
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Assumption: A buffer full of zero samples can be constructed by repetition of this byte.
Packit c32a2d
   Oh, and it handles some format conversion.
Packit c32a2d
   Only to be used by decode_the_frame() ... */
Packit c32a2d
static int zero_byte(mpg123_handle *fr)
Packit c32a2d
{
Packit c32a2d
#ifndef NO_8BIT
Packit c32a2d
	return fr->af.encoding & MPG123_ENC_8 ? fr->conv16to8[0] : 0;
Packit c32a2d
#else
Packit c32a2d
	return 0; /* All normal signed formats have the zero here (even in byte form -- that may be an assumption for your funny machine...). */
Packit c32a2d
#endif
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	Not part of the api. This just decodes the frame and fills missing bits with zeroes.
Packit c32a2d
	There can be frames that are broken and thus make do_layer() fail.
Packit c32a2d
*/
Packit c32a2d
static void decode_the_frame(mpg123_handle *fr)
Packit c32a2d
{
Packit c32a2d
	size_t needed_bytes = decoder_synth_bytes(fr, frame_expect_outsamples(fr));
Packit c32a2d
	fr->clip += (fr->do_layer)(fr);
Packit c32a2d
	/*fprintf(stderr, "frame %"OFF_P": got %"SIZE_P" / %"SIZE_P"\n", fr->num,(size_p)fr->buffer.fill, (size_p)needed_bytes);*/
Packit c32a2d
	/* There could be less data than promised.
Packit c32a2d
	   Also, then debugging, we look out for coding errors that could result in _more_ data than expected. */
Packit c32a2d
#ifdef DEBUG
Packit c32a2d
	if(fr->buffer.fill != needed_bytes)
Packit c32a2d
	{
Packit c32a2d
#endif
Packit c32a2d
		if(fr->buffer.fill < needed_bytes)
Packit c32a2d
		{
Packit c32a2d
			if(VERBOSE2)
Packit c32a2d
			fprintf(stderr, "Note: broken frame %li, filling up with %"SIZE_P" zeroes, from %"SIZE_P"\n", (long)fr->num, (size_p)(needed_bytes-fr->buffer.fill), (size_p)fr->buffer.fill);
Packit c32a2d
Packit c32a2d
			/*
Packit c32a2d
				One could do a loop with individual samples instead... but zero is zero
Packit c32a2d
				Actually, that is wrong: zero is mostly a series of null bytes,
Packit c32a2d
				but we have funny 8bit formats that have a different opinion on zero...
Packit c32a2d
				Unsigned 16 or 32 bit formats are handled later.
Packit c32a2d
			*/
Packit c32a2d
			memset( fr->buffer.data + fr->buffer.fill, zero_byte(fr), needed_bytes - fr->buffer.fill );
Packit c32a2d
Packit c32a2d
			fr->buffer.fill = needed_bytes;
Packit c32a2d
#ifndef NO_NTOM
Packit c32a2d
			/* ntom_val will be wrong when the decoding wasn't carried out completely */
Packit c32a2d
			ntom_set_ntom(fr, fr->num+1);
Packit c32a2d
#endif
Packit c32a2d
		}
Packit c32a2d
#ifdef DEBUG
Packit c32a2d
		else
Packit c32a2d
		{
Packit c32a2d
			if(NOQUIET)
Packit c32a2d
			error2("I got _more_ bytes than expected (%"SIZE_P" / %"SIZE_P"), that should not be possible!", (size_p)fr->buffer.fill, (size_p)needed_bytes);
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
#endif
Packit c32a2d
	postprocess_buffer(fr);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	Decode the current frame into the frame structure's buffer, accessible at the location stored in <audio>, with <bytes> bytes available.
Packit c32a2d
	<num> will contain the last decoded frame number. This function should be called after mpg123_framebyframe_next positioned the stream at a
Packit c32a2d
	valid mp3 frame. The buffer contents will get lost on the next call to mpg123_framebyframe_next or mpg123_framebyframe_decode.
Packit c32a2d
	returns
Packit c32a2d
	MPG123_OK -- successfully decoded or ignored the frame, you get your output data or in case of ignored frames 0 bytes
Packit c32a2d
	MPG123_DONE -- decoding finished, should not happen
Packit c32a2d
	MPG123_ERR -- some error occured.
Packit c32a2d
	MPG123_ERR_NULL -- audio or bytes are not pointing to valid storage addresses
Packit c32a2d
	MPG123_BAD_HANDLE -- mh has not been initialized
Packit c32a2d
	MPG123_NO_SPACE -- not enough space in buffer for safe decoding, should not happen
Packit c32a2d
*/
Packit c32a2d
int attribute_align_arg mpg123_framebyframe_decode(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
Packit c32a2d
{
Packit c32a2d
	if(bytes == NULL) return MPG123_ERR_NULL;
Packit c32a2d
	if(audio == NULL) return MPG123_ERR_NULL;
Packit c32a2d
	if(mh == NULL)    return MPG123_BAD_HANDLE;
Packit c32a2d
	if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
Packit c32a2d
Packit c32a2d
	*bytes = 0;
Packit c32a2d
	mh->buffer.fill = 0; /* always start fresh */
Packit c32a2d
	if(!mh->to_decode) return MPG123_OK;
Packit c32a2d
Packit c32a2d
	if(num != NULL) *num = mh->num;
Packit c32a2d
	debug("decoding");
Packit c32a2d
	decode_the_frame(mh);
Packit c32a2d
	mh->to_decode = mh->to_ignore = FALSE;
Packit c32a2d
	mh->buffer.p = mh->buffer.data;
Packit c32a2d
	FRAME_BUFFERCHECK(mh);
Packit c32a2d
	*audio = mh->buffer.p;
Packit c32a2d
	*bytes = mh->buffer.fill;
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	Find, read and parse the next mp3 frame while skipping junk and parsing id3 tags, lame headers, etc.
Packit c32a2d
	Prepares everything for decoding using mpg123_framebyframe_decode.
Packit c32a2d
	returns
Packit c32a2d
	MPG123_OK -- new frame was read and parsed, call mpg123_framebyframe_decode to actually decode
Packit c32a2d
	MPG123_NEW_FORMAT -- new frame was read, it results in changed output format, call mpg123_framebyframe_decode to actually decode
Packit c32a2d
	MPG123_BAD_HANDLE -- mh has not been initialized
Packit c32a2d
	MPG123_NEED_MORE  -- more input data is needed to advance to the next frame. supply more input data using mpg123_feed
Packit c32a2d
*/
Packit c32a2d
int attribute_align_arg mpg123_framebyframe_next(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mh->to_decode = mh->to_ignore = FALSE;
Packit c32a2d
	mh->buffer.fill = 0;
Packit c32a2d
Packit c32a2d
	b = get_next_frame(mh);
Packit c32a2d
	if(b < 0) return b;
Packit c32a2d
	debug1("got next frame, %i", mh->to_decode);
Packit c32a2d
Packit c32a2d
	/* mpg123_framebyframe_decode will return MPG123_OK with 0 bytes decoded if mh->to_decode is 0 */
Packit c32a2d
	if(!mh->to_decode)
Packit c32a2d
		return MPG123_OK;
Packit c32a2d
Packit c32a2d
	if(mh->new_format)
Packit c32a2d
	{
Packit c32a2d
		debug("notifiying new format");
Packit c32a2d
		mh->new_format = 0;
Packit c32a2d
		return MPG123_NEW_FORMAT;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	Put _one_ decoded frame into the frame structure's buffer, accessible at the location stored in <audio>, with <bytes> bytes available.
Packit c32a2d
	The buffer contents will be lost on next call to mpg123_decode_frame.
Packit c32a2d
	MPG123_OK -- successfully decoded the frame, you get your output data
Packit c32a2d
	MPg123_DONE -- This is it. End.
Packit c32a2d
	MPG123_ERR -- some error occured...
Packit c32a2d
	MPG123_NEW_FORMAT -- new frame was read, it results in changed output format -> will be decoded on next call
Packit c32a2d
	MPG123_NEED_MORE  -- that should not happen as this function is intended for in-library stream reader but if you force it...
Packit c32a2d
	MPG123_NO_SPACE   -- not enough space in buffer for safe decoding, also should not happen
Packit c32a2d
Packit c32a2d
	num will be updated to the last decoded frame number (may possibly _not_ increase, p.ex. when format changed).
Packit c32a2d
*/
Packit c32a2d
int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
Packit c32a2d
{
Packit c32a2d
	if(bytes != NULL) *bytes = 0;
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
Packit c32a2d
	mh->buffer.fill = 0; /* always start fresh */
Packit c32a2d
	while(TRUE)
Packit c32a2d
	{
Packit c32a2d
		/* decode if possible */
Packit c32a2d
		if(mh->to_decode)
Packit c32a2d
		{
Packit c32a2d
			if(mh->new_format)
Packit c32a2d
			{
Packit c32a2d
				debug("notifiying new format");
Packit c32a2d
				mh->new_format = 0;
Packit c32a2d
				return MPG123_NEW_FORMAT;
Packit c32a2d
			}
Packit c32a2d
			if(num != NULL) *num = mh->num;
Packit c32a2d
			debug("decoding");
Packit c32a2d
Packit c32a2d
			decode_the_frame(mh);
Packit c32a2d
Packit c32a2d
			mh->to_decode = mh->to_ignore = FALSE;
Packit c32a2d
			mh->buffer.p = mh->buffer.data;
Packit c32a2d
			FRAME_BUFFERCHECK(mh);
Packit c32a2d
			if(audio != NULL) *audio = mh->buffer.p;
Packit c32a2d
			if(bytes != NULL) *bytes = mh->buffer.fill;
Packit c32a2d
Packit c32a2d
			return MPG123_OK;
Packit c32a2d
		}
Packit c32a2d
		else
Packit c32a2d
		{
Packit c32a2d
			int b = get_next_frame(mh);
Packit c32a2d
			if(b < 0) return b;
Packit c32a2d
			debug1("got next frame, %i", mh->to_decode);
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_read(mpg123_handle *mh, unsigned char *out, size_t size, size_t *done)
Packit c32a2d
{
Packit c32a2d
	return mpg123_decode(mh, NULL, 0, out, size, done);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
	if(size > 0)
Packit c32a2d
	{
Packit c32a2d
		if(in != NULL)
Packit c32a2d
		{
Packit c32a2d
			if(feed_more(mh, in, size) != 0) return MPG123_ERR;
Packit c32a2d
			else
Packit c32a2d
			{
Packit c32a2d
				/* The need for more data might have triggered an error.
Packit c32a2d
				   This one is outdated now with the new data. */
Packit c32a2d
				if(mh->err == MPG123_ERR_READER) mh->err = MPG123_OK;
Packit c32a2d
Packit c32a2d
				return MPG123_OK;
Packit c32a2d
			}
Packit c32a2d
		}
Packit c32a2d
		else
Packit c32a2d
		{
Packit c32a2d
			mh->err = MPG123_NULL_BUFFER;
Packit c32a2d
			return MPG123_ERR;
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
#else
Packit c32a2d
	mh->err = MPG123_MISSING_FEATURE;
Packit c32a2d
	return MPG123_ERR;
Packit c32a2d
#endif
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	The old picture:
Packit c32a2d
	while(1) {
Packit c32a2d
		len = read(0,buf,16384);
Packit c32a2d
		if(len <= 0)
Packit c32a2d
			break;
Packit c32a2d
		ret = decodeMP3(&mp,buf,len,out,8192,&size);
Packit c32a2d
		while(ret == MP3_OK) {
Packit c32a2d
			write(1,out,size);
Packit c32a2d
			ret = decodeMP3(&mp,NULL,0,out,8192,&size);
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
*/
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done)
Packit c32a2d
{
Packit c32a2d
	int ret = MPG123_OK;
Packit c32a2d
	size_t mdone = 0;
Packit c32a2d
Packit c32a2d
	if(done != NULL) *done = 0;
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
	if(inmemsize > 0 && mpg123_feed(mh, inmemory, inmemsize) != MPG123_OK)
Packit c32a2d
	{
Packit c32a2d
		ret = MPG123_ERR;
Packit c32a2d
		goto decodeend;
Packit c32a2d
	}
Packit c32a2d
	if(outmemory == NULL) outmemsize = 0; /* Not just give error, give chance to get a status message. */
Packit c32a2d
Packit c32a2d
	while(ret == MPG123_OK)
Packit c32a2d
	{
Packit c32a2d
		debug4("decode loop, fill %i (%li vs. %li); to_decode: %i", (int)mh->buffer.fill, (long)mh->num, (long)mh->firstframe, mh->to_decode);
Packit c32a2d
		/* Decode a frame that has been read before.
Packit c32a2d
		   This only happens when buffer is empty! */
Packit c32a2d
		if(mh->to_decode)
Packit c32a2d
		{
Packit c32a2d
			if(mh->new_format)
Packit c32a2d
			{
Packit c32a2d
				debug("notifiying new format");
Packit c32a2d
				mh->new_format = 0;
Packit c32a2d
				ret = MPG123_NEW_FORMAT;
Packit c32a2d
				goto decodeend;
Packit c32a2d
			}
Packit c32a2d
			if(mh->buffer.size - mh->buffer.fill < mh->outblock)
Packit c32a2d
			{
Packit c32a2d
				ret = MPG123_NO_SPACE;
Packit c32a2d
				goto decodeend;
Packit c32a2d
			}
Packit c32a2d
			decode_the_frame(mh);
Packit c32a2d
			mh->to_decode = mh->to_ignore = FALSE;
Packit c32a2d
			mh->buffer.p = mh->buffer.data;
Packit c32a2d
			debug2("decoded frame %li, got %li samples in buffer", (long)mh->num, (long)(mh->buffer.fill / (samples_to_bytes(mh, 1))));
Packit c32a2d
			FRAME_BUFFERCHECK(mh);
Packit c32a2d
		}
Packit c32a2d
		if(mh->buffer.fill) /* Copy (part of) the decoded data to the caller's buffer. */
Packit c32a2d
		{
Packit c32a2d
			/* get what is needed - or just what is there */
Packit c32a2d
			int a = mh->buffer.fill > (outmemsize - mdone) ? outmemsize - mdone : mh->buffer.fill;
Packit c32a2d
			debug4("buffer fill: %i; copying %i (%i - %li)", (int)mh->buffer.fill, a, (int)outmemsize, (long)mdone);
Packit c32a2d
			memcpy(outmemory, mh->buffer.p, a);
Packit c32a2d
			/* less data in frame buffer, less needed, output pointer increase, more data given... */
Packit c32a2d
			mh->buffer.fill -= a;
Packit c32a2d
			outmemory  += a;
Packit c32a2d
			mdone += a;
Packit c32a2d
			mh->buffer.p += a;
Packit c32a2d
			if(!(outmemsize > mdone)) goto decodeend;
Packit c32a2d
		}
Packit c32a2d
		else /* If we didn't have data, get a new frame. */
Packit c32a2d
		{
Packit c32a2d
			int b = get_next_frame(mh);
Packit c32a2d
			if(b < 0){ ret = b; goto decodeend; }
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
decodeend:
Packit c32a2d
	if(done != NULL) *done = mdone;
Packit c32a2d
	return ret;
Packit c32a2d
#else
Packit c32a2d
	mh->err = MPG123_MISSING_FEATURE;
Packit c32a2d
	return MPG123_ERR;
Packit c32a2d
#endif
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
long attribute_align_arg mpg123_clip(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	long ret = 0;
Packit c32a2d
Packit c32a2d
	if(mh != NULL)
Packit c32a2d
	{
Packit c32a2d
		ret = mh->clip;
Packit c32a2d
		mh->clip = 0;
Packit c32a2d
	}
Packit c32a2d
	return ret;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Simples: Track needs initializtion if no initial frame has been read yet. */
Packit c32a2d
#define track_need_init(mh) ((mh)->num < 0)
Packit c32a2d
Packit c32a2d
static int init_track(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(track_need_init(mh))
Packit c32a2d
	{
Packit c32a2d
		/* Fresh track, need first frame for basic info. */
Packit c32a2d
		int b = get_next_frame(mh);
Packit c32a2d
		if(b < 0) return b;
Packit c32a2d
	}
Packit c32a2d
	return 0;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	if(mi == NULL)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_ERR_NULL;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	b = init_track(mh);
Packit c32a2d
	if(b < 0) return b;
Packit c32a2d
Packit c32a2d
	mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0);
Packit c32a2d
	mi->layer = mh->lay;
Packit c32a2d
	mi->rate = frame_freq(mh);
Packit c32a2d
	switch(mh->mode)
Packit c32a2d
	{
Packit c32a2d
		case 0: mi->mode = MPG123_M_STEREO; break;
Packit c32a2d
		case 1: mi->mode = MPG123_M_JOINT;  break;
Packit c32a2d
		case 2: mi->mode = MPG123_M_DUAL;   break;
Packit c32a2d
		case 3: mi->mode = MPG123_M_MONO;   break;
Packit c32a2d
		default: error("That mode cannot be!");
Packit c32a2d
	}
Packit c32a2d
	mi->mode_ext = mh->mode_ext;
Packit c32a2d
	mi->framesize = mh->framesize+4; /* Include header. */
Packit c32a2d
	mi->flags = 0;
Packit c32a2d
	if(mh->error_protection) mi->flags |= MPG123_CRC;
Packit c32a2d
	if(mh->copyright)        mi->flags |= MPG123_COPYRIGHT;
Packit c32a2d
	if(mh->extension)        mi->flags |= MPG123_PRIVATE;
Packit c32a2d
	if(mh->original)         mi->flags |= MPG123_ORIGINAL;
Packit c32a2d
	mi->emphasis = mh->emphasis;
Packit c32a2d
	mi->bitrate  = frame_bitrate(mh);
Packit c32a2d
	mi->abr_rate = mh->abr_rate;
Packit c32a2d
	mi->vbr = mh->vbr;
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_getformat2( mpg123_handle *mh
Packit c32a2d
,	long *rate, int *channels, int *encoding, int clear_flag )
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	b = init_track(mh);
Packit c32a2d
	if(b < 0) return b;
Packit c32a2d
Packit c32a2d
	if(rate != NULL) *rate = mh->af.rate;
Packit c32a2d
	if(channels != NULL) *channels = mh->af.channels;
Packit c32a2d
	if(encoding != NULL) *encoding = mh->af.encoding;
Packit c32a2d
	if(clear_flag) mh->new_format = 0;
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
Packit c32a2d
{
Packit c32a2d
	return mpg123_getformat2(mh, rate, channels, encoding, 1);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t attribute_align_arg mpg123_timeframe(mpg123_handle *mh, double seconds)
Packit c32a2d
{
Packit c32a2d
	off_t b;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_ERR;
Packit c32a2d
	b = init_track(mh);
Packit c32a2d
	if(b<0) return b;
Packit c32a2d
	return (off_t)(seconds/mpg123_tpf(mh));
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	Now, where are we? We need to know the last decoded frame... and what's left of it in buffer.
Packit c32a2d
	The current frame number can mean the last decoded frame or the to-be-decoded frame.
Packit c32a2d
	If mh->to_decode, then mh->num frames have been decoded, the frame mh->num now coming next.
Packit c32a2d
	If not, we have the possibility of mh->num+1 frames being decoded or nothing at all.
Packit c32a2d
	Then, there is firstframe...when we didn't reach it yet, then the next data will come from there.
Packit c32a2d
	mh->num starts with -1
Packit c32a2d
*/
Packit c32a2d
off_t attribute_align_arg mpg123_tell(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_ERR;
Packit c32a2d
	if(track_need_init(mh)) return 0;
Packit c32a2d
	/* Now we have all the info at hand. */
Packit c32a2d
	debug5("tell: %li/%i first %li buffer %lu; frame_outs=%li", (long)mh->num, mh->to_decode, (long)mh->firstframe, (unsigned long)mh->buffer.fill, (long)frame_outs(mh, mh->num));
Packit c32a2d
Packit c32a2d
	{ /* Funny block to keep C89 happy. */
Packit c32a2d
		off_t pos = 0;
Packit c32a2d
		if((mh->num < mh->firstframe) || (mh->num == mh->firstframe && mh->to_decode))
Packit c32a2d
		{ /* We are at the beginning, expect output from firstframe on. */
Packit c32a2d
			pos = frame_outs(mh, mh->firstframe);
Packit c32a2d
#ifdef GAPLESS
Packit c32a2d
			pos += mh->firstoff;
Packit c32a2d
#endif
Packit c32a2d
		}
Packit c32a2d
		else if(mh->to_decode)
Packit c32a2d
		{ /* We start fresh with this frame. Buffer should be empty, but we make sure to count it in.  */
Packit c32a2d
			pos = frame_outs(mh, mh->num) - bytes_to_samples(mh, mh->buffer.fill);
Packit c32a2d
		}
Packit c32a2d
		else
Packit c32a2d
		{ /* We serve what we have in buffer and then the beginning of next frame... */
Packit c32a2d
			pos = frame_outs(mh, mh->num+1) - bytes_to_samples(mh, mh->buffer.fill);
Packit c32a2d
		}
Packit c32a2d
		/* Substract padding and delay from the beginning. */
Packit c32a2d
		pos = SAMPLE_ADJUST(mh,pos);
Packit c32a2d
		/* Negative sample offsets are not right, less than nothing is still nothing. */
Packit c32a2d
		return pos>0 ? pos : 0;
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t attribute_align_arg mpg123_tellframe(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_ERR;
Packit c32a2d
	if(mh->num < mh->firstframe) return mh->firstframe;
Packit c32a2d
	if(mh->to_decode) return mh->num;
Packit c32a2d
	/* Consider firstoff? */
Packit c32a2d
	return mh->buffer.fill ? mh->num : mh->num + 1;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t attribute_align_arg mpg123_tell_stream(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_ERR;
Packit c32a2d
	/* mh->rd is at least a bad_reader, so no worry. */
Packit c32a2d
	return mh->rd->tell(mh);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
static int do_the_seek(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	off_t fnum = SEEKFRAME(mh);
Packit c32a2d
	mh->buffer.fill = 0;
Packit c32a2d
Packit c32a2d
	/* If we are inside the ignoreframe - firstframe window, we may get away without actual seeking. */
Packit c32a2d
	if(mh->num < mh->firstframe)
Packit c32a2d
	{
Packit c32a2d
		mh->to_decode = FALSE; /* In any case, don't decode the current frame, perhaps ignore instead. */
Packit c32a2d
		if(mh->num > fnum) return MPG123_OK;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	/* If we are already there, we are fine either for decoding or for ignoring. */
Packit c32a2d
	if(mh->num == fnum && (mh->to_decode || fnum < mh->firstframe)) return MPG123_OK;
Packit c32a2d
	/* We have the frame before... just go ahead as normal. */
Packit c32a2d
	if(mh->num == fnum-1)
Packit c32a2d
	{
Packit c32a2d
		mh->to_decode = FALSE;
Packit c32a2d
		return MPG123_OK;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	/* OK, real seeking follows... clear buffers and go for it. */
Packit c32a2d
	frame_buffers_reset(mh);
Packit c32a2d
#ifndef NO_NTOM
Packit c32a2d
	if(mh->down_sample == 3)
Packit c32a2d
	{
Packit c32a2d
		ntom_set_ntom(mh, fnum);
Packit c32a2d
		debug3("fixed ntom for frame %"OFF_P" to %lu, num=%"OFF_P, (off_p)fnum, mh->ntom_val[0], (off_p)mh->num);
Packit c32a2d
	}
Packit c32a2d
#endif
Packit c32a2d
	b = mh->rd->seek_frame(mh, fnum);
Packit c32a2d
	if(mh->header_change > 1)
Packit c32a2d
	{
Packit c32a2d
		if(decode_update(mh) < 0) return MPG123_ERR;
Packit c32a2d
		mh->header_change = 0;
Packit c32a2d
	}
Packit c32a2d
	debug1("seek_frame returned: %i", b);
Packit c32a2d
	if(b<0) return b;
Packit c32a2d
	/* Only mh->to_ignore is TRUE. */
Packit c32a2d
	if(mh->num < mh->firstframe) mh->to_decode = FALSE;
Packit c32a2d
Packit c32a2d
	mh->playnum = mh->num;
Packit c32a2d
	return 0;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t attribute_align_arg mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	off_t pos;
Packit c32a2d
Packit c32a2d
	pos = mpg123_tell(mh); /* adjusted samples */
Packit c32a2d
	/* pos < 0 also can mean that simply a former seek failed at the lower levels.
Packit c32a2d
	  In that case, we only allow absolute seeks. */
Packit c32a2d
	if(pos < 0 && whence != SEEK_SET)
Packit c32a2d
	{ /* Unless we got the obvious error of NULL handle, this is a special seek failure. */
Packit c32a2d
		if(mh != NULL) mh->err = MPG123_NO_RELSEEK;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	if((b=init_track(mh)) < 0) return b;
Packit c32a2d
	switch(whence)
Packit c32a2d
	{
Packit c32a2d
		case SEEK_CUR: pos += sampleoff; break;
Packit c32a2d
		case SEEK_SET: pos  = sampleoff; break;
Packit c32a2d
		case SEEK_END:
Packit c32a2d
			/* When we do not know the end already, we can try to find it. */
Packit c32a2d
			if(mh->track_frames < 1 && (mh->rdat.flags & READER_SEEKABLE))
Packit c32a2d
			mpg123_scan(mh);
Packit c32a2d
			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(mh,frame_outs(mh, mh->track_frames)) - sampleoff;
Packit c32a2d
#ifdef GAPLESS
Packit c32a2d
			else if(mh->end_os > 0) pos = SAMPLE_ADJUST(mh,mh->end_os) - sampleoff;
Packit c32a2d
#endif
Packit c32a2d
			else
Packit c32a2d
			{
Packit c32a2d
				mh->err = MPG123_NO_SEEK_FROM_END;
Packit c32a2d
				return MPG123_ERR;
Packit c32a2d
			}
Packit c32a2d
		break;
Packit c32a2d
		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	if(pos < 0) pos = 0;
Packit c32a2d
	/* pos now holds the wanted sample offset in adjusted samples */
Packit c32a2d
	frame_set_seek(mh, SAMPLE_UNADJUST(mh,pos));
Packit c32a2d
	pos = do_the_seek(mh);
Packit c32a2d
	if(pos < 0) return pos;
Packit c32a2d
Packit c32a2d
	return mpg123_tell(mh);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	A bit more tricky... libmpg123 does not do the seeking itself.
Packit c32a2d
	All it can do is to ignore frames until the wanted one is there.
Packit c32a2d
	The caller doesn't know where a specific frame starts and mpg123 also only knows the general region after it scanned the file.
Packit c32a2d
	Well, it is tricky...
Packit c32a2d
*/
Packit c32a2d
off_t attribute_align_arg mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	off_t pos;
Packit c32a2d
Packit c32a2d
	pos = mpg123_tell(mh); /* adjusted samples */
Packit c32a2d
	debug3("seek from %li to %li (whence=%i)", (long)pos, (long)sampleoff, whence);
Packit c32a2d
	/* The special seek error handling does not apply here... there is no lowlevel I/O. */
Packit c32a2d
	if(pos < 0) return pos; /* mh == NULL is covered in mpg123_tell() */
Packit c32a2d
#ifndef NO_FEEDER
Packit c32a2d
	if(input_offset == NULL)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_NULL_POINTER;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	if((b=init_track(mh)) < 0) return b; /* May need more to do anything at all. */
Packit c32a2d
Packit c32a2d
	switch(whence)
Packit c32a2d
	{
Packit c32a2d
		case SEEK_CUR: pos += sampleoff; break;
Packit c32a2d
		case SEEK_SET: pos  = sampleoff; break;
Packit c32a2d
		case SEEK_END:
Packit c32a2d
			if(mh->track_frames > 0) pos = SAMPLE_ADJUST(mh,frame_outs(mh, mh->track_frames)) - sampleoff;
Packit c32a2d
#ifdef GAPLESS
Packit c32a2d
			else if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh,mh->end_os) - sampleoff;
Packit c32a2d
#endif
Packit c32a2d
			else
Packit c32a2d
			{
Packit c32a2d
				mh->err = MPG123_NO_SEEK_FROM_END;
Packit c32a2d
				return MPG123_ERR;
Packit c32a2d
			}
Packit c32a2d
		break;
Packit c32a2d
		default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	if(pos < 0) pos = 0;
Packit c32a2d
	frame_set_seek(mh, SAMPLE_UNADJUST(mh,pos));
Packit c32a2d
	pos = SEEKFRAME(mh);
Packit c32a2d
	mh->buffer.fill = 0;
Packit c32a2d
Packit c32a2d
	/* Shortcuts without modifying input stream. */
Packit c32a2d
	*input_offset = mh->rdat.buffer.fileoff + mh->rdat.buffer.size;
Packit c32a2d
	if(mh->num < mh->firstframe) mh->to_decode = FALSE;
Packit c32a2d
	if(mh->num == pos && mh->to_decode) goto feedseekend;
Packit c32a2d
	if(mh->num == pos-1) goto feedseekend;
Packit c32a2d
	/* Whole way. */
Packit c32a2d
	*input_offset = feed_set_pos(mh, frame_index_find(mh, SEEKFRAME(mh), &pos));
Packit c32a2d
	mh->num = pos-1; /* The next read frame will have num = pos. */
Packit c32a2d
	if(*input_offset < 0) return MPG123_ERR;
Packit c32a2d
Packit c32a2d
feedseekend:
Packit c32a2d
	return mpg123_tell(mh);
Packit c32a2d
#else
Packit c32a2d
	mh->err = MPG123_MISSING_FEATURE;
Packit c32a2d
	return MPG123_ERR;
Packit c32a2d
#endif
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t attribute_align_arg mpg123_seek_frame(mpg123_handle *mh, off_t offset, int whence)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	off_t pos = 0;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_ERR;
Packit c32a2d
	if((b=init_track(mh)) < 0) return b;
Packit c32a2d
Packit c32a2d
	/* Could play games here with to_decode... */
Packit c32a2d
	pos = mh->num;
Packit c32a2d
	switch(whence)
Packit c32a2d
	{
Packit c32a2d
		case SEEK_CUR: pos += offset; break;
Packit c32a2d
		case SEEK_SET: pos  = offset; break;
Packit c32a2d
		case SEEK_END:
Packit c32a2d
			if(mh->track_frames > 0) pos = mh->track_frames - offset;
Packit c32a2d
			else
Packit c32a2d
			{
Packit c32a2d
				mh->err = MPG123_NO_SEEK_FROM_END;
Packit c32a2d
				return MPG123_ERR;
Packit c32a2d
			}
Packit c32a2d
		break;
Packit c32a2d
		default:
Packit c32a2d
			mh->err = MPG123_BAD_WHENCE;
Packit c32a2d
			return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	if(pos < 0) pos = 0;
Packit c32a2d
	/* Not limiting the possible position on end for the chance that there might be more to the stream than announced via track_frames. */
Packit c32a2d
Packit c32a2d
	frame_set_frameseek(mh, pos);
Packit c32a2d
	pos = do_the_seek(mh);
Packit c32a2d
	if(pos < 0) return pos;
Packit c32a2d
Packit c32a2d
	return mpg123_tellframe(mh);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_set_filesize(mpg123_handle *mh, off_t size)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	mh->rdat.filelen = size;
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t attribute_align_arg mpg123_framelength(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	if(mh == NULL)
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	b = init_track(mh);
Packit c32a2d
	if(b<0)
Packit c32a2d
		return b;
Packit c32a2d
	if(mh->track_frames > 0)
Packit c32a2d
		return mh->track_frames;
Packit c32a2d
	if(mh->rdat.filelen > 0)
Packit c32a2d
	{ /* A bad estimate. Ignoring tags 'n stuff. */
Packit c32a2d
		double bpf = mh->mean_framesize > 0.
Packit c32a2d
			? mh->mean_framesize
Packit c32a2d
			: compute_bpf(mh);
Packit c32a2d
		return (off_t)((double)(mh->rdat.filelen)/bpf+0.5);
Packit c32a2d
	}
Packit c32a2d
	/* Last resort: No view of the future, can at least count the frames that
Packit c32a2d
	   were already parsed. */
Packit c32a2d
	if(mh->num > -1)
Packit c32a2d
		return mh->num+1;
Packit c32a2d
	/* Giving up. */
Packit c32a2d
	return MPG123_ERR;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t attribute_align_arg mpg123_length(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	off_t length;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_ERR;
Packit c32a2d
	b = init_track(mh);
Packit c32a2d
	if(b<0) return b;
Packit c32a2d
	if(mh->track_samples > -1) length = mh->track_samples;
Packit c32a2d
	else if(mh->track_frames > 0) length = mh->track_frames*mh->spf;
Packit c32a2d
	else if(mh->rdat.filelen > 0) /* Let the case of 0 length just fall through. */
Packit c32a2d
	{
Packit c32a2d
		/* A bad estimate. Ignoring tags 'n stuff. */
Packit c32a2d
		double bpf = mh->mean_framesize ? mh->mean_framesize : compute_bpf(mh);
Packit c32a2d
		length = (off_t)((double)(mh->rdat.filelen)/bpf*mh->spf);
Packit c32a2d
	}
Packit c32a2d
	else if(mh->rdat.filelen == 0) return mpg123_tell(mh); /* we could be in feeder mode */
Packit c32a2d
	else return MPG123_ERR; /* No length info there! */
Packit c32a2d
Packit c32a2d
	debug1("mpg123_length: internal sample length: %"OFF_P, (off_p)length);
Packit c32a2d
Packit c32a2d
	length = frame_ins2outs(mh, length);
Packit c32a2d
	debug1("mpg123_length: external sample length: %"OFF_P, (off_p)length);
Packit c32a2d
	length = SAMPLE_ADJUST(mh,length);
Packit c32a2d
	return length;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_scan(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int b;
Packit c32a2d
	off_t oldpos;
Packit c32a2d
	off_t track_frames = 0;
Packit c32a2d
	off_t track_samples = 0;
Packit c32a2d
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	if(!(mh->rdat.flags & READER_SEEKABLE)){ mh->err = MPG123_NO_SEEK; return MPG123_ERR; }
Packit c32a2d
	/* Scan through the _whole_ file, since the current position is no count but computed assuming constant samples per frame. */
Packit c32a2d
	/* Also, we can just keep the current buffer and seek settings. Just operate on input frames here. */
Packit c32a2d
	debug("issuing scan");
Packit c32a2d
	b = init_track(mh); /* mh->num >= 0 !! */
Packit c32a2d
	if(b<0)
Packit c32a2d
	{
Packit c32a2d
		if(b == MPG123_DONE) return MPG123_OK;
Packit c32a2d
		else return MPG123_ERR; /* Must be error here, NEED_MORE is not for seekable streams. */
Packit c32a2d
	}
Packit c32a2d
	oldpos = mpg123_tell(mh);
Packit c32a2d
	b = mh->rd->seek_frame(mh, 0);
Packit c32a2d
	if(b<0 || mh->num != 0) return MPG123_ERR;
Packit c32a2d
	/* One frame must be there now. */
Packit c32a2d
	track_frames = 1;
Packit c32a2d
	track_samples = mh->spf; /* Internal samples. */
Packit c32a2d
	debug("TODO: We should disable gapless code when encountering inconsistent mh->spf!");
Packit c32a2d
	debug("      ... at least unset MPG123_ACCURATE.");
Packit c32a2d
	/* Do not increment mh->track_frames in the loop as tha would confuse Frankenstein detection. */
Packit c32a2d
	while(read_frame(mh) == 1)
Packit c32a2d
	{
Packit c32a2d
		++track_frames;
Packit c32a2d
		track_samples += mh->spf;
Packit c32a2d
	}
Packit c32a2d
	mh->track_frames = track_frames;
Packit c32a2d
	mh->track_samples = track_samples;
Packit c32a2d
	debug2("Scanning yielded %"OFF_P" track samples, %"OFF_P" frames.", (off_p)mh->track_samples, (off_p)mh->track_frames);
Packit c32a2d
#ifdef GAPLESS
Packit c32a2d
	/* Also, think about usefulness of that extra value track_samples ... it could be used for consistency checking. */
Packit c32a2d
	if(mh->p.flags & MPG123_GAPLESS) frame_gapless_update(mh, mh->track_samples);
Packit c32a2d
#endif
Packit c32a2d
	return mpg123_seek(mh, oldpos, SEEK_SET) >= 0 ? MPG123_OK : MPG123_ERR;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_meta_check(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh != NULL) return mh->metaflags;
Packit c32a2d
	else return 0;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
void attribute_align_arg mpg123_meta_free(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return;
Packit c32a2d
Packit c32a2d
	reset_id3(mh);
Packit c32a2d
	reset_icy(&mh->icy);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2)
Packit c32a2d
{
Packit c32a2d
	if(v1 != NULL) *v1 = NULL;
Packit c32a2d
	if(v2 != NULL) *v2 = NULL;
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	if(mh->metaflags & MPG123_ID3)
Packit c32a2d
	{
Packit c32a2d
		id3_link(mh);
Packit c32a2d
		if(v1 != NULL && mh->rdat.flags & READER_ID3TAG) *v1 = (mpg123_id3v1*) mh->id3buf;
Packit c32a2d
		if(v2 != NULL)
Packit c32a2d
#ifdef NO_ID3V2
Packit c32a2d
		*v2 = NULL;
Packit c32a2d
#else
Packit c32a2d
		*v2 = &mh->id3v2;
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
		mh->metaflags |= MPG123_ID3;
Packit c32a2d
		mh->metaflags &= ~MPG123_NEW_ID3;
Packit c32a2d
	}
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_icy(mpg123_handle *mh, char **icy_meta)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
#ifndef NO_ICY
Packit c32a2d
	if(icy_meta == NULL)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_NULL_POINTER;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	*icy_meta = NULL;
Packit c32a2d
Packit c32a2d
	if(mh->metaflags & MPG123_ICY)
Packit c32a2d
	{
Packit c32a2d
		*icy_meta = mh->icy.data;
Packit c32a2d
		mh->metaflags |= MPG123_ICY;
Packit c32a2d
		mh->metaflags &= ~MPG123_NEW_ICY;
Packit c32a2d
	}
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
#else
Packit c32a2d
	mh->err = MPG123_MISSING_FEATURE;
Packit c32a2d
	return MPG123_ERR;
Packit c32a2d
#endif
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
char* attribute_align_arg mpg123_icy2utf8(const char* icy_text)
Packit c32a2d
{
Packit c32a2d
#ifndef NO_ICY
Packit c32a2d
	return icy2utf8(icy_text, 0);
Packit c32a2d
#else
Packit c32a2d
	return NULL;
Packit c32a2d
#endif
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* That one is always defined... it's not worth it to remove it for NO_ID3V2. */
Packit c32a2d
enum mpg123_text_encoding attribute_align_arg mpg123_enc_from_id3(unsigned char id3_enc_byte)
Packit c32a2d
{
Packit c32a2d
	switch(id3_enc_byte)
Packit c32a2d
	{
Packit c32a2d
		case mpg123_id3_latin1:   return mpg123_text_latin1;
Packit c32a2d
		case mpg123_id3_utf16bom: return mpg123_text_utf16bom; /* ID3v2.3 has UCS-2 with BOM here. */
Packit c32a2d
		case mpg123_id3_utf16be:  return mpg123_text_utf16be;
Packit c32a2d
		case mpg123_id3_utf8:     return mpg123_text_utf8;
Packit c32a2d
		default: return mpg123_text_unknown;
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
#ifndef NO_STRING
Packit c32a2d
int mpg123_store_utf8(mpg123_string *sb, enum mpg123_text_encoding enc, const unsigned char *source, size_t source_size)
Packit c32a2d
{
Packit c32a2d
	switch(enc)
Packit c32a2d
	{
Packit c32a2d
#ifndef NO_ID3V2
Packit c32a2d
		/* The encodings we get from ID3v2 tags. */
Packit c32a2d
		case mpg123_text_utf8:
Packit c32a2d
			id3_to_utf8(sb, mpg123_id3_utf8, source, source_size, 0);
Packit c32a2d
		break;
Packit c32a2d
		case mpg123_text_latin1:
Packit c32a2d
			id3_to_utf8(sb, mpg123_id3_latin1, source, source_size, 0);
Packit c32a2d
		break;
Packit c32a2d
		case mpg123_text_utf16bom:
Packit c32a2d
		case mpg123_text_utf16:
Packit c32a2d
			id3_to_utf8(sb, mpg123_id3_utf16bom, source, source_size, 0);
Packit c32a2d
		break;
Packit c32a2d
		/* Special because one cannot skip zero bytes here. */
Packit c32a2d
		case mpg123_text_utf16be:
Packit c32a2d
			id3_to_utf8(sb, mpg123_id3_utf16be, source, source_size, 0);
Packit c32a2d
		break;
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_ICY
Packit c32a2d
		/* ICY encoding... */
Packit c32a2d
		case mpg123_text_icy:
Packit c32a2d
		case mpg123_text_cp1252:
Packit c32a2d
		{
Packit c32a2d
			mpg123_free_string(sb);
Packit c32a2d
			/* Paranoia: Make sure that the string ends inside the buffer... */
Packit c32a2d
			if(source[source_size-1] == 0)
Packit c32a2d
			{
Packit c32a2d
				/* Convert from ICY encoding... with force applied or not. */
Packit c32a2d
				char *tmpstring = icy2utf8((const char*)source, enc == mpg123_text_cp1252 ? 1 : 0);
Packit c32a2d
				if(tmpstring != NULL)
Packit c32a2d
				{
Packit c32a2d
					mpg123_set_string(sb, tmpstring);
Packit c32a2d
					free(tmpstring);
Packit c32a2d
				}
Packit c32a2d
			}
Packit c32a2d
		}
Packit c32a2d
		break;
Packit c32a2d
#endif
Packit c32a2d
		default:
Packit c32a2d
			mpg123_free_string(sb);
Packit c32a2d
	}
Packit c32a2d
	/* At least a trailing null of some form should be there... */
Packit c32a2d
	return (sb->fill > 0) ? 1 : 0;
Packit c32a2d
}
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	if(offsets == NULL || step == NULL || fill == NULL)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_BAD_INDEX_PAR;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
#ifdef FRAME_INDEX
Packit c32a2d
	*offsets = mh->index.data;
Packit c32a2d
	*step    = mh->index.step;
Packit c32a2d
	*fill    = mh->index.fill;
Packit c32a2d
#else
Packit c32a2d
	*offsets = NULL;
Packit c32a2d
	*step    = 0;
Packit c32a2d
	*fill    = 0;
Packit c32a2d
#endif
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_set_index(mpg123_handle *mh, off_t *offsets, off_t step, size_t fill)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
#ifdef FRAME_INDEX
Packit c32a2d
	if(step == 0)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_BAD_INDEX_PAR;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	if(fi_set(&mh->index, offsets, step, fill) == -1)
Packit c32a2d
	{
Packit c32a2d
		mh->err = MPG123_OUT_OF_MEM;
Packit c32a2d
		return MPG123_ERR;
Packit c32a2d
	}
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
#else
Packit c32a2d
	mh->err = MPG123_MISSING_FEATURE;
Packit c32a2d
	return MPG123_ERR;
Packit c32a2d
#endif
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_close(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	/* mh->rd is never NULL! */
Packit c32a2d
	if(mh->rd->close != NULL) mh->rd->close(mh);
Packit c32a2d
Packit c32a2d
	if(mh->new_format)
Packit c32a2d
	{
Packit c32a2d
		debug("Hey, we are closing a track before the new format has been queried...");
Packit c32a2d
		invalidate_format(&mh->af);
Packit c32a2d
		mh->new_format = 0;
Packit c32a2d
	}
Packit c32a2d
	/* Always reset the frame buffers on close, so we cannot forget it in funky opening routines (wrappers, even). */
Packit c32a2d
	frame_reset(mh);
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
void attribute_align_arg mpg123_delete(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh != NULL)
Packit c32a2d
	{
Packit c32a2d
		mpg123_close(mh);
Packit c32a2d
		frame_exit(mh); /* free buffers in frame */
Packit c32a2d
		free(mh); /* free struct; cast? */
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
static const char *mpg123_error[] =
Packit c32a2d
{
Packit c32a2d
	"No error... (code 0)",
Packit c32a2d
	"Unable to set up output format! (code 1)",
Packit c32a2d
	"Invalid channel number specified. (code 2)",
Packit c32a2d
	"Invalid sample rate specified. (code 3)",
Packit c32a2d
	"Unable to allocate memory for 16 to 8 converter table! (code 4)",
Packit c32a2d
	"Bad parameter id! (code 5)",
Packit c32a2d
	"Bad buffer given -- invalid pointer or too small size. (code 6)",
Packit c32a2d
	"Out of memory -- some malloc() failed. (code 7)",
Packit c32a2d
	"You didn't initialize the library! (code 8)",
Packit c32a2d
	"Invalid decoder choice. (code 9)",
Packit c32a2d
	"Invalid mpg123 handle. (code 10)",
Packit c32a2d
	"Unable to initialize frame buffers (out of memory?)! (code 11)",
Packit c32a2d
	"Invalid RVA mode. (code 12)",
Packit c32a2d
	"This build doesn't support gapless decoding. (code 13)",
Packit c32a2d
	"Not enough buffer space. (code 14)",
Packit c32a2d
	"Incompatible numeric data types. (code 15)",
Packit c32a2d
	"Bad equalizer band. (code 16)",
Packit c32a2d
	"Null pointer given where valid storage address needed. (code 17)",
Packit c32a2d
	"Error reading the stream. (code 18)",
Packit c32a2d
	"Cannot seek from end (end is not known). (code 19)",
Packit c32a2d
	"Invalid 'whence' for seek function. (code 20)",
Packit c32a2d
	"Build does not support stream timeouts. (code 21)",
Packit c32a2d
	"File access error. (code 22)",
Packit c32a2d
	"Seek not supported by stream. (code 23)",
Packit c32a2d
	"No stream opened. (code 24)",
Packit c32a2d
	"Bad parameter handle. (code 25)",
Packit c32a2d
	"Invalid parameter addresses for index retrieval. (code 26)",
Packit c32a2d
	"Lost track in the bytestream and did not attempt resync. (code 27)",
Packit c32a2d
	"Failed to find valid MPEG data within limit on resync. (code 28)",
Packit c32a2d
	"No 8bit encoding possible. (code 29)",
Packit c32a2d
	"Stack alignment is not good. (code 30)",
Packit c32a2d
	"You gave me a NULL buffer? (code 31)",
Packit c32a2d
	"File position is screwed up, please do an absolute seek (code 32)",
Packit c32a2d
	"Inappropriate NULL-pointer provided.",
Packit c32a2d
	"Bad key value given.",
Packit c32a2d
	"There is no frame index (disabled in this build).",
Packit c32a2d
	"Frame index operation failed.",
Packit c32a2d
	"Decoder setup failed (invalid combination of settings?)",
Packit c32a2d
	"Feature not in this build."
Packit c32a2d
	,"Some bad value has been provided."
Packit c32a2d
	,"Low-level seeking has failed (call to lseek(), usually)."
Packit c32a2d
	,"Custom I/O obviously not prepared."
Packit c32a2d
	,"Overflow in LFS (large file support) conversion."
Packit c32a2d
	,"Overflow in integer conversion."
Packit c32a2d
};
Packit c32a2d
Packit c32a2d
const char* attribute_align_arg mpg123_plain_strerror(int errcode)
Packit c32a2d
{
Packit c32a2d
	if(errcode >= 0 && errcode < sizeof(mpg123_error)/sizeof(char*))
Packit c32a2d
	return mpg123_error[errcode];
Packit c32a2d
	else switch(errcode)
Packit c32a2d
	{
Packit c32a2d
		case MPG123_ERR:
Packit c32a2d
			return "A generic mpg123 error.";
Packit c32a2d
		case MPG123_DONE:
Packit c32a2d
			return "Message: I am done with this track.";
Packit c32a2d
		case MPG123_NEED_MORE:
Packit c32a2d
			return "Message: Feed me more input data!";
Packit c32a2d
		case MPG123_NEW_FORMAT:
Packit c32a2d
			return "Message: Prepare for a changed audio format (query the new one)!";
Packit c32a2d
		default:
Packit c32a2d
			return "I have no idea - an unknown error code!";
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_errcode(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	if(mh != NULL) return mh->err;
Packit c32a2d
	return MPG123_BAD_HANDLE;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
const char* attribute_align_arg mpg123_strerror(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	return mpg123_plain_strerror(mpg123_errcode(mh));
Packit c32a2d
}