xref: /reactos/sdk/lib/3rdparty/libmpg123/format.c (revision 34593d93)
1c2c66affSColin Finck /*
2c2c66affSColin Finck 	format: routines to deal with audio (output) format
3c2c66affSColin Finck 
4*aa811c00SThomas Faber 	copyright 2008-20 by the mpg123 project - free software under the terms of the LGPL 2.1
5c2c66affSColin Finck 	see COPYING and AUTHORS files in distribution or http://mpg123.org
6c2c66affSColin Finck 	initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now
7c2c66affSColin Finck 
8c2c66affSColin Finck 	A Major change from mpg123 <= 1.18 is that all encodings are only really
9c2c66affSColin Finck 	disabled when done so via specific build configuration. Otherwise, the
10c2c66affSColin Finck 	missing support of decoders to produce a certain format is augmented by
11c2c66affSColin Finck 	postprocessing that converts the samples. This means happily creating
12c2c66affSColin Finck 	data with higher resolution from less accurate decoder output.
13c2c66affSColin Finck 
14c2c66affSColin Finck 	The main point is to still offer float encoding when the decoding core uses
15c2c66affSColin Finck 	a fixed point representation that has only 16 bit output. Actually, that's
16c2c66affSColin Finck 	the only point: A fixed-point build needs to create float from 16 bit, also
17c2c66affSColin Finck 	32 or 24 bit from the same source. That's all there is to it: Everything else
18c2c66affSColin Finck 	is covered by fallback synth functions. It may be a further step to check if
19c2c66affSColin Finck 	there are cases where conversion in postprocessing works well enough to omit
20c2c66affSColin Finck 	a certain specialized decoder ... but usually, they are justified by some
21c2c66affSColin Finck 	special way to get from float to integer to begin with.
22c2c66affSColin Finck 
23c2c66affSColin Finck 	I won't cover the case of faking double output with float/s16 decoders here.
24c2c66affSColin Finck 	Double precision output is a thing for experimental builds anyway. Mostly
25c2c66affSColin Finck 	theoretical and without a point.
26c2c66affSColin Finck */
27c2c66affSColin Finck 
28c2c66affSColin Finck #include "mpg123lib_intern.h"
29*aa811c00SThomas Faber #include "sample.h"
30c2c66affSColin Finck #include "debug.h"
31c2c66affSColin Finck 
32c2c66affSColin Finck /* static int chans[NUM_CHANNELS] = { 1 , 2 }; */
33c2c66affSColin Finck static const long my_rates[MPG123_RATES] = /* only the standard rates */
34c2c66affSColin Finck {
35c2c66affSColin Finck 	 8000, 11025, 12000,
36c2c66affSColin Finck 	16000, 22050, 24000,
37c2c66affSColin Finck 	32000, 44100, 48000,
38c2c66affSColin Finck };
39c2c66affSColin Finck 
40c2c66affSColin Finck static const int my_encodings[MPG123_ENCODINGS] =
41c2c66affSColin Finck {
42c2c66affSColin Finck 	MPG123_ENC_SIGNED_16,
43c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_16,
44c2c66affSColin Finck 	MPG123_ENC_SIGNED_32,
45c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_32,
46c2c66affSColin Finck 	MPG123_ENC_SIGNED_24,
47c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_24,
48c2c66affSColin Finck 	/* Floating point range, see below. */
49c2c66affSColin Finck 	MPG123_ENC_FLOAT_32,
50c2c66affSColin Finck 	MPG123_ENC_FLOAT_64,
51c2c66affSColin Finck 	/* 8 bit range, see below. */
52c2c66affSColin Finck 	MPG123_ENC_SIGNED_8,
53c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_8,
54c2c66affSColin Finck 	MPG123_ENC_ULAW_8,
55c2c66affSColin Finck 	MPG123_ENC_ALAW_8
56c2c66affSColin Finck };
57c2c66affSColin Finck 
58c2c66affSColin Finck /* Make that match the above table.
59c2c66affSColin Finck    And yes, I still don't like this kludgy stuff. */
60c2c66affSColin Finck /* range[0] <= i < range[1] for forced floating point */
61c2c66affSColin Finck static const int enc_float_range[2] = { 6, 8 };
62c2c66affSColin Finck /* same for 8 bit encodings */
63c2c66affSColin Finck static const int enc_8bit_range[2] = { 8, 12 };
64*aa811c00SThomas Faber // for 24 bit quality (24 and 32 bit integers)
65*aa811c00SThomas Faber static const int enc_24bit_range[2] = { 2, 6 };
66*aa811c00SThomas Faber // for completeness, the 16 bits
67*aa811c00SThomas Faber static const int enc_16bit_range[2] = { 0, 2};
68c2c66affSColin Finck 
69c2c66affSColin Finck /*
70c2c66affSColin Finck 	Only one type of float is supported.
71c2c66affSColin Finck 	Actually, double is a very special experimental case not occuring in normal
72c2c66affSColin Finck 	builds. Might actually get rid of it.
73c2c66affSColin Finck 
74c2c66affSColin Finck 	Remember here: Also with REAL_IS_FIXED, I want to be able to produce float
75c2c66affSColin Finck 	output (f32) via post-processing.
76c2c66affSColin Finck */
77c2c66affSColin Finck # ifdef REAL_IS_DOUBLE
78c2c66affSColin Finck #  define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_64
79c2c66affSColin Finck # else
80c2c66affSColin Finck #  define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32
81c2c66affSColin Finck # endif
82c2c66affSColin Finck 
83c2c66affSColin Finck /* The list of actually possible encodings. */
84c2c66affSColin Finck static const int good_encodings[] =
85c2c66affSColin Finck {
86c2c66affSColin Finck #ifndef NO_16BIT
87c2c66affSColin Finck 	MPG123_ENC_SIGNED_16,
88c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_16,
89c2c66affSColin Finck #endif
90c2c66affSColin Finck #ifndef NO_32BIT
91c2c66affSColin Finck 	MPG123_ENC_SIGNED_32,
92c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_32,
93c2c66affSColin Finck 	MPG123_ENC_SIGNED_24,
94c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_24,
95c2c66affSColin Finck #endif
96c2c66affSColin Finck #ifndef NO_REAL
97c2c66affSColin Finck 	MPG123_FLOAT_ENC,
98c2c66affSColin Finck #endif
99c2c66affSColin Finck #ifndef NO_8BIT
100c2c66affSColin Finck 	MPG123_ENC_SIGNED_8,
101c2c66affSColin Finck 	MPG123_ENC_UNSIGNED_8,
102c2c66affSColin Finck 	MPG123_ENC_ULAW_8,
103c2c66affSColin Finck 	MPG123_ENC_ALAW_8
104c2c66affSColin Finck #endif
105c2c66affSColin Finck };
106c2c66affSColin Finck 
107c2c66affSColin Finck /* Check if encoding is a valid one in this build.
108c2c66affSColin Finck    ...lazy programming: linear search. */
good_enc(const int enc)109c2c66affSColin Finck static int good_enc(const int enc)
110c2c66affSColin Finck {
111c2c66affSColin Finck 	size_t i;
112c2c66affSColin Finck 	for(i=0; i<sizeof(good_encodings)/sizeof(int); ++i)
113c2c66affSColin Finck 	if(enc == good_encodings[i]) return TRUE;
114c2c66affSColin Finck 
115c2c66affSColin Finck 	return FALSE;
116c2c66affSColin Finck }
117c2c66affSColin Finck 
mpg123_rates(const long ** list,size_t * number)118c2c66affSColin Finck void attribute_align_arg mpg123_rates(const long **list, size_t *number)
119c2c66affSColin Finck {
120c2c66affSColin Finck 	if(list   != NULL) *list   = my_rates;
121c2c66affSColin Finck 	if(number != NULL) *number = sizeof(my_rates)/sizeof(long);
122c2c66affSColin Finck }
123c2c66affSColin Finck 
124c2c66affSColin Finck /* Now that's a bit tricky... One build of the library knows only a subset of the encodings. */
mpg123_encodings(const int ** list,size_t * number)125c2c66affSColin Finck void attribute_align_arg mpg123_encodings(const int **list, size_t *number)
126c2c66affSColin Finck {
127c2c66affSColin Finck 	if(list   != NULL) *list   = good_encodings;
128c2c66affSColin Finck 	if(number != NULL) *number = sizeof(good_encodings)/sizeof(int);
129c2c66affSColin Finck }
130c2c66affSColin Finck 
mpg123_encsize(int encoding)131c2c66affSColin Finck int attribute_align_arg mpg123_encsize(int encoding)
132c2c66affSColin Finck {
133c2c66affSColin Finck 	return MPG123_SAMPLESIZE(encoding);
134c2c66affSColin Finck }
135c2c66affSColin Finck 
136c2c66affSColin Finck /*	char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */
137c2c66affSColin Finck 
rate2num(mpg123_pars * mp,long r)138c2c66affSColin Finck static int rate2num(mpg123_pars *mp, long r)
139c2c66affSColin Finck {
140c2c66affSColin Finck 	int i;
141c2c66affSColin Finck 	for(i=0;i<MPG123_RATES;i++) if(my_rates[i] == r) return i;
142c2c66affSColin Finck #ifndef NO_NTOM
143c2c66affSColin Finck 	if(mp && mp->force_rate != 0 && mp->force_rate == r) return MPG123_RATES;
144c2c66affSColin Finck #endif
145c2c66affSColin Finck 
146c2c66affSColin Finck 	return -1;
147c2c66affSColin Finck }
148c2c66affSColin Finck 
enc2num(int encoding)149c2c66affSColin Finck static int enc2num(int encoding)
150c2c66affSColin Finck {
151c2c66affSColin Finck 	int i;
152c2c66affSColin Finck 	for(i=0;i<MPG123_ENCODINGS;++i)
153c2c66affSColin Finck 	if(my_encodings[i] == encoding) return i;
154c2c66affSColin Finck 
155c2c66affSColin Finck 	return -1;
156c2c66affSColin Finck }
157c2c66affSColin Finck 
cap_fit(mpg123_pars * p,struct audioformat * nf,int f0,int f2)158*aa811c00SThomas Faber static int cap_fit(mpg123_pars *p, struct audioformat *nf, int f0, int f2)
159c2c66affSColin Finck {
160c2c66affSColin Finck 	int i;
161c2c66affSColin Finck 	int c  = nf->channels-1;
162*aa811c00SThomas Faber 	int rn = rate2num(p, nf->rate);
163c2c66affSColin Finck 	if(rn >= 0)	for(i=f0;i<f2;i++)
164c2c66affSColin Finck 	{
165*aa811c00SThomas Faber 		if(p->audio_caps[c][rn][i])
166c2c66affSColin Finck 		{
167c2c66affSColin Finck 			nf->encoding = my_encodings[i];
168c2c66affSColin Finck 			return 1;
169c2c66affSColin Finck 		}
170c2c66affSColin Finck 	}
171c2c66affSColin Finck 	return 0;
172c2c66affSColin Finck }
173c2c66affSColin Finck 
imin(int a,int b)174*aa811c00SThomas Faber static int imin(int a, int b)
175c2c66affSColin Finck {
176*aa811c00SThomas Faber 	return a < b ? a : b;
177c2c66affSColin Finck }
178c2c66affSColin Finck 
imax(int a,int b)179*aa811c00SThomas Faber static int imax(int a, int b)
180*aa811c00SThomas Faber {
181*aa811c00SThomas Faber 	return a > b ? a : b;
182*aa811c00SThomas Faber }
183*aa811c00SThomas Faber 
184*aa811c00SThomas Faber // Find a possible encoding with given rate and channel count,
185*aa811c00SThomas Faber // try differing channel count, too.
186*aa811c00SThomas Faber // This updates the given format and returns TRUE if an encoding
187*aa811c00SThomas Faber // was found.
enc_chan_fit(mpg123_pars * p,long rate,struct audioformat * nnf,int f0,int f2,int try_float)188*aa811c00SThomas Faber static int enc_chan_fit( mpg123_pars *p, long rate, struct audioformat *nnf
189*aa811c00SThomas Faber ,	int f0, int f2, int try_float )
190*aa811c00SThomas Faber {
191*aa811c00SThomas Faber #define ENCRANGE(range) imax(f0, range[0]), imin(f2, range[1])
192*aa811c00SThomas Faber 	struct audioformat nf = *nnf;
193*aa811c00SThomas Faber 	nf.rate = rate;
194*aa811c00SThomas Faber 	if(cap_fit(p, &nf, ENCRANGE(enc_16bit_range)))
195*aa811c00SThomas Faber 		goto eend;
196*aa811c00SThomas Faber 	if(cap_fit(p, &nf, ENCRANGE(enc_24bit_range)))
197*aa811c00SThomas Faber 		goto eend;
198*aa811c00SThomas Faber 	if(try_float &&
199*aa811c00SThomas Faber 		cap_fit(p, &nf, ENCRANGE(enc_float_range)))
200*aa811c00SThomas Faber 		goto eend;
201*aa811c00SThomas Faber 	if(cap_fit(p, &nf, ENCRANGE(enc_8bit_range)))
202*aa811c00SThomas Faber 		goto eend;
203*aa811c00SThomas Faber 
204*aa811c00SThomas Faber 	/* try again with different stereoness */
205*aa811c00SThomas Faber 	if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
206*aa811c00SThomas Faber 	else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
207*aa811c00SThomas Faber 
208*aa811c00SThomas Faber 	if(cap_fit(p, &nf, ENCRANGE(enc_16bit_range)))
209*aa811c00SThomas Faber 		goto eend;
210*aa811c00SThomas Faber 	if(cap_fit(p, &nf, ENCRANGE(enc_24bit_range)))
211*aa811c00SThomas Faber 		goto eend;
212*aa811c00SThomas Faber 	if(try_float &&
213*aa811c00SThomas Faber 		cap_fit(p, &nf, ENCRANGE(enc_float_range)))
214*aa811c00SThomas Faber 		goto eend;
215*aa811c00SThomas Faber 	if(cap_fit(p, &nf, ENCRANGE(enc_8bit_range)))
216*aa811c00SThomas Faber 		goto eend;
217*aa811c00SThomas Faber 	return FALSE;
218*aa811c00SThomas Faber eend:
219*aa811c00SThomas Faber 	*nnf = nf;
220*aa811c00SThomas Faber 	return TRUE;
221*aa811c00SThomas Faber #undef ENCRANGE
222c2c66affSColin Finck }
223c2c66affSColin Finck 
224c2c66affSColin Finck /* match constraints against supported audio formats, store possible setup in frame
225c2c66affSColin Finck   return: -1: error; 0: no format change; 1: format change */
frame_output_format(mpg123_handle * fr)226c2c66affSColin Finck int frame_output_format(mpg123_handle *fr)
227c2c66affSColin Finck {
228c2c66affSColin Finck 	struct audioformat nf;
229c2c66affSColin Finck 	int f0=0;
230*aa811c00SThomas Faber 	int f2=MPG123_ENCODINGS+1; // Include all encodings by default.
231c2c66affSColin Finck 	mpg123_pars *p = &fr->p;
232*aa811c00SThomas Faber 	int try_float = (p->flags & MPG123_FLOAT_FALLBACK) ? 0 : 1;
233c2c66affSColin Finck 	/* initialize new format, encoding comes later */
234c2c66affSColin Finck 	nf.channels = fr->stereo;
235c2c66affSColin Finck 
236*aa811c00SThomas Faber 	// I intended the forcing stuff to be weaved into the format support table,
237*aa811c00SThomas Faber 	// but this probably will never happen, as this would change library behaviour.
238*aa811c00SThomas Faber 	// One could introduce an additional effective format table that takes for
239*aa811c00SThomas Faber 	// forcings into account, but that would have to be updated on any flag
240*aa811c00SThomas Faber 	// change. Tedious.
241c2c66affSColin Finck 	if(p->flags & MPG123_FORCE_8BIT)
242c2c66affSColin Finck 	{
243c2c66affSColin Finck 		f0 = enc_8bit_range[0];
244c2c66affSColin Finck 		f2 = enc_8bit_range[1];
245c2c66affSColin Finck 	}
246c2c66affSColin Finck 	if(p->flags & MPG123_FORCE_FLOAT)
247c2c66affSColin Finck 	{
248*aa811c00SThomas Faber 		try_float = 1;
249c2c66affSColin Finck 		f0 = enc_float_range[0];
250c2c66affSColin Finck 		f2 = enc_float_range[1];
251c2c66affSColin Finck 	}
252c2c66affSColin Finck 
253c2c66affSColin Finck 	/* force stereo is stronger */
254c2c66affSColin Finck 	if(p->flags & MPG123_FORCE_MONO)   nf.channels = 1;
255c2c66affSColin Finck 	if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2;
256c2c66affSColin Finck 
257*aa811c00SThomas Faber 	// Strategy update: Avoid too early triggering of the NtoM decoder.
258*aa811c00SThomas Faber 	// Main target is the native rate, with any encoding.
259*aa811c00SThomas Faber 	// Then, native rate with any channel count and any encoding.
260*aa811c00SThomas Faber 	// Then, it's down_sample from native rate.
261*aa811c00SThomas Faber 	// As last resort: NtoM rate.
262*aa811c00SThomas Faber 	// So the priority is 1. rate 2. channels 3. encoding.
263*aa811c00SThomas Faber 	// As encodings go, 16 bit is tranditionally preferred as efficient choice.
264*aa811c00SThomas Faber 	// Next in line are wider float and integer encodings, then 8 bit as
265*aa811c00SThomas Faber 	// last resort.
266*aa811c00SThomas Faber 
267c2c66affSColin Finck #ifndef NO_NTOM
268c2c66affSColin Finck 	if(p->force_rate)
269c2c66affSColin Finck 	{
270*aa811c00SThomas Faber 		if(enc_chan_fit(p, p->force_rate, &nf, f0, f2, try_float))
271*aa811c00SThomas Faber 			goto end;
272*aa811c00SThomas Faber 		// Keep the order consistent if float is considered fallback only.
273*aa811c00SThomas Faber 		if(!try_float &&
274*aa811c00SThomas Faber 			enc_chan_fit(p, p->force_rate, &nf, f0, f2, TRUE))
275*aa811c00SThomas Faber 				goto end;
276c2c66affSColin Finck 
277*aa811c00SThomas Faber 		merror( "Unable to set up output format! Constraints: %s%s%liHz."
278*aa811c00SThomas Faber 		,	( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
279*aa811c00SThomas Faber 				(p->flags & MPG123_FORCE_MONO ? "mono, " : "") )
280*aa811c00SThomas Faber 		,	( p->flags & MPG123_FORCE_FLOAT ? "float, " :
281*aa811c00SThomas Faber 				(p->flags & MPG123_FORCE_8BIT ? "8bit, " : "") )
282*aa811c00SThomas Faber 		,	p->force_rate );
283c2c66affSColin Finck /*		if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
284c2c66affSColin Finck 
285c2c66affSColin Finck 		fr->err = MPG123_BAD_OUTFORMAT;
286c2c66affSColin Finck 		return -1;
287c2c66affSColin Finck 	}
288c2c66affSColin Finck #endif
289*aa811c00SThomas Faber 	// Native decoder rate first.
290*aa811c00SThomas Faber 	if(enc_chan_fit(p, frame_freq(fr)>>p->down_sample, &nf, f0, f2, try_float))
291*aa811c00SThomas Faber 		goto end;
292*aa811c00SThomas Faber 	// Then downsamplings.
293*aa811c00SThomas Faber 	if(p->flags & MPG123_AUTO_RESAMPLE && p->down_sample < 2)
294*aa811c00SThomas Faber 	{
295*aa811c00SThomas Faber 		if(enc_chan_fit( p, frame_freq(fr)>>(p->down_sample+1), &nf
296*aa811c00SThomas Faber 		,	f0, f2, try_float ))
297*aa811c00SThomas Faber 			goto end;
298*aa811c00SThomas Faber 		if(p->down_sample < 1 && enc_chan_fit( p, frame_freq(fr)>>2, &nf
299*aa811c00SThomas Faber 		,	f0, f2, try_float ))
300*aa811c00SThomas Faber 			goto end;
301*aa811c00SThomas Faber 	}
302*aa811c00SThomas Faber 	// And again the whole deal with float fallback.
303*aa811c00SThomas Faber 	if(!try_float)
304*aa811c00SThomas Faber 	{
305*aa811c00SThomas Faber 		if(enc_chan_fit(p, frame_freq(fr)>>p->down_sample, &nf, f0, f2, TRUE))
306*aa811c00SThomas Faber 			goto end;
307*aa811c00SThomas Faber 		// Then downsamplings.
308*aa811c00SThomas Faber 		if(p->flags & MPG123_AUTO_RESAMPLE && p->down_sample < 2)
309*aa811c00SThomas Faber 		{
310*aa811c00SThomas Faber 			if(enc_chan_fit( p, frame_freq(fr)>>(p->down_sample+1), &nf
311*aa811c00SThomas Faber 			,	f0, f2, TRUE ))
312*aa811c00SThomas Faber 				goto end;
313*aa811c00SThomas Faber 			if(p->down_sample < 1 && enc_chan_fit( p, frame_freq(fr)>>2, &nf
314*aa811c00SThomas Faber 			,	f0, f2, TRUE ))
315*aa811c00SThomas Faber 				goto end;
316*aa811c00SThomas Faber 		}
317*aa811c00SThomas Faber 	}
318*aa811c00SThomas Faber #ifndef NO_NTOM
319*aa811c00SThomas Faber 	// Try to find any rate that works and resample using NtoM hackery.
320*aa811c00SThomas Faber 	if(  p->flags & MPG123_AUTO_RESAMPLE && fr->p.down_sample == 0)
321*aa811c00SThomas Faber 	{
322*aa811c00SThomas Faber 		int i;
323*aa811c00SThomas Faber 		int rn = rate2num(p, frame_freq(fr));
324*aa811c00SThomas Faber 		int rrn;
325*aa811c00SThomas Faber 		if(rn < 0) return 0;
326*aa811c00SThomas Faber 		/* Try higher rates first. */
327*aa811c00SThomas Faber 		for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
328*aa811c00SThomas Faber 			if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, try_float))
329*aa811c00SThomas Faber 				goto end;
330*aa811c00SThomas Faber 		/* Then lower rates. */
331*aa811c00SThomas Faber 		for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
332*aa811c00SThomas Faber 			if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, try_float))
333*aa811c00SThomas Faber 				goto end;
334*aa811c00SThomas Faber 		// And again for float fallback.
335*aa811c00SThomas Faber 		if(!try_float)
336*aa811c00SThomas Faber 		{
337*aa811c00SThomas Faber 			/* Try higher rates first. */
338*aa811c00SThomas Faber 			for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
339*aa811c00SThomas Faber 				if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, TRUE))
340*aa811c00SThomas Faber 					goto end;
341*aa811c00SThomas Faber 			/* Then lower rates. */
342*aa811c00SThomas Faber 			for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
343*aa811c00SThomas Faber 				if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, TRUE))
344*aa811c00SThomas Faber 					goto end;
345*aa811c00SThomas Faber 		}
346*aa811c00SThomas Faber 	}
347*aa811c00SThomas Faber #endif
348c2c66affSColin Finck 
349c2c66affSColin Finck 	/* Here is the _bad_ end. */
350*aa811c00SThomas Faber 	merror( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz."
351*aa811c00SThomas Faber 	,	( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
352*aa811c00SThomas Faber 			(p->flags & MPG123_FORCE_MONO ? "mono, " : "") )
353*aa811c00SThomas Faber 	,	( p->flags & MPG123_FORCE_FLOAT ? "float, " :
354*aa811c00SThomas Faber 			(p->flags & MPG123_FORCE_8BIT ? "8bit, " : "") )
355*aa811c00SThomas Faber 	,	frame_freq(fr),  frame_freq(fr)>>1, frame_freq(fr)>>2 );
356c2c66affSColin Finck /*	if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
357c2c66affSColin Finck 
358c2c66affSColin Finck 	fr->err = MPG123_BAD_OUTFORMAT;
359c2c66affSColin Finck 	return -1;
360c2c66affSColin Finck 
361c2c66affSColin Finck end: /* Here is the _good_ end. */
362c2c66affSColin Finck 	/* we had a successful match, now see if there's a change */
363c2c66affSColin Finck 	if(nf.rate == fr->af.rate && nf.channels == fr->af.channels && nf.encoding == fr->af.encoding)
364c2c66affSColin Finck 	{
365c2c66affSColin Finck 		debug2("Old format with %i channels, and FORCE_MONO=%li", nf.channels, p->flags & MPG123_FORCE_MONO);
366c2c66affSColin Finck 		return 0; /* the same format as before */
367c2c66affSColin Finck 	}
368c2c66affSColin Finck 	else /* a new format */
369c2c66affSColin Finck 	{
370c2c66affSColin Finck 		debug1("New format with %i channels!", nf.channels);
371c2c66affSColin Finck 		fr->af.rate = nf.rate;
372c2c66affSColin Finck 		fr->af.channels = nf.channels;
373c2c66affSColin Finck 		fr->af.encoding = nf.encoding;
374c2c66affSColin Finck 		/* Cache the size of one sample in bytes, for ease of use. */
375c2c66affSColin Finck 		fr->af.encsize = mpg123_encsize(fr->af.encoding);
376c2c66affSColin Finck 		if(fr->af.encsize < 1)
377c2c66affSColin Finck 		{
378*aa811c00SThomas Faber 			error1("Some unknown encoding??? (%i)", fr->af.encoding);
379c2c66affSColin Finck 
380c2c66affSColin Finck 			fr->err = MPG123_BAD_OUTFORMAT;
381c2c66affSColin Finck 			return -1;
382c2c66affSColin Finck 		}
383c2c66affSColin Finck 		/* Set up the decoder synth format. Might differ. */
384c2c66affSColin Finck #ifdef NO_SYNTH32
385c2c66affSColin Finck 		/* Without high-precision synths, 16 bit signed is the basis for
386c2c66affSColin Finck 		   everything higher than 8 bit. */
387c2c66affSColin Finck 		if(fr->af.encsize > 2)
388c2c66affSColin Finck 		fr->af.dec_enc = MPG123_ENC_SIGNED_16;
389c2c66affSColin Finck 		else
390c2c66affSColin Finck 		{
391c2c66affSColin Finck #endif
392c2c66affSColin Finck 			switch(fr->af.encoding)
393c2c66affSColin Finck 			{
394c2c66affSColin Finck #ifndef NO_32BIT
395c2c66affSColin Finck 			case MPG123_ENC_SIGNED_24:
396c2c66affSColin Finck 			case MPG123_ENC_UNSIGNED_24:
397c2c66affSColin Finck 			case MPG123_ENC_UNSIGNED_32:
398c2c66affSColin Finck 				fr->af.dec_enc = MPG123_ENC_SIGNED_32;
399c2c66affSColin Finck 			break;
400c2c66affSColin Finck #endif
401c2c66affSColin Finck #ifndef NO_16BIT
402c2c66affSColin Finck 			case MPG123_ENC_UNSIGNED_16:
403c2c66affSColin Finck 				fr->af.dec_enc = MPG123_ENC_SIGNED_16;
404c2c66affSColin Finck 			break;
405c2c66affSColin Finck #endif
406c2c66affSColin Finck 			default:
407c2c66affSColin Finck 				fr->af.dec_enc = fr->af.encoding;
408c2c66affSColin Finck 			}
409c2c66affSColin Finck #ifdef NO_SYNTH32
410c2c66affSColin Finck 		}
411c2c66affSColin Finck #endif
412c2c66affSColin Finck 		fr->af.dec_encsize = mpg123_encsize(fr->af.dec_enc);
413c2c66affSColin Finck 		return 1;
414c2c66affSColin Finck 	}
415c2c66affSColin Finck }
416c2c66affSColin Finck 
mpg123_format_none(mpg123_handle * mh)417c2c66affSColin Finck int attribute_align_arg mpg123_format_none(mpg123_handle *mh)
418c2c66affSColin Finck {
419c2c66affSColin Finck 	int r;
420c2c66affSColin Finck 	if(mh == NULL) return MPG123_BAD_HANDLE;
421c2c66affSColin Finck 
422c2c66affSColin Finck 	r = mpg123_fmt_none(&mh->p);
423c2c66affSColin Finck 	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
424c2c66affSColin Finck 
425c2c66affSColin Finck 	return r;
426c2c66affSColin Finck }
427c2c66affSColin Finck 
mpg123_fmt_none(mpg123_pars * mp)428c2c66affSColin Finck int attribute_align_arg mpg123_fmt_none(mpg123_pars *mp)
429c2c66affSColin Finck {
430c2c66affSColin Finck 	if(mp == NULL) return MPG123_BAD_PARS;
431c2c66affSColin Finck 
432c2c66affSColin Finck 	if(PVERB(mp,3)) fprintf(stderr, "Note: Disabling all formats.\n");
433c2c66affSColin Finck 
434c2c66affSColin Finck 	memset(mp->audio_caps,0,sizeof(mp->audio_caps));
435c2c66affSColin Finck 	return MPG123_OK;
436c2c66affSColin Finck }
437c2c66affSColin Finck 
mpg123_format_all(mpg123_handle * mh)438c2c66affSColin Finck int attribute_align_arg mpg123_format_all(mpg123_handle *mh)
439c2c66affSColin Finck {
440c2c66affSColin Finck 	int r;
441c2c66affSColin Finck 	if(mh == NULL) return MPG123_BAD_HANDLE;
442c2c66affSColin Finck 
443c2c66affSColin Finck 	r = mpg123_fmt_all(&mh->p);
444c2c66affSColin Finck 	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
445c2c66affSColin Finck 
446c2c66affSColin Finck 	return r;
447c2c66affSColin Finck }
448c2c66affSColin Finck 
mpg123_fmt_all(mpg123_pars * mp)449c2c66affSColin Finck int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp)
450c2c66affSColin Finck {
451c2c66affSColin Finck 	size_t rate, ch, enc;
452c2c66affSColin Finck 	if(mp == NULL) return MPG123_BAD_PARS;
453c2c66affSColin Finck 
454c2c66affSColin Finck 	if(PVERB(mp,3)) fprintf(stderr, "Note: Enabling all formats.\n");
455c2c66affSColin Finck 
456c2c66affSColin Finck 	for(ch=0;   ch   < NUM_CHANNELS;     ++ch)
457c2c66affSColin Finck 	for(rate=0; rate < MPG123_RATES+1;   ++rate)
458c2c66affSColin Finck 	for(enc=0;  enc  < MPG123_ENCODINGS; ++enc)
459c2c66affSColin Finck 	mp->audio_caps[ch][rate][enc] = good_enc(my_encodings[enc]) ? 1 : 0;
460c2c66affSColin Finck 
461c2c66affSColin Finck 	return MPG123_OK;
462c2c66affSColin Finck }
463c2c66affSColin Finck 
mpg123_format2(mpg123_handle * mh,long rate,int channels,int encodings)464*aa811c00SThomas Faber int attribute_align_arg mpg123_format2(mpg123_handle *mh, long rate, int channels, int encodings)
465*aa811c00SThomas Faber {
466*aa811c00SThomas Faber 	int r;
467*aa811c00SThomas Faber 	if(mh == NULL) return MPG123_BAD_HANDLE;
468*aa811c00SThomas Faber 	r = mpg123_fmt2(&mh->p, rate, channels, encodings);
469*aa811c00SThomas Faber 	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
470*aa811c00SThomas Faber 
471*aa811c00SThomas Faber 	return r;
472*aa811c00SThomas Faber }
473*aa811c00SThomas Faber 
474*aa811c00SThomas Faber // Keep old behaviour.
mpg123_format(mpg123_handle * mh,long rate,int channels,int encodings)475c2c66affSColin Finck int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
476c2c66affSColin Finck {
477c2c66affSColin Finck 	int r;
478c2c66affSColin Finck 	if(mh == NULL) return MPG123_BAD_HANDLE;
479c2c66affSColin Finck 	r = mpg123_fmt(&mh->p, rate, channels, encodings);
480c2c66affSColin Finck 	if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
481c2c66affSColin Finck 
482c2c66affSColin Finck 	return r;
483c2c66affSColin Finck }
484c2c66affSColin Finck 
mpg123_fmt2(mpg123_pars * mp,long rate,int channels,int encodings)485*aa811c00SThomas Faber int attribute_align_arg mpg123_fmt2(mpg123_pars *mp, long rate, int channels, int encodings)
486c2c66affSColin Finck {
487*aa811c00SThomas Faber 	int ie, ic, ratei, r1, r2;
488c2c66affSColin Finck 	int ch[2] = {0, 1};
489c2c66affSColin Finck 	if(mp == NULL) return MPG123_BAD_PARS;
490c2c66affSColin Finck 	if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL;
491c2c66affSColin Finck 
492c2c66affSColin Finck 	if(PVERB(mp,3)) fprintf(stderr, "Note: Want to enable format %li/%i for encodings 0x%x.\n", rate, channels, encodings);
493c2c66affSColin Finck 
494c2c66affSColin Finck 	if(!(channels & MPG123_STEREO)) ch[1] = 0;     /* {0,0} */
495c2c66affSColin Finck 	else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */
496*aa811c00SThomas Faber 	if(rate)
497*aa811c00SThomas Faber 	{
498*aa811c00SThomas Faber 		r1 = rate2num(mp, rate);
499*aa811c00SThomas Faber 		r2 = r1+1;
500*aa811c00SThomas Faber 	}
501*aa811c00SThomas Faber 	else
502*aa811c00SThomas Faber 	{
503*aa811c00SThomas Faber 		r1 = 0;
504*aa811c00SThomas Faber 		r2 = MPG123_RATES+1; /* including forced rate */
505*aa811c00SThomas Faber 	}
506*aa811c00SThomas Faber 
507*aa811c00SThomas Faber 	if(r1 < 0) return MPG123_BAD_RATE;
508c2c66affSColin Finck 
509c2c66affSColin Finck 	/* now match the encodings */
510*aa811c00SThomas Faber 	for(ratei = r1; ratei < r2; ++ratei)
511c2c66affSColin Finck 	for(ic = 0; ic < 2; ++ic)
512c2c66affSColin Finck 	{
513c2c66affSColin Finck 		for(ie = 0; ie < MPG123_ENCODINGS; ++ie)
514c2c66affSColin Finck 		if(good_enc(my_encodings[ie]) && ((my_encodings[ie] & encodings) == my_encodings[ie]))
515c2c66affSColin Finck 		mp->audio_caps[ch[ic]][ratei][ie] = 1;
516c2c66affSColin Finck 
517c2c66affSColin Finck 		if(ch[0] == ch[1]) break; /* no need to do it again */
518c2c66affSColin Finck 	}
519c2c66affSColin Finck 
520c2c66affSColin Finck 	return MPG123_OK;
521c2c66affSColin Finck }
522c2c66affSColin Finck 
523*aa811c00SThomas Faber // Keep old behaviour, error on rate=0.
mpg123_fmt(mpg123_pars * mp,long rate,int channels,int encodings)524*aa811c00SThomas Faber int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
525*aa811c00SThomas Faber {
526*aa811c00SThomas Faber 	return (rate == 0)
527*aa811c00SThomas Faber 	?	MPG123_BAD_RATE
528*aa811c00SThomas Faber 	:	mpg123_fmt2(mp, rate, channels, encodings);
529*aa811c00SThomas Faber }
530*aa811c00SThomas Faber 
mpg123_format_support(mpg123_handle * mh,long rate,int encoding)531c2c66affSColin Finck int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding)
532c2c66affSColin Finck {
533c2c66affSColin Finck 	if(mh == NULL) return 0;
534c2c66affSColin Finck 	else return mpg123_fmt_support(&mh->p, rate, encoding);
535c2c66affSColin Finck }
536c2c66affSColin Finck 
mpg123_fmt_support(mpg123_pars * mp,long rate,int encoding)537c2c66affSColin Finck int attribute_align_arg mpg123_fmt_support(mpg123_pars *mp, long rate, int encoding)
538c2c66affSColin Finck {
539c2c66affSColin Finck 	int ch = 0;
540c2c66affSColin Finck 	int ratei, enci;
541c2c66affSColin Finck 	ratei = rate2num(mp, rate);
542c2c66affSColin Finck 	enci  = enc2num(encoding);
543c2c66affSColin Finck 	if(mp == NULL || ratei < 0 || enci < 0) return 0;
544c2c66affSColin Finck 	if(mp->audio_caps[0][ratei][enci]) ch |= MPG123_MONO;
545c2c66affSColin Finck 	if(mp->audio_caps[1][ratei][enci]) ch |= MPG123_STEREO;
546c2c66affSColin Finck 	return ch;
547c2c66affSColin Finck }
548c2c66affSColin Finck 
549c2c66affSColin Finck /* Call this one to ensure that any valid format will be something different than this. */
invalidate_format(struct audioformat * af)550c2c66affSColin Finck void invalidate_format(struct audioformat *af)
551c2c66affSColin Finck {
552c2c66affSColin Finck 	af->encoding = 0;
553c2c66affSColin Finck 	af->rate     = 0;
554c2c66affSColin Finck 	af->channels = 0;
555c2c66affSColin Finck }
556c2c66affSColin Finck 
557c2c66affSColin Finck /* Number of bytes the decoder produces. */
decoder_synth_bytes(mpg123_handle * fr,off_t s)558c2c66affSColin Finck off_t decoder_synth_bytes(mpg123_handle *fr, off_t s)
559c2c66affSColin Finck {
560c2c66affSColin Finck 	return s * fr->af.dec_encsize * fr->af.channels;
561c2c66affSColin Finck }
562c2c66affSColin Finck 
563c2c66affSColin Finck /* Samples/bytes for output buffer after post-processing. */
564c2c66affSColin Finck /* take into account: channels, bytes per sample -- NOT resampling!*/
samples_to_bytes(mpg123_handle * fr,off_t s)565c2c66affSColin Finck off_t samples_to_bytes(mpg123_handle *fr , off_t s)
566c2c66affSColin Finck {
567c2c66affSColin Finck 	return s * fr->af.encsize * fr->af.channels;
568c2c66affSColin Finck }
569c2c66affSColin Finck 
bytes_to_samples(mpg123_handle * fr,off_t b)570c2c66affSColin Finck off_t bytes_to_samples(mpg123_handle *fr , off_t b)
571c2c66affSColin Finck {
572c2c66affSColin Finck 	return b / fr->af.encsize / fr->af.channels;
573c2c66affSColin Finck }
574c2c66affSColin Finck 
575c2c66affSColin Finck /* Number of bytes needed for decoding _and_ post-processing. */
outblock_bytes(mpg123_handle * fr,off_t s)576c2c66affSColin Finck off_t outblock_bytes(mpg123_handle *fr, off_t s)
577c2c66affSColin Finck {
578c2c66affSColin Finck 	int encsize = (fr->af.encoding & MPG123_ENC_24)
579c2c66affSColin Finck 	? 4 /* Intermediate 32 bit. */
580c2c66affSColin Finck 	: (fr->af.encsize > fr->af.dec_encsize
581c2c66affSColin Finck 		? fr->af.encsize
582c2c66affSColin Finck 		: fr->af.dec_encsize);
583c2c66affSColin Finck 	return s * encsize * fr->af.channels;
584c2c66affSColin Finck }
585c2c66affSColin Finck 
586c2c66affSColin Finck #ifndef NO_32BIT
587*aa811c00SThomas Faber 
588c2c66affSColin Finck /* Remove every fourth byte, facilitating conversion from 32 bit to 24 bit integers.
589c2c66affSColin Finck    This has to be aware of endianness, of course. */
chop_fourth_byte(struct outbuffer * buf)590c2c66affSColin Finck static void chop_fourth_byte(struct outbuffer *buf)
591c2c66affSColin Finck {
592c2c66affSColin Finck 	unsigned char *wpos = buf->data;
593c2c66affSColin Finck 	unsigned char *rpos = buf->data;
594*aa811c00SThomas Faber 	size_t blocks = buf->fill/4;
595*aa811c00SThomas Faber 	size_t i;
596*aa811c00SThomas Faber 	for(i=0; i<blocks; ++i,wpos+=3,rpos+=4)
597*aa811c00SThomas Faber 		DROP4BYTE(wpos, rpos)
598c2c66affSColin Finck 	buf->fill = wpos-buf->data;
599c2c66affSColin Finck }
600c2c66affSColin Finck 
conv_s32_to_u32(struct outbuffer * buf)601c2c66affSColin Finck static void conv_s32_to_u32(struct outbuffer *buf)
602c2c66affSColin Finck {
603c2c66affSColin Finck 	size_t i;
604c2c66affSColin Finck 	int32_t  *ssamples = (int32_t*)  buf->data;
605c2c66affSColin Finck 	uint32_t *usamples = (uint32_t*) buf->data;
606c2c66affSColin Finck 	size_t count = buf->fill/sizeof(int32_t);
607c2c66affSColin Finck 
608c2c66affSColin Finck 	for(i=0; i<count; ++i)
609*aa811c00SThomas Faber 		usamples[i] = CONV_SU32(ssamples[i]);
610c2c66affSColin Finck }
611c2c66affSColin Finck 
612c2c66affSColin Finck #endif
613c2c66affSColin Finck 
614c2c66affSColin Finck 
615c2c66affSColin Finck /* We always assume that whole numbers are written!
616c2c66affSColin Finck    partials will be cut out. */
617c2c66affSColin Finck 
618c2c66affSColin Finck static const char *bufsizeerr = "Fatal: Buffer too small for postprocessing!";
619c2c66affSColin Finck 
620c2c66affSColin Finck 
621c2c66affSColin Finck #ifndef NO_16BIT
622c2c66affSColin Finck 
conv_s16_to_u16(struct outbuffer * buf)623c2c66affSColin Finck static void conv_s16_to_u16(struct outbuffer *buf)
624c2c66affSColin Finck {
625c2c66affSColin Finck 	size_t i;
626c2c66affSColin Finck 	int16_t  *ssamples = (int16_t*) buf->data;
627c2c66affSColin Finck 	uint16_t *usamples = (uint16_t*)buf->data;
628c2c66affSColin Finck 	size_t count = buf->fill/sizeof(int16_t);
629c2c66affSColin Finck 
630c2c66affSColin Finck 	for(i=0; i<count; ++i)
631*aa811c00SThomas Faber 		usamples[i] = CONV_SU16(ssamples[i]);
632c2c66affSColin Finck }
633c2c66affSColin Finck 
634c2c66affSColin Finck #ifndef NO_REAL
conv_s16_to_f32(struct outbuffer * buf)635c2c66affSColin Finck static void conv_s16_to_f32(struct outbuffer *buf)
636c2c66affSColin Finck {
637c2c66affSColin Finck 	ssize_t i;
638c2c66affSColin Finck 	int16_t *in = (int16_t*) buf->data;
639c2c66affSColin Finck 	float  *out = (float*)   buf->data;
640c2c66affSColin Finck 	size_t count = buf->fill/sizeof(int16_t);
641c2c66affSColin Finck 	/* Does that make any sense? In x86, there is an actual instruction to divide
642c2c66affSColin Finck 	   float by integer ... but then, if we have that FPU, we don't really need
643c2c66affSColin Finck 	   fixed point decoder hacks ...? */
644c2c66affSColin Finck 	float scale = 1./SHORT_SCALE;
645c2c66affSColin Finck 
646c2c66affSColin Finck 	if(buf->size < count*sizeof(float))
647c2c66affSColin Finck 	{
648c2c66affSColin Finck 		error1("%s", bufsizeerr);
649c2c66affSColin Finck 		return;
650c2c66affSColin Finck 	}
651c2c66affSColin Finck 
652c2c66affSColin Finck 	/* Work from the back since output is bigger. */
653c2c66affSColin Finck 	for(i=count-1; i>=0; --i)
654c2c66affSColin Finck 	out[i] = (float)in[i] * scale;
655c2c66affSColin Finck 
656c2c66affSColin Finck 	buf->fill = count*sizeof(float);
657c2c66affSColin Finck }
658c2c66affSColin Finck #endif
659c2c66affSColin Finck 
660c2c66affSColin Finck #ifndef NO_32BIT
conv_s16_to_s32(struct outbuffer * buf)661c2c66affSColin Finck static void conv_s16_to_s32(struct outbuffer *buf)
662c2c66affSColin Finck {
663c2c66affSColin Finck 	ssize_t i;
664c2c66affSColin Finck 	int16_t  *in = (int16_t*) buf->data;
665c2c66affSColin Finck 	int32_t *out = (int32_t*) buf->data;
666c2c66affSColin Finck 	size_t count = buf->fill/sizeof(int16_t);
667c2c66affSColin Finck 
668c2c66affSColin Finck 	if(buf->size < count*sizeof(int32_t))
669c2c66affSColin Finck 	{
670c2c66affSColin Finck 		error1("%s", bufsizeerr);
671c2c66affSColin Finck 		return;
672c2c66affSColin Finck 	}
673c2c66affSColin Finck 
674c2c66affSColin Finck 	/* Work from the back since output is bigger. */
675c2c66affSColin Finck 	for(i=count-1; i>=0; --i)
676c2c66affSColin Finck 	{
677c2c66affSColin Finck 		out[i] = in[i];
678c2c66affSColin Finck 		/* Could just shift bytes, but would have to mess with sign bit. */
679c2c66affSColin Finck 		out[i] *= S32_RESCALE;
680c2c66affSColin Finck 	}
681c2c66affSColin Finck 
682c2c66affSColin Finck 	buf->fill = count*sizeof(int32_t);
683c2c66affSColin Finck }
684c2c66affSColin Finck #endif
685c2c66affSColin Finck #endif
686c2c66affSColin Finck 
687*aa811c00SThomas Faber #include "swap_bytes_impl.h"
688*aa811c00SThomas Faber 
swap_endian(struct outbuffer * buf,int block)689*aa811c00SThomas Faber void swap_endian(struct outbuffer *buf, int block)
690*aa811c00SThomas Faber {
691*aa811c00SThomas Faber 	size_t count;
692*aa811c00SThomas Faber 
693*aa811c00SThomas Faber 	if(block >= 2)
694*aa811c00SThomas Faber 	{
695*aa811c00SThomas Faber 		count = buf->fill/(unsigned int)block;
696*aa811c00SThomas Faber 		swap_bytes(buf->data, (size_t)block, count);
697*aa811c00SThomas Faber 	}
698*aa811c00SThomas Faber }
699c2c66affSColin Finck 
postprocess_buffer(mpg123_handle * fr)700c2c66affSColin Finck void postprocess_buffer(mpg123_handle *fr)
701c2c66affSColin Finck {
702c2c66affSColin Finck 	/*
703c2c66affSColin Finck 		This caters for the final output formats that are never produced by
704c2c66affSColin Finck 		decoder synth directly (wide unsigned and 24 bit formats) or that are
705c2c66affSColin Finck 		missing because of limited decoder precision (16 bit synth but 32 or
706c2c66affSColin Finck 		24 bit output).
707c2c66affSColin Finck 	*/
708c2c66affSColin Finck 	switch(fr->af.dec_enc)
709c2c66affSColin Finck 	{
710c2c66affSColin Finck #ifndef NO_32BIT
711c2c66affSColin Finck 	case MPG123_ENC_SIGNED_32:
712c2c66affSColin Finck 		switch(fr->af.encoding)
713c2c66affSColin Finck 		{
714c2c66affSColin Finck 		case MPG123_ENC_UNSIGNED_32:
715c2c66affSColin Finck 			conv_s32_to_u32(&fr->buffer);
716c2c66affSColin Finck 		break;
717c2c66affSColin Finck 		case MPG123_ENC_UNSIGNED_24:
718c2c66affSColin Finck 			conv_s32_to_u32(&fr->buffer);
719c2c66affSColin Finck 			chop_fourth_byte(&fr->buffer);
720c2c66affSColin Finck 		break;
721c2c66affSColin Finck 		case MPG123_ENC_SIGNED_24:
722c2c66affSColin Finck 			chop_fourth_byte(&fr->buffer);
723c2c66affSColin Finck 		break;
724c2c66affSColin Finck 		}
725c2c66affSColin Finck 	break;
726c2c66affSColin Finck #endif
727c2c66affSColin Finck #ifndef NO_16BIT
728c2c66affSColin Finck 	case MPG123_ENC_SIGNED_16:
729c2c66affSColin Finck 		switch(fr->af.encoding)
730c2c66affSColin Finck 		{
731c2c66affSColin Finck 		case MPG123_ENC_UNSIGNED_16:
732c2c66affSColin Finck 			conv_s16_to_u16(&fr->buffer);
733c2c66affSColin Finck 		break;
734c2c66affSColin Finck #ifndef NO_REAL
735c2c66affSColin Finck 		case MPG123_ENC_FLOAT_32:
736c2c66affSColin Finck 			conv_s16_to_f32(&fr->buffer);
737c2c66affSColin Finck 		break;
738c2c66affSColin Finck #endif
739c2c66affSColin Finck #ifndef NO_32BIT
740c2c66affSColin Finck 		case MPG123_ENC_SIGNED_32:
741c2c66affSColin Finck 			conv_s16_to_s32(&fr->buffer);
742c2c66affSColin Finck 		break;
743c2c66affSColin Finck 		case MPG123_ENC_UNSIGNED_32:
744c2c66affSColin Finck 			conv_s16_to_s32(&fr->buffer);
745c2c66affSColin Finck 			conv_s32_to_u32(&fr->buffer);
746c2c66affSColin Finck 		break;
747c2c66affSColin Finck 		case MPG123_ENC_UNSIGNED_24:
748c2c66affSColin Finck 			conv_s16_to_s32(&fr->buffer);
749c2c66affSColin Finck 			conv_s32_to_u32(&fr->buffer);
750c2c66affSColin Finck 			chop_fourth_byte(&fr->buffer);
751c2c66affSColin Finck 		break;
752c2c66affSColin Finck 		case MPG123_ENC_SIGNED_24:
753c2c66affSColin Finck 			conv_s16_to_s32(&fr->buffer);
754c2c66affSColin Finck 			chop_fourth_byte(&fr->buffer);
755c2c66affSColin Finck 		break;
756c2c66affSColin Finck #endif
757c2c66affSColin Finck 		}
758c2c66affSColin Finck 	break;
759c2c66affSColin Finck #endif
760c2c66affSColin Finck 	}
761*aa811c00SThomas Faber 	if(fr->p.flags & MPG123_FORCE_ENDIAN)
762*aa811c00SThomas Faber 	{
763*aa811c00SThomas Faber 		if(
764*aa811c00SThomas Faber #ifdef WORDS_BIGENDIAN
765*aa811c00SThomas Faber 			!(
766*aa811c00SThomas Faber #endif
767*aa811c00SThomas Faber 				fr->p.flags & MPG123_BIG_ENDIAN
768*aa811c00SThomas Faber #ifdef WORDS_BIGENDIAN
769*aa811c00SThomas Faber 			)
770*aa811c00SThomas Faber #endif
771*aa811c00SThomas Faber 		)
772*aa811c00SThomas Faber 			swap_endian(&fr->buffer, mpg123_encsize(fr->af.encoding));
773*aa811c00SThomas Faber 	}
774c2c66affSColin Finck }
775