Blame src/libmpg123/format.c

Packit c32a2d
/*
Packit c32a2d
	format:routines to deal with audio (output) format
Packit c32a2d
Packit c32a2d
	copyright 2008-14 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
	initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now
Packit c32a2d
Packit c32a2d
	A Major change from mpg123 <= 1.18 is that all encodings are only really
Packit c32a2d
	disabled when done so via specific build configuration. Otherwise, the
Packit c32a2d
	missing support of decoders to produce a certain format is augmented by
Packit c32a2d
	postprocessing that converts the samples. This means happily creating
Packit c32a2d
	data with higher resolution from less accurate decoder output.
Packit c32a2d
Packit c32a2d
	The main point is to still offer float encoding when the decoding core uses
Packit c32a2d
	a fixed point representation that has only 16 bit output. Actually, that's
Packit c32a2d
	the only point: A fixed-point build needs to create float from 16 bit, also
Packit c32a2d
	32 or 24 bit from the same source. That's all there is to it: Everything else
Packit c32a2d
	is covered by fallback synth functions. It may be a further step to check if
Packit c32a2d
	there are cases where conversion in postprocessing works well enough to omit
Packit c32a2d
	a certain specialized decoder ... but usually, they are justified by some
Packit c32a2d
	special way to get from float to integer to begin with.
Packit c32a2d
Packit c32a2d
	I won't cover the case of faking double output with float/s16 decoders here.
Packit c32a2d
	Double precision output is a thing for experimental builds anyway. Mostly
Packit c32a2d
	theoretical and without a point.
Packit c32a2d
*/
Packit c32a2d
Packit c32a2d
#include "mpg123lib_intern.h"
Packit c32a2d
#include "debug.h"
Packit c32a2d
Packit c32a2d
/* static int chans[NUM_CHANNELS] = { 1 , 2 }; */
Packit c32a2d
static const long my_rates[MPG123_RATES] = /* only the standard rates */
Packit c32a2d
{
Packit c32a2d
	 8000, 11025, 12000, 
Packit c32a2d
	16000, 22050, 24000,
Packit c32a2d
	32000, 44100, 48000,
Packit c32a2d
};
Packit c32a2d
Packit c32a2d
static const int my_encodings[MPG123_ENCODINGS] =
Packit c32a2d
{
Packit c32a2d
	MPG123_ENC_SIGNED_16,
Packit c32a2d
	MPG123_ENC_UNSIGNED_16,
Packit c32a2d
	MPG123_ENC_SIGNED_32,
Packit c32a2d
	MPG123_ENC_UNSIGNED_32,
Packit c32a2d
	MPG123_ENC_SIGNED_24,
Packit c32a2d
	MPG123_ENC_UNSIGNED_24,
Packit c32a2d
	/* Floating point range, see below. */
Packit c32a2d
	MPG123_ENC_FLOAT_32,
Packit c32a2d
	MPG123_ENC_FLOAT_64,
Packit c32a2d
	/* 8 bit range, see below. */
Packit c32a2d
	MPG123_ENC_SIGNED_8,
Packit c32a2d
	MPG123_ENC_UNSIGNED_8,
Packit c32a2d
	MPG123_ENC_ULAW_8,
Packit c32a2d
	MPG123_ENC_ALAW_8
Packit c32a2d
};
Packit c32a2d
Packit c32a2d
/* Make that match the above table.
Packit c32a2d
   And yes, I still don't like this kludgy stuff. */
Packit c32a2d
/* range[0] <= i < range[1] for forced floating point */
Packit c32a2d
static const int enc_float_range[2] = { 6, 8 };
Packit c32a2d
/* same for 8 bit encodings */
Packit c32a2d
static const int enc_8bit_range[2] = { 8, 12 };
Packit c32a2d
Packit c32a2d
/*
Packit c32a2d
	Only one type of float is supported.
Packit c32a2d
	Actually, double is a very special experimental case not occuring in normal
Packit c32a2d
	builds. Might actually get rid of it.
Packit c32a2d
Packit c32a2d
	Remember here: Also with REAL_IS_FIXED, I want to be able to produce float
Packit c32a2d
	output (f32) via post-processing.
Packit c32a2d
*/
Packit c32a2d
# ifdef REAL_IS_DOUBLE
Packit c32a2d
#  define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_64
Packit c32a2d
# else
Packit c32a2d
#  define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32
Packit c32a2d
# endif
Packit c32a2d
Packit c32a2d
/* The list of actually possible encodings. */
Packit c32a2d
static const int good_encodings[] =
Packit c32a2d
{
Packit c32a2d
#ifndef NO_16BIT
Packit c32a2d
	MPG123_ENC_SIGNED_16,
Packit c32a2d
	MPG123_ENC_UNSIGNED_16,
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_32BIT
Packit c32a2d
	MPG123_ENC_SIGNED_32,
Packit c32a2d
	MPG123_ENC_UNSIGNED_32,
Packit c32a2d
	MPG123_ENC_SIGNED_24,
Packit c32a2d
	MPG123_ENC_UNSIGNED_24,
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_REAL
Packit c32a2d
	MPG123_FLOAT_ENC,
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_8BIT
Packit c32a2d
	MPG123_ENC_SIGNED_8,
Packit c32a2d
	MPG123_ENC_UNSIGNED_8,
Packit c32a2d
	MPG123_ENC_ULAW_8,
Packit c32a2d
	MPG123_ENC_ALAW_8
Packit c32a2d
#endif
Packit c32a2d
};
Packit c32a2d
Packit c32a2d
/* Check if encoding is a valid one in this build.
Packit c32a2d
   ...lazy programming: linear search. */
Packit c32a2d
static int good_enc(const int enc)
Packit c32a2d
{
Packit c32a2d
	size_t i;
Packit c32a2d
	for(i=0; i
Packit c32a2d
	if(enc == good_encodings[i]) return TRUE;
Packit c32a2d
Packit c32a2d
	return FALSE;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
void attribute_align_arg mpg123_rates(const long **list, size_t *number)
Packit c32a2d
{
Packit c32a2d
	if(list   != NULL) *list   = my_rates;
Packit c32a2d
	if(number != NULL) *number = sizeof(my_rates)/sizeof(long);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Now that's a bit tricky... One build of the library knows only a subset of the encodings. */
Packit c32a2d
void attribute_align_arg mpg123_encodings(const int **list, size_t *number)
Packit c32a2d
{
Packit c32a2d
	if(list   != NULL) *list   = good_encodings;
Packit c32a2d
	if(number != NULL) *number = sizeof(good_encodings)/sizeof(int);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_encsize(int encoding)
Packit c32a2d
{
Packit c32a2d
	return MPG123_SAMPLESIZE(encoding);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/*	char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */
Packit c32a2d
Packit c32a2d
static int rate2num(mpg123_pars *mp, long r)
Packit c32a2d
{
Packit c32a2d
	int i;
Packit c32a2d
	for(i=0;i
Packit c32a2d
#ifndef NO_NTOM
Packit c32a2d
	if(mp && mp->force_rate != 0 && mp->force_rate == r) return MPG123_RATES;
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
	return -1;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
static int enc2num(int encoding)
Packit c32a2d
{
Packit c32a2d
	int i;
Packit c32a2d
	for(i=0;i
Packit c32a2d
	if(my_encodings[i] == encoding) return i;
Packit c32a2d
Packit c32a2d
	return -1;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
Packit c32a2d
{
Packit c32a2d
	int i;
Packit c32a2d
	int c  = nf->channels-1;
Packit c32a2d
	int rn = rate2num(&fr->p, nf->rate);
Packit c32a2d
	if(rn >= 0)	for(i=f0;i
Packit c32a2d
	{
Packit c32a2d
		if(fr->p.audio_caps[c][rn][i])
Packit c32a2d
		{
Packit c32a2d
			nf->encoding = my_encodings[i];
Packit c32a2d
			return 1;
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
	return 0;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
Packit c32a2d
{
Packit c32a2d
	nf->rate = frame_freq(fr)>>fr->p.down_sample;
Packit c32a2d
	if(cap_fit(fr,nf,f0,f2)) return 1;
Packit c32a2d
	if(fr->p.flags & MPG123_AUTO_RESAMPLE)
Packit c32a2d
	{
Packit c32a2d
		nf->rate>>=1;
Packit c32a2d
		if(cap_fit(fr,nf,f0,f2)) return 1;
Packit c32a2d
		nf->rate>>=1;
Packit c32a2d
		if(cap_fit(fr,nf,f0,f2)) return 1;
Packit c32a2d
	}
Packit c32a2d
#ifndef NO_NTOM
Packit c32a2d
	/* If nothing worked, try the other rates, only without constrains from user.
Packit c32a2d
	   In case you didn't guess: We enable flexible resampling if we find a working rate. */
Packit c32a2d
	if(  fr->p.flags & MPG123_AUTO_RESAMPLE &&
Packit c32a2d
	    !fr->p.force_rate && fr->p.down_sample == 0)
Packit c32a2d
	{
Packit c32a2d
		int i;
Packit c32a2d
		int c  = nf->channels-1;
Packit c32a2d
		int rn = rate2num(&fr->p, frame_freq(fr));
Packit c32a2d
		int rrn;
Packit c32a2d
		if(rn < 0) return 0;
Packit c32a2d
		/* Try higher rates first. */
Packit c32a2d
		for(i=f0;i
Packit c32a2d
		if(fr->p.audio_caps[c][rrn][i])
Packit c32a2d
		{
Packit c32a2d
			nf->rate = my_rates[rrn];
Packit c32a2d
			nf->encoding = my_encodings[i];
Packit c32a2d
			return 1;
Packit c32a2d
		}
Packit c32a2d
		/* Then lower rates. */
Packit c32a2d
		for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
Packit c32a2d
		if(fr->p.audio_caps[c][rrn][i])
Packit c32a2d
		{
Packit c32a2d
			nf->rate = my_rates[rrn];
Packit c32a2d
			nf->encoding = my_encodings[i];
Packit c32a2d
			return 1;
Packit c32a2d
		}
Packit c32a2d
	}
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
	return 0;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* match constraints against supported audio formats, store possible setup in frame
Packit c32a2d
  return: -1: error; 0: no format change; 1: format change */
Packit c32a2d
int frame_output_format(mpg123_handle *fr)
Packit c32a2d
{
Packit c32a2d
	struct audioformat nf;
Packit c32a2d
	int f0=0;
Packit c32a2d
	int f2=MPG123_ENCODINGS; /* Omit the 32bit and float encodings. */
Packit c32a2d
	mpg123_pars *p = &fr->p;
Packit c32a2d
	/* initialize new format, encoding comes later */
Packit c32a2d
	nf.channels = fr->stereo;
Packit c32a2d
Packit c32a2d
	/* All this forcing should be removed in favour of the capabilities table... */
Packit c32a2d
	if(p->flags & MPG123_FORCE_8BIT)
Packit c32a2d
	{
Packit c32a2d
		f0 = enc_8bit_range[0];
Packit c32a2d
		f2 = enc_8bit_range[1];
Packit c32a2d
	}
Packit c32a2d
	if(p->flags & MPG123_FORCE_FLOAT)
Packit c32a2d
	{
Packit c32a2d
		f0 = enc_float_range[0];
Packit c32a2d
		f2 = enc_float_range[1];
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	/* force stereo is stronger */
Packit c32a2d
	if(p->flags & MPG123_FORCE_MONO)   nf.channels = 1;
Packit c32a2d
	if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2;
Packit c32a2d
Packit c32a2d
#ifndef NO_NTOM
Packit c32a2d
	if(p->force_rate)
Packit c32a2d
	{
Packit c32a2d
		nf.rate = p->force_rate;
Packit c32a2d
		if(cap_fit(fr,&nf,f0,2)) goto end;            /* 16bit encodings */
Packit c32a2d
		if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /*  8bit encodings */
Packit c32a2d
Packit c32a2d
		/* try again with different stereoness */
Packit c32a2d
		if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
Packit c32a2d
		else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
Packit c32a2d
Packit c32a2d
		if(cap_fit(fr,&nf,f0,2)) goto end;            /* 16bit encodings */
Packit c32a2d
		if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /*  8bit encodings */
Packit c32a2d
Packit c32a2d
		if(NOQUIET)
Packit c32a2d
		error3( "Unable to set up output format! Constraints: %s%s%liHz.",
Packit c32a2d
		        ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
Packit c32a2d
		          (p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
Packit c32a2d
		        (p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
Packit c32a2d
		        p->force_rate );
Packit c32a2d
/*		if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
Packit c32a2d
Packit c32a2d
		fr->err = MPG123_BAD_OUTFORMAT;
Packit c32a2d
		return -1;
Packit c32a2d
	}
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
	if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
Packit c32a2d
	if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
Packit c32a2d
Packit c32a2d
	/* try again with different stereoness */
Packit c32a2d
	if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
Packit c32a2d
	else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
Packit c32a2d
Packit c32a2d
	if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
Packit c32a2d
	if(freq_fit(fr, &nf,  f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
Packit c32a2d
Packit c32a2d
	/* Here is the _bad_ end. */
Packit c32a2d
	if(NOQUIET)
Packit c32a2d
	{
Packit c32a2d
		error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.",
Packit c32a2d
		        ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
Packit c32a2d
		          (p->flags & MPG123_FORCE_MONO ? "mono, "  : "") ),
Packit c32a2d
		        (p->flags & MPG123_FORCE_8BIT  ? "8bit, " : ""),
Packit c32a2d
		        frame_freq(fr),  frame_freq(fr)>>1, frame_freq(fr)>>2 );
Packit c32a2d
	}
Packit c32a2d
/*	if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
Packit c32a2d
Packit c32a2d
	fr->err = MPG123_BAD_OUTFORMAT;
Packit c32a2d
	return -1;
Packit c32a2d
Packit c32a2d
end: /* Here is the _good_ end. */
Packit c32a2d
	/* we had a successful match, now see if there's a change */
Packit c32a2d
	if(nf.rate == fr->af.rate && nf.channels == fr->af.channels && nf.encoding == fr->af.encoding)
Packit c32a2d
	{
Packit c32a2d
		debug2("Old format with %i channels, and FORCE_MONO=%li", nf.channels, p->flags & MPG123_FORCE_MONO);
Packit c32a2d
		return 0; /* the same format as before */
Packit c32a2d
	}
Packit c32a2d
	else /* a new format */
Packit c32a2d
	{
Packit c32a2d
		debug1("New format with %i channels!", nf.channels);
Packit c32a2d
		fr->af.rate = nf.rate;
Packit c32a2d
		fr->af.channels = nf.channels;
Packit c32a2d
		fr->af.encoding = nf.encoding;
Packit c32a2d
		/* Cache the size of one sample in bytes, for ease of use. */
Packit c32a2d
		fr->af.encsize = mpg123_encsize(fr->af.encoding);
Packit c32a2d
		if(fr->af.encsize < 1)
Packit c32a2d
		{
Packit c32a2d
			if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding);
Packit c32a2d
Packit c32a2d
			fr->err = MPG123_BAD_OUTFORMAT;
Packit c32a2d
			return -1;
Packit c32a2d
		}
Packit c32a2d
		/* Set up the decoder synth format. Might differ. */
Packit c32a2d
#ifdef NO_SYNTH32
Packit c32a2d
		/* Without high-precision synths, 16 bit signed is the basis for
Packit c32a2d
		   everything higher than 8 bit. */
Packit c32a2d
		if(fr->af.encsize > 2)
Packit c32a2d
		fr->af.dec_enc = MPG123_ENC_SIGNED_16;
Packit c32a2d
		else
Packit c32a2d
		{
Packit c32a2d
#endif
Packit c32a2d
			switch(fr->af.encoding)
Packit c32a2d
			{
Packit c32a2d
#ifndef NO_32BIT
Packit c32a2d
			case MPG123_ENC_SIGNED_24:
Packit c32a2d
			case MPG123_ENC_UNSIGNED_24:
Packit c32a2d
			case MPG123_ENC_UNSIGNED_32:
Packit c32a2d
				fr->af.dec_enc = MPG123_ENC_SIGNED_32;
Packit c32a2d
			break;
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_16BIT
Packit c32a2d
			case MPG123_ENC_UNSIGNED_16:
Packit c32a2d
				fr->af.dec_enc = MPG123_ENC_SIGNED_16;
Packit c32a2d
			break;
Packit c32a2d
#endif
Packit c32a2d
			default:
Packit c32a2d
				fr->af.dec_enc = fr->af.encoding;
Packit c32a2d
			}
Packit c32a2d
#ifdef NO_SYNTH32
Packit c32a2d
		}
Packit c32a2d
#endif
Packit c32a2d
		fr->af.dec_encsize = mpg123_encsize(fr->af.dec_enc);
Packit c32a2d
		return 1;
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_format_none(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int r;
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	r = mpg123_fmt_none(&mh->p);
Packit c32a2d
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
Packit c32a2d
Packit c32a2d
	return r;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_fmt_none(mpg123_pars *mp)
Packit c32a2d
{
Packit c32a2d
	if(mp == NULL) return MPG123_BAD_PARS;
Packit c32a2d
Packit c32a2d
	if(PVERB(mp,3)) fprintf(stderr, "Note: Disabling all formats.\n");
Packit c32a2d
Packit c32a2d
	memset(mp->audio_caps,0,sizeof(mp->audio_caps));
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_format_all(mpg123_handle *mh)
Packit c32a2d
{
Packit c32a2d
	int r;
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
Packit c32a2d
	r = mpg123_fmt_all(&mh->p);
Packit c32a2d
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
Packit c32a2d
Packit c32a2d
	return r;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp)
Packit c32a2d
{
Packit c32a2d
	size_t rate, ch, enc;
Packit c32a2d
	if(mp == NULL) return MPG123_BAD_PARS;
Packit c32a2d
Packit c32a2d
	if(PVERB(mp,3)) fprintf(stderr, "Note: Enabling all formats.\n");
Packit c32a2d
Packit c32a2d
	for(ch=0;   ch   < NUM_CHANNELS;     ++ch)
Packit c32a2d
	for(rate=0; rate < MPG123_RATES+1;   ++rate)
Packit c32a2d
	for(enc=0;  enc  < MPG123_ENCODINGS; ++enc)
Packit c32a2d
	mp->audio_caps[ch][rate][enc] = good_enc(my_encodings[enc]) ? 1 : 0;
Packit c32a2d
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
Packit c32a2d
{
Packit c32a2d
	int r;
Packit c32a2d
	if(mh == NULL) return MPG123_BAD_HANDLE;
Packit c32a2d
	r = mpg123_fmt(&mh->p, rate, channels, encodings);
Packit c32a2d
	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
Packit c32a2d
Packit c32a2d
	return r;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
Packit c32a2d
{
Packit c32a2d
	int ie, ic, ratei;
Packit c32a2d
	int ch[2] = {0, 1};
Packit c32a2d
	if(mp == NULL) return MPG123_BAD_PARS;
Packit c32a2d
	if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL;
Packit c32a2d
Packit c32a2d
	if(PVERB(mp,3)) fprintf(stderr, "Note: Want to enable format %li/%i for encodings 0x%x.\n", rate, channels, encodings);
Packit c32a2d
Packit c32a2d
	if(!(channels & MPG123_STEREO)) ch[1] = 0;     /* {0,0} */
Packit c32a2d
	else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */
Packit c32a2d
	ratei = rate2num(mp, rate);
Packit c32a2d
	if(ratei < 0) return MPG123_BAD_RATE;
Packit c32a2d
Packit c32a2d
	/* now match the encodings */
Packit c32a2d
	for(ic = 0; ic < 2; ++ic)
Packit c32a2d
	{
Packit c32a2d
		for(ie = 0; ie < MPG123_ENCODINGS; ++ie)
Packit c32a2d
		if(good_enc(my_encodings[ie]) && ((my_encodings[ie] & encodings) == my_encodings[ie]))
Packit c32a2d
		mp->audio_caps[ch[ic]][ratei][ie] = 1;
Packit c32a2d
Packit c32a2d
		if(ch[0] == ch[1]) break; /* no need to do it again */
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	return MPG123_OK;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding)
Packit c32a2d
{
Packit c32a2d
	if(mh == NULL) return 0;
Packit c32a2d
	else return mpg123_fmt_support(&mh->p, rate, encoding);
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
int attribute_align_arg mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding)
Packit c32a2d
{
Packit c32a2d
	int ch = 0;
Packit c32a2d
	int ratei, enci;
Packit c32a2d
	ratei = rate2num(mp, rate);
Packit c32a2d
	enci  = enc2num(encoding);
Packit c32a2d
	if(mp == NULL || ratei < 0 || enci < 0) return 0;
Packit c32a2d
	if(mp->audio_caps[0][ratei][enci]) ch |= MPG123_MONO;
Packit c32a2d
	if(mp->audio_caps[1][ratei][enci]) ch |= MPG123_STEREO;
Packit c32a2d
	return ch;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Call this one to ensure that any valid format will be something different than this. */
Packit c32a2d
void invalidate_format(struct audioformat *af)
Packit c32a2d
{
Packit c32a2d
	af->encoding = 0;
Packit c32a2d
	af->rate     = 0;
Packit c32a2d
	af->channels = 0;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Number of bytes the decoder produces. */
Packit c32a2d
off_t decoder_synth_bytes(mpg123_handle *fr, off_t s)
Packit c32a2d
{
Packit c32a2d
	return s * fr->af.dec_encsize * fr->af.channels;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Samples/bytes for output buffer after post-processing. */
Packit c32a2d
/* take into account: channels, bytes per sample -- NOT resampling!*/
Packit c32a2d
off_t samples_to_bytes(mpg123_handle *fr , off_t s)
Packit c32a2d
{
Packit c32a2d
	return s * fr->af.encsize * fr->af.channels;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
off_t bytes_to_samples(mpg123_handle *fr , off_t b)
Packit c32a2d
{
Packit c32a2d
	return b / fr->af.encsize / fr->af.channels;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
/* Number of bytes needed for decoding _and_ post-processing. */
Packit c32a2d
off_t outblock_bytes(mpg123_handle *fr, off_t s)
Packit c32a2d
{
Packit c32a2d
	int encsize = (fr->af.encoding & MPG123_ENC_24)
Packit c32a2d
	? 4 /* Intermediate 32 bit. */
Packit c32a2d
	: (fr->af.encsize > fr->af.dec_encsize
Packit c32a2d
		? fr->af.encsize
Packit c32a2d
		: fr->af.dec_encsize);
Packit c32a2d
	return s * encsize * fr->af.channels;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
#ifndef NO_32BIT
Packit c32a2d
/* Remove every fourth byte, facilitating conversion from 32 bit to 24 bit integers.
Packit c32a2d
   This has to be aware of endianness, of course. */
Packit c32a2d
static void chop_fourth_byte(struct outbuffer *buf)
Packit c32a2d
{
Packit c32a2d
	unsigned char *wpos = buf->data;
Packit c32a2d
	unsigned char *rpos = buf->data;
Packit c32a2d
#ifdef WORDS_BIGENDIAN
Packit c32a2d
	while((size_t) (rpos - buf->data + 4) <= buf->fill)
Packit c32a2d
	{
Packit c32a2d
		/* Really stupid: Copy, increment. Byte per byte. */
Packit c32a2d
		*wpos = *rpos;
Packit c32a2d
		wpos++; rpos++;
Packit c32a2d
		*wpos = *rpos;
Packit c32a2d
		wpos++; rpos++;
Packit c32a2d
		*wpos = *rpos;
Packit c32a2d
		wpos++; rpos++;
Packit c32a2d
		rpos++; /* Skip the lowest byte (last). */
Packit c32a2d
	}
Packit c32a2d
#else
Packit c32a2d
	while((size_t) (rpos - buf->data + 4) <= buf->fill)
Packit c32a2d
	{
Packit c32a2d
		/* Really stupid: Copy, increment. Byte per byte. */
Packit c32a2d
		rpos++; /* Skip the lowest byte (first). */
Packit c32a2d
		*wpos = *rpos;
Packit c32a2d
		wpos++; rpos++;
Packit c32a2d
		*wpos = *rpos;
Packit c32a2d
		wpos++; rpos++;
Packit c32a2d
		*wpos = *rpos;
Packit c32a2d
		wpos++; rpos++;
Packit c32a2d
	}
Packit c32a2d
#endif
Packit c32a2d
	buf->fill = wpos-buf->data;
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
static void conv_s32_to_u32(struct outbuffer *buf)
Packit c32a2d
{
Packit c32a2d
	size_t i;
Packit c32a2d
	int32_t  *ssamples = (int32_t*)  buf->data;
Packit c32a2d
	uint32_t *usamples = (uint32_t*) buf->data;
Packit c32a2d
	size_t count = buf->fill/sizeof(int32_t);
Packit c32a2d
Packit c32a2d
	for(i=0; i
Packit c32a2d
	{
Packit c32a2d
		/* Different strategy since we don't have a larger type at hand.
Packit c32a2d
			 Also watch out for silly +-1 fun because integer constants are signed in C90! */
Packit c32a2d
		if(ssamples[i] >= 0)
Packit c32a2d
		usamples[i] = (uint32_t)ssamples[i] + 2147483647+1;
Packit c32a2d
		/* The smallest value goes zero. */
Packit c32a2d
		else if(ssamples[i] == ((int32_t)-2147483647-1))
Packit c32a2d
		usamples[i] = 0;
Packit c32a2d
		/* Now -value is in the positive range of signed int ... so it's a possible value at all. */
Packit c32a2d
		else
Packit c32a2d
		usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]);
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
Packit c32a2d
/* We always assume that whole numbers are written!
Packit c32a2d
   partials will be cut out. */
Packit c32a2d
Packit c32a2d
static const char *bufsizeerr = "Fatal: Buffer too small for postprocessing!";
Packit c32a2d
Packit c32a2d
Packit c32a2d
#ifndef NO_16BIT
Packit c32a2d
Packit c32a2d
static void conv_s16_to_u16(struct outbuffer *buf)
Packit c32a2d
{
Packit c32a2d
	size_t i;
Packit c32a2d
	int16_t  *ssamples = (int16_t*) buf->data;
Packit c32a2d
	uint16_t *usamples = (uint16_t*)buf->data;
Packit c32a2d
	size_t count = buf->fill/sizeof(int16_t);
Packit c32a2d
Packit c32a2d
	for(i=0; i
Packit c32a2d
	{
Packit c32a2d
		long tmp = (long)ssamples[i]+32768;
Packit c32a2d
		usamples[i] = (uint16_t)tmp;
Packit c32a2d
	}
Packit c32a2d
}
Packit c32a2d
Packit c32a2d
#ifndef NO_REAL
Packit c32a2d
static void conv_s16_to_f32(struct outbuffer *buf)
Packit c32a2d
{
Packit c32a2d
	ssize_t i;
Packit c32a2d
	int16_t *in = (int16_t*) buf->data;
Packit c32a2d
	float  *out = (float*)   buf->data;
Packit c32a2d
	size_t count = buf->fill/sizeof(int16_t);
Packit c32a2d
	/* Does that make any sense? In x86, there is an actual instruction to divide
Packit c32a2d
	   float by integer ... but then, if we have that FPU, we don't really need
Packit c32a2d
	   fixed point decoder hacks ...? */
Packit c32a2d
	float scale = 1./SHORT_SCALE;
Packit c32a2d
Packit c32a2d
	if(buf->size < count*sizeof(float))
Packit c32a2d
	{
Packit c32a2d
		error1("%s", bufsizeerr);
Packit c32a2d
		return;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	/* Work from the back since output is bigger. */
Packit c32a2d
	for(i=count-1; i>=0; --i)
Packit c32a2d
	out[i] = (float)in[i] * scale;
Packit c32a2d
Packit c32a2d
	buf->fill = count*sizeof(float);
Packit c32a2d
}
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
#ifndef NO_32BIT
Packit c32a2d
static void conv_s16_to_s32(struct outbuffer *buf)
Packit c32a2d
{
Packit c32a2d
	ssize_t i;
Packit c32a2d
	int16_t  *in = (int16_t*) buf->data;
Packit c32a2d
	int32_t *out = (int32_t*) buf->data;
Packit c32a2d
	size_t count = buf->fill/sizeof(int16_t);
Packit c32a2d
Packit c32a2d
	if(buf->size < count*sizeof(int32_t))
Packit c32a2d
	{
Packit c32a2d
		error1("%s", bufsizeerr);
Packit c32a2d
		return;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	/* Work from the back since output is bigger. */
Packit c32a2d
	for(i=count-1; i>=0; --i)
Packit c32a2d
	{
Packit c32a2d
		out[i] = in[i];
Packit c32a2d
		/* Could just shift bytes, but would have to mess with sign bit. */
Packit c32a2d
		out[i] *= S32_RESCALE;
Packit c32a2d
	}
Packit c32a2d
Packit c32a2d
	buf->fill = count*sizeof(int32_t);
Packit c32a2d
}
Packit c32a2d
#endif
Packit c32a2d
#endif
Packit c32a2d
Packit c32a2d
Packit c32a2d
void postprocess_buffer(mpg123_handle *fr)
Packit c32a2d
{
Packit c32a2d
	/*
Packit c32a2d
		This caters for the final output formats that are never produced by
Packit c32a2d
		decoder synth directly (wide unsigned and 24 bit formats) or that are
Packit c32a2d
		missing because of limited decoder precision (16 bit synth but 32 or
Packit c32a2d
		24 bit output).
Packit c32a2d
	*/
Packit c32a2d
	switch(fr->af.dec_enc)
Packit c32a2d
	{
Packit c32a2d
#ifndef NO_32BIT
Packit c32a2d
	case MPG123_ENC_SIGNED_32:
Packit c32a2d
		switch(fr->af.encoding)
Packit c32a2d
		{
Packit c32a2d
		case MPG123_ENC_UNSIGNED_32:
Packit c32a2d
			conv_s32_to_u32(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ENC_UNSIGNED_24:
Packit c32a2d
			conv_s32_to_u32(&fr->buffer);
Packit c32a2d
			chop_fourth_byte(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ENC_SIGNED_24:
Packit c32a2d
			chop_fourth_byte(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
		}
Packit c32a2d
	break;
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_16BIT
Packit c32a2d
	case MPG123_ENC_SIGNED_16:
Packit c32a2d
		switch(fr->af.encoding)
Packit c32a2d
		{
Packit c32a2d
		case MPG123_ENC_UNSIGNED_16:
Packit c32a2d
			conv_s16_to_u16(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
#ifndef NO_REAL
Packit c32a2d
		case MPG123_ENC_FLOAT_32:
Packit c32a2d
			conv_s16_to_f32(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
#endif
Packit c32a2d
#ifndef NO_32BIT
Packit c32a2d
		case MPG123_ENC_SIGNED_32:
Packit c32a2d
			conv_s16_to_s32(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ENC_UNSIGNED_32:
Packit c32a2d
			conv_s16_to_s32(&fr->buffer);
Packit c32a2d
			conv_s32_to_u32(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ENC_UNSIGNED_24:
Packit c32a2d
			conv_s16_to_s32(&fr->buffer);
Packit c32a2d
			conv_s32_to_u32(&fr->buffer);
Packit c32a2d
			chop_fourth_byte(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
		case MPG123_ENC_SIGNED_24:
Packit c32a2d
			conv_s16_to_s32(&fr->buffer);
Packit c32a2d
			chop_fourth_byte(&fr->buffer);
Packit c32a2d
		break;
Packit c32a2d
#endif
Packit c32a2d
		}
Packit c32a2d
	break;
Packit c32a2d
#endif
Packit c32a2d
	}
Packit c32a2d
}