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