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