Mercurial > SDL_sound_CoreAudio
comparison decoders/libmpg123/libmpg123.c @ 562:7e08477b0fc1
MP3 decoder upgrade work.
Ripped out SMPEG and mpglib support, replaced it with "mpg123.c" and libmpg123.
libmpg123 is a much better version of mpglib, so it should solve all the
problems about MP3's not seeking, or most modern MP3's not playing at all,
etc. Since you no longer have to make a tradeoff with SMPEG for features, and
SMPEG is basically rotting, I removed it from the project.
There is still work to be done with libmpg123...there are MMX, 3DNow, SSE,
Altivec, etc decoders which we don't have enabled at the moment, and the
build system could use some work to make this compile more cleanly, etc.
Still: huge win.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Fri, 30 Jan 2009 02:44:47 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
561:f2985e08589c | 562:7e08477b0fc1 |
---|---|
1 /* | |
2 libmpg123: MPEG Audio Decoder library | |
3 | |
4 copyright 1995-2008 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 | |
7 */ | |
8 | |
9 #include "mpg123lib_intern.h" | |
10 #include "icy2utf8.h" | |
11 #include "getbits.h" | |
12 #include "debug.h" | |
13 | |
14 #ifdef GAPLESS | |
15 #define SAMPLE_ADJUST(x) ((x) - ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0)) | |
16 #define SAMPLE_UNADJUST(x) ((x) + ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0)) | |
17 #else | |
18 #define SAMPLE_ADJUST(x) (x) | |
19 #define SAMPLE_UNADJUST(x) (x) | |
20 #endif | |
21 | |
22 #define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe) | |
23 | |
24 static int initialized = 0; | |
25 | |
26 #define ALIGNCHECK(mh) | |
27 #define ALIGNCHECKK | |
28 /* On compilers that support data alignment but not the automatic stack realignment. | |
29 We check for properly aligned stack before risking a crash because of badly compiled | |
30 client program. */ | |
31 #if (defined CCALIGN) && (defined NEED_ALIGNCHECK) && ((defined DEBUG) || (defined CHECK_ALIGN)) | |
32 | |
33 /* Common building block. */ | |
34 #define ALIGNMAINPART \ | |
35 /* minimum size of 16 bytes, not all compilers would align a smaller piece of data */ \ | |
36 double ALIGNED(16) altest[2]; \ | |
37 debug2("testing alignment, with %lu %% 16 = %lu", \ | |
38 (unsigned long)altest, (unsigned long)((size_t)altest % 16)); \ | |
39 if((size_t)altest % 16 != 0) | |
40 | |
41 #undef ALIGNCHECK | |
42 #define ALIGNCHECK(mh) \ | |
43 ALIGNMAINPART \ | |
44 { \ | |
45 error("Stack variable is not aligned! Your combination of compiler/library is dangerous!"); \ | |
46 if(mh != NULL) mh->err = MPG123_BAD_ALIGN; \ | |
47 \ | |
48 return MPG123_ERR; \ | |
49 } | |
50 #undef ALIGNCHECKK | |
51 #define ALIGNCHECKK \ | |
52 ALIGNMAINPART \ | |
53 { \ | |
54 error("Stack variable is not aligned! Your combination of compiler/library is dangerous!"); \ | |
55 return MPG123_BAD_ALIGN; \ | |
56 } | |
57 | |
58 #endif | |
59 | |
60 | |
61 #ifdef GAPLESS | |
62 /* | |
63 Take the buffer after a frame decode (strictly: it is the data from frame fr->num!) and cut samples out. | |
64 fr->buffer.fill may then be smaller than before... | |
65 */ | |
66 static void frame_buffercheck(mpg123_handle *fr) | |
67 { | |
68 /* When we have no accurate position, gapless code does not make sense. */ | |
69 if(!fr->accurate) return; | |
70 | |
71 /* The first interesting frame: Skip some leading samples. */ | |
72 if(fr->firstoff && fr->num == fr->firstframe) | |
73 { | |
74 off_t byteoff = samples_to_bytes(fr, fr->firstoff); | |
75 if(fr->buffer.fill > byteoff) | |
76 { | |
77 fr->buffer.fill -= byteoff; | |
78 /* buffer.p != buffer.data only for own buffer */ | |
79 debug6("cutting %li samples/%li bytes on begin, own_buffer=%i at %p=%p, buf[1]=%i", | |
80 (long)fr->firstoff, (long)byteoff, fr->own_buffer, (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]); | |
81 if(fr->own_buffer) fr->buffer.p = fr->buffer.data + byteoff; | |
82 else memmove(fr->buffer.data, fr->buffer.data + byteoff, fr->buffer.fill); | |
83 debug3("done cutting, buffer at %p =? %p, buf[1]=%i", | |
84 (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]); | |
85 } | |
86 else fr->buffer.fill = 0; | |
87 fr->firstoff = 0; /* Only enter here once... when you seek, firstoff should be reset. */ | |
88 } | |
89 /* The last interesting (planned) frame: Only use some leading samples. */ | |
90 if(fr->lastoff && fr->num == fr->lastframe) | |
91 { | |
92 off_t byteoff = samples_to_bytes(fr, fr->lastoff); | |
93 if(fr->buffer.fill > byteoff) | |
94 { | |
95 fr->buffer.fill = byteoff; | |
96 } | |
97 fr->lastoff = 0; /* Only enter here once... when you seek, lastoff should be reset. */ | |
98 } | |
99 } | |
100 #endif | |
101 | |
102 | |
103 int attribute_align_arg mpg123_init(void) | |
104 { | |
105 ALIGNCHECKK | |
106 if((sizeof(short) != 2) || (sizeof(long) < 4)) return MPG123_BAD_TYPES; | |
107 | |
108 init_layer2(); /* inits also shared tables with layer1 */ | |
109 init_layer3(); | |
110 #ifndef OPT_MMX_ONLY | |
111 prepare_decode_tables(); | |
112 #endif | |
113 check_decoders(); | |
114 initialized = 1; | |
115 return MPG123_OK; | |
116 } | |
117 | |
118 void attribute_align_arg mpg123_exit(void) | |
119 { | |
120 /* nothing yet, but something later perhaps */ | |
121 if(initialized) return; | |
122 } | |
123 | |
124 /* create a new handle with specified decoder, decoder can be "", "auto" or NULL for auto-detection */ | |
125 mpg123_handle attribute_align_arg *mpg123_new(const char* decoder, int *error) | |
126 { | |
127 return mpg123_parnew(NULL, decoder, error); | |
128 } | |
129 | |
130 /* ...the full routine with optional initial parameters to override defaults. */ | |
131 mpg123_handle attribute_align_arg *mpg123_parnew(mpg123_pars *mp, const char* decoder, int *error) | |
132 { | |
133 mpg123_handle *fr = NULL; | |
134 int err = MPG123_OK; | |
135 #ifdef DEBUG | |
136 #ifdef CCALIGN | |
137 double ALIGNED(16) altest[4]; | |
138 if(((size_t)altest) % 16 != 0) | |
139 { | |
140 error("Stack variable is not aligned! Your combination of compiler/library is dangerous!"); | |
141 *error = MPG123_BAD_ALIGN; | |
142 return NULL; | |
143 } | |
144 #endif | |
145 #endif | |
146 if(initialized) fr = (mpg123_handle*) malloc(sizeof(mpg123_handle)); | |
147 else err = MPG123_NOT_INITIALIZED; | |
148 if(fr != NULL) | |
149 { | |
150 frame_init_par(fr, mp); | |
151 debug("cpu opt setting"); | |
152 if(frame_cpu_opt(fr, decoder) != 1) | |
153 { | |
154 err = MPG123_BAD_DECODER; | |
155 frame_exit(fr); | |
156 free(fr); | |
157 fr = NULL; | |
158 } | |
159 } | |
160 if(fr != NULL) | |
161 { | |
162 if((frame_outbuffer(fr) != 0) || (frame_buffers(fr) != 0)) | |
163 { | |
164 err = MPG123_NO_BUFFERS; | |
165 frame_exit(fr); | |
166 free(fr); | |
167 fr = NULL; | |
168 } | |
169 else | |
170 { | |
171 opt_make_decode_tables(fr); | |
172 fr->decoder_change = 1; | |
173 /* happening on frame change instead: | |
174 init_layer3_stuff(fr); | |
175 init_layer2_stuff(fr); */ | |
176 } | |
177 } | |
178 else if(err == MPG123_OK) err = MPG123_OUT_OF_MEM; | |
179 | |
180 if(error != NULL) *error = err; | |
181 return fr; | |
182 } | |
183 | |
184 int attribute_align_arg mpg123_decoder(mpg123_handle *mh, const char* decoder) | |
185 { | |
186 enum optdec dt = dectype(decoder); | |
187 ALIGNCHECK(mh); | |
188 if(mh == NULL) return MPG123_ERR; | |
189 | |
190 if(dt == nodec) | |
191 { | |
192 mh->err = MPG123_BAD_DECODER; | |
193 return MPG123_ERR; | |
194 } | |
195 if(dt == mh->cpu_opts.type) return MPG123_OK; | |
196 | |
197 /* Now really change. */ | |
198 /* frame_exit(mh); | |
199 frame_init(mh); */ | |
200 debug("cpu opt setting"); | |
201 if(frame_cpu_opt(mh, decoder) != 1) | |
202 { | |
203 mh->err = MPG123_BAD_DECODER; | |
204 frame_exit(mh); | |
205 return MPG123_ERR; | |
206 } | |
207 /* New buffers for decoder are created in frame_buffers() */ | |
208 if((frame_outbuffer(mh) != 0) || (frame_buffers(mh) != 0)) | |
209 { | |
210 mh->err = MPG123_NO_BUFFERS; | |
211 frame_exit(mh); | |
212 return MPG123_ERR; | |
213 } | |
214 opt_make_decode_tables(mh); | |
215 mh->decoder_change = 1; | |
216 return MPG123_OK; | |
217 } | |
218 | |
219 int attribute_align_arg mpg123_param(mpg123_handle *mh, enum mpg123_parms key, long val, double fval) | |
220 { | |
221 int r; | |
222 ALIGNCHECK(mh); | |
223 if(mh == NULL) return MPG123_ERR; | |
224 r = mpg123_par(&mh->p, key, val, fval); | |
225 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } | |
226 else | |
227 { /* Special treatment for some settings. */ | |
228 #ifdef FRAME_INDEX | |
229 if(key == MPG123_INDEX_SIZE) | |
230 { /* Apply frame index size and grow property on the fly. */ | |
231 r = frame_index_setup(mh); | |
232 if(r != MPG123_OK) mh->err = MPG123_INDEX_FAIL; | |
233 } | |
234 #endif | |
235 } | |
236 return r; | |
237 } | |
238 | |
239 int attribute_align_arg mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long val, double fval) | |
240 { | |
241 int ret = MPG123_OK; | |
242 ALIGNCHECKK | |
243 if(mp == NULL) return MPG123_BAD_PARS; | |
244 switch(key) | |
245 { | |
246 case MPG123_VERBOSE: | |
247 mp->verbose = val; | |
248 break; | |
249 case MPG123_FLAGS: | |
250 #ifndef GAPLESS | |
251 if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS; | |
252 #endif | |
253 #ifdef FLOATOUT | |
254 if(val & MPG123_FORCE_8BIT) ret = MPG123_NO_8BIT; | |
255 #endif | |
256 if(ret == MPG123_OK) mp->flags = val; | |
257 debug1("set flags to 0x%lx", (unsigned long) mp->flags); | |
258 break; | |
259 case MPG123_ADD_FLAGS: | |
260 #ifndef GAPLESS | |
261 /* Enabling of gapless mode doesn't work when it's not there, but disabling (below) is no problem. */ | |
262 if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS; | |
263 else | |
264 #endif | |
265 mp->flags |= val; | |
266 debug1("set flags to 0x%lx", (unsigned long) mp->flags); | |
267 break; | |
268 case MPG123_REMOVE_FLAGS: | |
269 mp->flags &= ~val; | |
270 debug1("set flags to 0x%lx", (unsigned long) mp->flags); | |
271 break; | |
272 case MPG123_FORCE_RATE: /* should this trigger something? */ | |
273 if(val > 96000) ret = MPG123_BAD_RATE; | |
274 else mp->force_rate = val < 0 ? 0 : val; /* >0 means enable, 0 disable */ | |
275 break; | |
276 case MPG123_DOWN_SAMPLE: | |
277 if(val < 0 || val > 2) ret = MPG123_BAD_RATE; | |
278 else mp->down_sample = (int)val; | |
279 break; | |
280 case MPG123_RVA: | |
281 if(val < 0 || val > MPG123_RVA_MAX) ret = MPG123_BAD_RVA; | |
282 else mp->rva = (int)val; | |
283 break; | |
284 case MPG123_DOWNSPEED: | |
285 mp->halfspeed = val < 0 ? 0 : val; | |
286 break; | |
287 case MPG123_UPSPEED: | |
288 mp->doublespeed = val < 0 ? 0 : val; | |
289 break; | |
290 case MPG123_ICY_INTERVAL: | |
291 mp->icy_interval = val > 0 ? val : 0; | |
292 break; | |
293 case MPG123_OUTSCALE: | |
294 #ifdef FLOATOUT | |
295 mp->outscale = fval; | |
296 #else | |
297 mp->outscale = val; | |
298 #endif | |
299 break; | |
300 case MPG123_TIMEOUT: | |
301 #ifndef WIN32 | |
302 mp->timeout = val >= 0 ? val : 0; | |
303 #else | |
304 ret = MPG123_NO_TIMEOUT; | |
305 #endif | |
306 break; | |
307 case MPG123_RESYNC_LIMIT: | |
308 mp->resync_limit = val; | |
309 break; | |
310 case MPG123_INDEX_SIZE: | |
311 #ifdef FRAME_INDEX | |
312 mp->index_size = val; | |
313 #else | |
314 ret = MPG123_NO_INDEX; | |
315 #endif | |
316 break; | |
317 default: | |
318 ret = MPG123_BAD_PARAM; | |
319 } | |
320 return ret; | |
321 } | |
322 | |
323 int attribute_align_arg mpg123_getparam(mpg123_handle *mh, enum mpg123_parms key, long *val, double *fval) | |
324 { | |
325 int r; | |
326 ALIGNCHECK(mh); | |
327 if(mh == NULL) return MPG123_ERR; | |
328 r = mpg123_getpar(&mh->p, key, val, fval); | |
329 if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; } | |
330 return r; | |
331 } | |
332 | |
333 int attribute_align_arg mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, long *val, double *fval) | |
334 { | |
335 int ret = 0; | |
336 ALIGNCHECKK | |
337 if(mp == NULL) return MPG123_BAD_PARS; | |
338 switch(key) | |
339 { | |
340 case MPG123_VERBOSE: | |
341 if(val) *val = mp->verbose; | |
342 break; | |
343 case MPG123_FLAGS: | |
344 case MPG123_ADD_FLAGS: | |
345 if(val) *val = mp->flags; | |
346 break; | |
347 case MPG123_FORCE_RATE: | |
348 if(val) *val = mp->force_rate; | |
349 break; | |
350 case MPG123_DOWN_SAMPLE: | |
351 if(val) *val = mp->down_sample; | |
352 break; | |
353 case MPG123_RVA: | |
354 if(val) *val = mp->rva; | |
355 break; | |
356 case MPG123_DOWNSPEED: | |
357 if(val) *val = mp->halfspeed; | |
358 break; | |
359 case MPG123_UPSPEED: | |
360 if(val) *val = mp->doublespeed; | |
361 break; | |
362 case MPG123_ICY_INTERVAL: | |
363 if(val) *val = (long)mp->icy_interval; | |
364 break; | |
365 case MPG123_OUTSCALE: | |
366 #ifdef FLOATOUT | |
367 if(fval) *fval = mp->outscale; | |
368 #else | |
369 if(val) *val = mp->outscale; | |
370 #endif | |
371 break; | |
372 case MPG123_RESYNC_LIMIT: | |
373 if(val) *val = mp->resync_limit; | |
374 break; | |
375 default: | |
376 ret = MPG123_BAD_PARAM; | |
377 } | |
378 return ret; | |
379 } | |
380 | |
381 int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key, long *val, double *fval) | |
382 { | |
383 int ret = MPG123_OK; | |
384 long theval = 0; | |
385 double thefval = 0.; | |
386 ALIGNCHECK(mh); | |
387 if(mh == NULL) return MPG123_ERR; | |
388 | |
389 switch(key) | |
390 { | |
391 case MPG123_ACCURATE: | |
392 theval = mh->accurate; | |
393 break; | |
394 default: | |
395 mh->err = MPG123_BAD_KEY; | |
396 ret = MPG123_ERR; | |
397 } | |
398 | |
399 if(val != NULL) *val = theval; | |
400 if(fval != NULL) *fval = thefval; | |
401 | |
402 return ret; | |
403 } | |
404 | |
405 int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val) | |
406 { | |
407 ALIGNCHECK(mh); | |
408 if(mh == NULL) return MPG123_ERR; | |
409 if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; } | |
410 switch(channel) | |
411 { | |
412 case MPG123_LEFT|MPG123_RIGHT: | |
413 mh->equalizer[0][band] = mh->equalizer[1][band] = DOUBLE_TO_REAL(val); | |
414 break; | |
415 case MPG123_LEFT: mh->equalizer[0][band] = DOUBLE_TO_REAL(val); break; | |
416 case MPG123_RIGHT: mh->equalizer[1][band] = DOUBLE_TO_REAL(val); break; | |
417 default: | |
418 mh->err=MPG123_BAD_CHANNEL; | |
419 return MPG123_ERR; | |
420 } | |
421 mh->have_eq_settings = TRUE; | |
422 return MPG123_OK; | |
423 } | |
424 | |
425 double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band) | |
426 { | |
427 double ret = 0.; | |
428 ALIGNCHECK(mh); | |
429 if(mh == NULL) return MPG123_ERR; | |
430 | |
431 /* Handle this gracefully. When there is no band, it has no volume. */ | |
432 if(band > -1 && band < 32) | |
433 switch(channel) | |
434 { | |
435 case MPG123_LEFT|MPG123_RIGHT: | |
436 ret = 0.5*(REAL_TO_DOUBLE(mh->equalizer[0][band])+REAL_TO_DOUBLE(mh->equalizer[1][band])); | |
437 break; | |
438 case MPG123_LEFT: ret = REAL_TO_DOUBLE(mh->equalizer[0][band]); break; | |
439 case MPG123_RIGHT: ret = REAL_TO_DOUBLE(mh->equalizer[1][band]); break; | |
440 /* Default case is already handled: ret = 0 */ | |
441 } | |
442 | |
443 return ret; | |
444 } | |
445 | |
446 | |
447 /* plain file access, no http! */ | |
448 int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path) | |
449 { | |
450 ALIGNCHECK(mh); | |
451 if(mh == NULL) return MPG123_ERR; | |
452 | |
453 mpg123_close(mh); | |
454 frame_reset(mh); | |
455 return open_stream(mh, path, -1); | |
456 } | |
457 | |
458 int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd) | |
459 { | |
460 ALIGNCHECK(mh); | |
461 if(mh == NULL) return MPG123_ERR; | |
462 | |
463 mpg123_close(mh); | |
464 frame_reset(mh); | |
465 return open_stream(mh, NULL, fd); | |
466 } | |
467 | |
468 int attribute_align_arg mpg123_open_feed(mpg123_handle *mh) | |
469 { | |
470 ALIGNCHECK(mh); | |
471 if(mh == NULL) return MPG123_ERR; | |
472 | |
473 mpg123_close(mh); | |
474 frame_reset(mh); | |
475 return open_feed(mh); | |
476 } | |
477 | |
478 int attribute_align_arg mpg123_replace_reader( mpg123_handle *mh, | |
479 ssize_t (*r_read) (int, void *, size_t), | |
480 off_t (*r_lseek)(int, off_t, int) ) | |
481 { | |
482 ALIGNCHECK(mh); | |
483 if(mh == NULL) return MPG123_ERR; | |
484 mh->rdat.r_read = r_read; | |
485 mh->rdat.r_lseek = r_lseek; | |
486 return MPG123_OK; | |
487 } | |
488 | |
489 | |
490 int decode_update(mpg123_handle *mh) | |
491 { | |
492 long native_rate; | |
493 ALIGNCHECK(mh); | |
494 native_rate = frame_freq(mh); | |
495 debug2("updating decoder structure with native rate %li and af.rate %li", native_rate, mh->af.rate); | |
496 if(mh->af.rate == native_rate) mh->down_sample = 0; | |
497 else if(mh->af.rate == native_rate>>1) mh->down_sample = 1; | |
498 else if(mh->af.rate == native_rate>>2) mh->down_sample = 2; | |
499 else mh->down_sample = 3; /* flexible (fixed) rate */ | |
500 switch(mh->down_sample) | |
501 { | |
502 case 0: | |
503 case 1: | |
504 case 2: | |
505 mh->down_sample_sblimit = SBLIMIT>>(mh->down_sample); | |
506 /* With downsampling I get less samples per frame */ | |
507 mh->outblock = sizeof(sample_t)*mh->af.channels*(spf(mh)>>mh->down_sample); | |
508 break; | |
509 case 3: | |
510 { | |
511 if(synth_ntom_set_step(mh) != 0) return -1; | |
512 if(frame_freq(mh) > mh->af.rate) | |
513 { | |
514 mh->down_sample_sblimit = SBLIMIT * mh->af.rate; | |
515 mh->down_sample_sblimit /= frame_freq(mh); | |
516 } | |
517 else mh->down_sample_sblimit = SBLIMIT; | |
518 mh->outblock = sizeof(sample_t) * mh->af.channels * | |
519 ( ( NTOM_MUL-1+spf(mh) | |
520 * (((size_t)NTOM_MUL*mh->af.rate)/frame_freq(mh)) | |
521 )/NTOM_MUL ); | |
522 } | |
523 break; | |
524 } | |
525 | |
526 if(!(mh->p.flags & MPG123_FORCE_MONO)) | |
527 { | |
528 if(mh->af.channels == 1) mh->single = SINGLE_MIX; | |
529 else mh->single = SINGLE_STEREO; | |
530 } | |
531 else mh->single = (mh->p.flags & MPG123_FORCE_MONO)-1; | |
532 if(set_synth_functions(mh) != 0) return -1;; | |
533 init_layer3_stuff(mh); | |
534 init_layer2_stuff(mh); | |
535 do_rva(mh); | |
536 debug3("done updating decoder structure with native rate %li and af.rate %li and down_sample %i", frame_freq(mh), mh->af.rate, mh->down_sample); | |
537 | |
538 return 0; | |
539 } | |
540 | |
541 size_t attribute_align_arg mpg123_safe_buffer() | |
542 { | |
543 return sizeof(sample_t)*2*1152*NTOM_MAX; | |
544 } | |
545 | |
546 size_t attribute_align_arg mpg123_outblock(mpg123_handle *mh) | |
547 { | |
548 if(mh != NULL) return mh->outblock; | |
549 else return mpg123_safe_buffer(); | |
550 } | |
551 | |
552 static int get_next_frame(mpg123_handle *mh) | |
553 { | |
554 int change = mh->decoder_change; | |
555 do | |
556 { | |
557 int b; | |
558 /* Decode & discard some frame(s) before beginning. */ | |
559 if(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe) | |
560 { | |
561 debug1("ignoring frame %li", (long)mh->num); | |
562 /* Decoder structure must be current! decode_update has been called before... */ | |
563 (mh->do_layer)(mh); mh->buffer.fill = 0; | |
564 /* The ignored decoding may have failed. Make sure ntom stays consistent. */ | |
565 if(mh->down_sample == 3) ntom_set_ntom(mh, mh->num+1); | |
566 | |
567 mh->to_ignore = mh->to_decode = FALSE; | |
568 } | |
569 /* Read new frame data; possibly breaking out here for MPG123_NEED_MORE. */ | |
570 debug("read frame"); | |
571 mh->to_decode = FALSE; | |
572 b = read_frame(mh); /* That sets to_decode only if a full frame was read. */ | |
573 debug4("read of frame %li returned %i (to_decode=%i) at sample %li", (long)mh->num, b, mh->to_decode, (long)mpg123_tell(mh)); | |
574 if(b == MPG123_NEED_MORE) return MPG123_NEED_MORE; /* need another call with data */ | |
575 else if(b <= 0) | |
576 { | |
577 /* More sophisticated error control? */ | |
578 if(b==0 || mh->rdat.filepos == mh->rdat.filelen) | |
579 { /* We simply reached the end. */ | |
580 mh->track_frames = mh->num + 1; | |
581 return MPG123_DONE; | |
582 } | |
583 else return MPG123_ERR; /* Some real error. */ | |
584 } | |
585 /* Now, there should be new data to decode ... and also possibly new stream properties */ | |
586 if(mh->header_change > 1) | |
587 { | |
588 debug("big header change"); | |
589 change = 1; | |
590 } | |
591 } while(mh->num < mh->firstframe); | |
592 /* When we start actually using the CRC, this could move into the loop... */ | |
593 /* A question of semantics ... should I fold start_frame and frame_number into firstframe/lastframe? */ | |
594 if(mh->lastframe >= 0 && mh->num > mh->lastframe) | |
595 { | |
596 mh->to_decode = mh->to_ignore = FALSE; | |
597 return MPG123_DONE; | |
598 } | |
599 if(change) | |
600 { | |
601 int b = frame_output_format(mh); /* Select the new output format based on given constraints. */ | |
602 if(b < 0) return MPG123_ERR; /* not nice to fail here... perhaps once should add possibility to repeat this step */ | |
603 if(decode_update(mh) < 0) return MPG123_ERR; /* dito... */ | |
604 mh->decoder_change = 0; | |
605 if(b == 1) mh->new_format = 1; /* Store for later... */ | |
606 #ifdef GAPLESS | |
607 if(mh->fresh) | |
608 { | |
609 b=0; | |
610 /* Prepare offsets for gapless decoding. */ | |
611 debug1("preparing gapless stuff with native rate %li", frame_freq(mh)); | |
612 frame_gapless_realinit(mh); | |
613 frame_set_frameseek(mh, mh->num); | |
614 mh->fresh = 0; | |
615 /* Could this possibly happen? With a real big gapless offset... */ | |
616 if(mh->num < mh->firstframe) b = get_next_frame(mh); | |
617 if(b < 0) return b; /* Could be error, need for more, new format... */ | |
618 } | |
619 #endif | |
620 } | |
621 return MPG123_OK; | |
622 } | |
623 | |
624 /* | |
625 Not part of the api. This just decodes the frame and fills missing bits with zeroes. | |
626 There can be frames that are broken and thus make do_layer() fail. | |
627 */ | |
628 void decode_the_frame(mpg123_handle *fr) | |
629 { | |
630 size_t needed_bytes = samples_to_bytes(fr, frame_outs(fr, fr->num+1)-frame_outs(fr, fr->num)); | |
631 | |
632 fr->clip += (fr->do_layer)(fr); | |
633 /* There could be less data than promised. */ | |
634 if(fr->buffer.fill < needed_bytes) | |
635 { | |
636 if(NOQUIET) fprintf(stderr, "Note: broken frame %li, filling up with zeroes\n", (long)fr->num); | |
637 | |
638 /* One could do a loop with individual samples instead... but zero is zero. */ | |
639 memset(fr->buffer.data + fr->buffer.fill, 0, needed_bytes - fr->buffer.fill); | |
640 fr->buffer.fill = needed_bytes; | |
641 /* ntom_val will be wrong when the decoding wasn't carried out completely */ | |
642 if(fr->down_sample == 3) ntom_set_ntom(fr, fr->num+1); | |
643 } | |
644 } | |
645 | |
646 /* | |
647 Put _one_ decoded frame into the frame structure's buffer, accessible at the location stored in <audio>, with <bytes> bytes available. | |
648 The buffer contents will be lost on next call to mpg123_decode_frame. | |
649 MPG123_OK -- successfully decoded the frame, you get your output data | |
650 MPg123_DONE -- This is it. End. | |
651 MPG123_ERR -- some error occured... | |
652 MPG123_NEW_FORMAT -- new frame was read, it results in changed output format -> will be decoded on next call | |
653 MPG123_NEED_MORE -- that should not happen as this function is intended for in-library stream reader but if you force it... | |
654 MPG123_NO_SPACE -- not enough space in buffer for safe decoding, also should not happen | |
655 | |
656 num will be updated to the last decoded frame number (may possibly _not_ increase, p.ex. when format changed). | |
657 */ | |
658 int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes) | |
659 { | |
660 ALIGNCHECK(mh); | |
661 if(bytes != NULL) *bytes = 0; | |
662 if(mh == NULL) return MPG123_ERR; | |
663 if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE; | |
664 mh->buffer.fill = 0; /* always start fresh */ | |
665 while(TRUE) | |
666 { | |
667 /* decode if possible */ | |
668 if(mh->to_decode) | |
669 { | |
670 if(mh->new_format) | |
671 { | |
672 mh->new_format = 0; | |
673 return MPG123_NEW_FORMAT; | |
674 } | |
675 if(num != NULL) *num = mh->num; | |
676 debug("decoding"); | |
677 | |
678 decode_the_frame(mh); | |
679 | |
680 mh->to_decode = mh->to_ignore = FALSE; | |
681 mh->buffer.p = mh->buffer.data; | |
682 #ifdef GAPLESS | |
683 /* This checks for individual samples to skip, for gapless mode or sample-accurate seek. */ | |
684 frame_buffercheck(mh); | |
685 #endif | |
686 if(audio != NULL) *audio = mh->buffer.p; | |
687 if(bytes != NULL) *bytes = mh->buffer.fill; | |
688 | |
689 return MPG123_OK; | |
690 } | |
691 else | |
692 { | |
693 int b = get_next_frame(mh); | |
694 if(b < 0) return b; | |
695 debug1("got next frame, %i", mh->to_decode); | |
696 } | |
697 } | |
698 } | |
699 | |
700 int attribute_align_arg mpg123_read(mpg123_handle *mh, unsigned char *out, size_t size, size_t *done) | |
701 { | |
702 return mpg123_decode(mh, NULL, 0, out, size, done); | |
703 } | |
704 | |
705 int attribute_align_arg mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size) | |
706 { | |
707 if(mh == NULL) return MPG123_ERR; | |
708 if(size > 0) | |
709 { | |
710 if(in != NULL) | |
711 { | |
712 if(feed_more(mh, in, size) != 0) return MPG123_ERR; | |
713 else return MPG123_OK; | |
714 } | |
715 else | |
716 { | |
717 mh->err = MPG123_NULL_BUFFER; | |
718 return MPG123_ERR; | |
719 } | |
720 } | |
721 return MPG123_OK; | |
722 } | |
723 | |
724 /* | |
725 The old picture: | |
726 while(1) { | |
727 len = read(0,buf,16384); | |
728 if(len <= 0) | |
729 break; | |
730 ret = decodeMP3(&mp,buf,len,out,8192,&size); | |
731 while(ret == MP3_OK) { | |
732 write(1,out,size); | |
733 ret = decodeMP3(&mp,NULL,0,out,8192,&size); | |
734 } | |
735 } | |
736 */ | |
737 | |
738 int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done) | |
739 { | |
740 int ret = MPG123_OK; | |
741 size_t mdone = 0; | |
742 ALIGNCHECK(mh); | |
743 if(done != NULL) *done = 0; | |
744 if(mh == NULL) return MPG123_ERR; | |
745 if(inmemsize > 0 && mpg123_feed(mh, inmemory, inmemsize) != MPG123_OK) | |
746 { | |
747 ret = MPG123_ERR; | |
748 goto decodeend; | |
749 } | |
750 if(outmemory == NULL) outmemsize = 0; /* Not just give error, give chance to get a status message. */ | |
751 | |
752 while(ret == MPG123_OK) | |
753 { | |
754 debug4("decode loop, fill %i (%li vs. %li); to_decode: %i", (int)mh->buffer.fill, (long)mh->num, (long)mh->firstframe, mh->to_decode); | |
755 /* Decode a frame that has been read before. | |
756 This only happens when buffer is empty! */ | |
757 if(mh->to_decode) | |
758 { | |
759 if(mh->new_format) | |
760 { | |
761 mh->new_format = 0; | |
762 return MPG123_NEW_FORMAT; | |
763 } | |
764 if(mh->buffer.size - mh->buffer.fill < mh->outblock) | |
765 { | |
766 ret = MPG123_NO_SPACE; | |
767 goto decodeend; | |
768 } | |
769 decode_the_frame(mh); | |
770 mh->to_decode = mh->to_ignore = FALSE; | |
771 mh->buffer.p = mh->buffer.data; | |
772 debug2("decoded frame %li, got %li samples in buffer", (long)mh->num, (long)(mh->buffer.fill / (samples_to_bytes(mh, 1)))); | |
773 #ifdef GAPLESS | |
774 frame_buffercheck(mh); /* Seek & gapless. */ | |
775 #endif | |
776 } | |
777 if(mh->buffer.fill) /* Copy (part of) the decoded data to the caller's buffer. */ | |
778 { | |
779 /* get what is needed - or just what is there */ | |
780 int a = mh->buffer.fill > (outmemsize - mdone) ? outmemsize - mdone : mh->buffer.fill; | |
781 debug4("buffer fill: %i; copying %i (%i - %li)", (int)mh->buffer.fill, a, (int)outmemsize, (long)mdone); | |
782 memcpy(outmemory, mh->buffer.p, a); | |
783 /* less data in frame buffer, less needed, output pointer increase, more data given... */ | |
784 mh->buffer.fill -= a; | |
785 outmemory += a; | |
786 mdone += a; | |
787 mh->buffer.p += a; | |
788 if(!(outmemsize > mdone)) goto decodeend; | |
789 } | |
790 else /* If we didn't have data, get a new frame. */ | |
791 { | |
792 int b = get_next_frame(mh); | |
793 if(b < 0){ ret = b; goto decodeend; } | |
794 } | |
795 } | |
796 decodeend: | |
797 if(done != NULL) *done = mdone; | |
798 return ret; | |
799 } | |
800 | |
801 long attribute_align_arg mpg123_clip(mpg123_handle *mh) | |
802 { | |
803 long ret = 0; | |
804 ALIGNCHECK(mh); | |
805 if(mh != NULL) | |
806 { | |
807 ret = mh->clip; | |
808 mh->clip = 0; | |
809 } | |
810 return ret; | |
811 } | |
812 | |
813 #define track_need_init(mh) (!(mh)->to_decode && (mh)->fresh) | |
814 | |
815 static int init_track(mpg123_handle *mh) | |
816 { | |
817 if(track_need_init(mh)) | |
818 { | |
819 /* Fresh track, need first frame for basic info. */ | |
820 int b = get_next_frame(mh); | |
821 if(b < 0) return b; | |
822 } | |
823 return 0; | |
824 } | |
825 | |
826 int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding) | |
827 { | |
828 ALIGNCHECK(mh); | |
829 if(mh == NULL) return MPG123_ERR; | |
830 if(init_track(mh) == MPG123_ERR) return MPG123_ERR; | |
831 | |
832 if(rate != NULL) *rate = mh->af.rate; | |
833 if(channels != NULL) *channels = mh->af.channels; | |
834 if(encoding != NULL) *encoding = mh->af.encoding; | |
835 mh->new_format = 0; | |
836 return MPG123_OK; | |
837 } | |
838 | |
839 off_t attribute_align_arg mpg123_timeframe(mpg123_handle *mh, double seconds) | |
840 { | |
841 off_t b; | |
842 ALIGNCHECK(mh); | |
843 if(mh == NULL) return MPG123_ERR; | |
844 b = init_track(mh); | |
845 if(b<0) return b; | |
846 return (off_t)(seconds/mpg123_tpf(mh)); | |
847 } | |
848 | |
849 /* | |
850 Now, where are we? We need to know the last decoded frame... and what's left of it in buffer. | |
851 The current frame number can mean the last decoded frame or the to-be-decoded frame. | |
852 If mh->to_decode, then mh->num frames have been decoded, the frame mh->num now coming next. | |
853 If not, we have the possibility of mh->num+1 frames being decoded or nothing at all. | |
854 Then, there is firstframe...when we didn't reach it yet, then the next data will come from there. | |
855 mh->num starts with -1 | |
856 */ | |
857 off_t attribute_align_arg mpg123_tell(mpg123_handle *mh) | |
858 { | |
859 ALIGNCHECK(mh); | |
860 if(mh == NULL) return MPG123_ERR; | |
861 if(track_need_init(mh)) return 0; | |
862 /* Now we have all the info at hand. */ | |
863 debug5("tell: %li/%i first %li buffer %lu; frame_outs=%li", (long)mh->num, mh->to_decode, (long)mh->firstframe, (unsigned long)mh->buffer.fill, (long)frame_outs(mh, mh->num)); | |
864 | |
865 { /* Funny block to keep C89 happy. */ | |
866 off_t pos = 0; | |
867 if((mh->num < mh->firstframe) || (mh->num == mh->firstframe && mh->to_decode)) | |
868 { /* We are at the beginning, expect output from firstframe on. */ | |
869 pos = frame_outs(mh, mh->firstframe); | |
870 #ifdef GAPLESS | |
871 pos += mh->firstoff; | |
872 #endif | |
873 } | |
874 else if(mh->to_decode) | |
875 { /* We start fresh with this frame. Buffer should be empty, but we make sure to count it in. */ | |
876 pos = frame_outs(mh, mh->num) - bytes_to_samples(mh, mh->buffer.fill); | |
877 } | |
878 else | |
879 { /* We serve what we have in buffer and then the beginning of next frame... */ | |
880 pos = frame_outs(mh, mh->num+1) - bytes_to_samples(mh, mh->buffer.fill); | |
881 } | |
882 /* Substract padding and delay from the beginning. */ | |
883 pos = SAMPLE_ADJUST(pos); | |
884 /* Negative sample offsets are not right, less than nothing is still nothing. */ | |
885 return pos>0 ? pos : 0; | |
886 } | |
887 } | |
888 | |
889 off_t attribute_align_arg mpg123_tellframe(mpg123_handle *mh) | |
890 { | |
891 ALIGNCHECK(mh); | |
892 if(mh == NULL) return MPG123_ERR; | |
893 if(mh->num < mh->firstframe) return mh->firstframe; | |
894 if(mh->to_decode) return mh->num; | |
895 /* Consider firstoff? */ | |
896 return mh->buffer.fill ? mh->num : mh->num + 1; | |
897 } | |
898 | |
899 off_t attribute_align_arg mpg123_tell_stream(mpg123_handle *mh) | |
900 { | |
901 ALIGNCHECK(mh); | |
902 if(mh == NULL) return MPG123_ERR; | |
903 /* mh->rd is at least a bad_reader, so no worry. */ | |
904 return mh->rd->tell(mh); | |
905 } | |
906 | |
907 static int do_the_seek(mpg123_handle *mh) | |
908 { | |
909 int b; | |
910 off_t fnum = SEEKFRAME(mh); | |
911 mh->buffer.fill = 0; | |
912 | |
913 if(mh->num < mh->firstframe) mh->to_decode = FALSE; | |
914 | |
915 if(mh->num == fnum && mh->to_decode) return MPG123_OK; | |
916 if(mh->num == fnum-1) | |
917 { | |
918 mh->to_decode = FALSE; | |
919 return MPG123_OK; | |
920 } | |
921 if(mh->down_sample == 3) | |
922 { | |
923 ntom_set_ntom(mh, fnum); | |
924 debug3("fixed ntom for frame %"OFF_P" to %i, num=%"OFF_P, fnum, mh->ntom_val[0], mh->num); | |
925 } | |
926 b = mh->rd->seek_frame(mh, fnum); | |
927 debug1("seek_frame returned: %i", b); | |
928 if(b<0) return b; | |
929 /* Only mh->to_ignore is TRUE. */ | |
930 if(mh->num < mh->firstframe) mh->to_decode = FALSE; | |
931 return 0; | |
932 } | |
933 | |
934 off_t attribute_align_arg mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence) | |
935 { | |
936 int b; | |
937 off_t pos; | |
938 ALIGNCHECK(mh); | |
939 pos = mpg123_tell(mh); /* adjusted samples */ | |
940 /* pos < 0 also can mean that simply a former seek failed at the lower levels. | |
941 In that case, we only allow absolute seeks. */ | |
942 if(pos < 0 && whence != SEEK_SET) | |
943 { /* Unless we got the obvious error of NULL handle, this is a special seek failure. */ | |
944 if(mh != NULL) mh->err = MPG123_NO_RELSEEK; | |
945 return MPG123_ERR; | |
946 } | |
947 if((b=init_track(mh)) < 0) return b; | |
948 | |
949 switch(whence) | |
950 { | |
951 case SEEK_CUR: pos += sampleoff; break; | |
952 case SEEK_SET: pos = sampleoff; break; | |
953 case SEEK_END: | |
954 #ifdef GAPLESS | |
955 if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff; | |
956 #else | |
957 if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff; | |
958 #endif | |
959 else | |
960 { | |
961 mh->err = MPG123_NO_SEEK_FROM_END; | |
962 return MPG123_ERR; | |
963 } | |
964 break; | |
965 default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR; | |
966 } | |
967 if(pos < 0) pos = 0; | |
968 /* pos now holds the wanted sample offset in adjusted samples */ | |
969 frame_set_seek(mh, SAMPLE_UNADJUST(pos)); | |
970 pos = do_the_seek(mh); | |
971 if(pos < 0) return pos; | |
972 | |
973 return mpg123_tell(mh); | |
974 } | |
975 | |
976 /* | |
977 A bit more tricky... libmpg123 does not do the seeking itself. | |
978 All it can do is to ignore frames until the wanted one is there. | |
979 The caller doesn't know where a specific frame starts and mpg123 also only knows the general region after it scanned the file. | |
980 Well, it is tricky... | |
981 */ | |
982 off_t attribute_align_arg mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset) | |
983 { | |
984 int b; | |
985 off_t pos; | |
986 ALIGNCHECK(mh); | |
987 pos = mpg123_tell(mh); /* adjusted samples */ | |
988 debug3("seek from %li to %li (whence=%i)", (long)pos, (long)sampleoff, whence); | |
989 /* The special seek error handling does not apply here... there is no lowlevel I/O. */ | |
990 if(pos < 0) return pos; /* mh == NULL is covered in mpg123_tell() */ | |
991 if(input_offset == NULL) | |
992 { | |
993 mh->err = MPG123_NULL_POINTER; | |
994 return MPG123_ERR; | |
995 } | |
996 | |
997 if((b=init_track(mh)) < 0) return b; /* May need more to do anything at all. */ | |
998 | |
999 switch(whence) | |
1000 { | |
1001 case SEEK_CUR: pos += sampleoff; break; | |
1002 case SEEK_SET: pos = sampleoff; break; | |
1003 case SEEK_END: | |
1004 #ifdef GAPLESS | |
1005 if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff; | |
1006 #else | |
1007 if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff; | |
1008 #endif | |
1009 else | |
1010 { | |
1011 mh->err = MPG123_NO_SEEK_FROM_END; | |
1012 return MPG123_ERR; | |
1013 } | |
1014 break; | |
1015 default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR; | |
1016 } | |
1017 if(pos < 0) pos = 0; | |
1018 frame_set_seek(mh, SAMPLE_UNADJUST(pos)); | |
1019 pos = SEEKFRAME(mh); | |
1020 mh->buffer.fill = 0; | |
1021 | |
1022 /* Shortcuts without modifying input stream. */ | |
1023 *input_offset = mh->rdat.buffer.fileoff + mh->rdat.buffer.size; | |
1024 if(mh->num < mh->firstframe) mh->to_decode = FALSE; | |
1025 if(mh->num == pos && mh->to_decode) goto feedseekend; | |
1026 if(mh->num == pos-1) goto feedseekend; | |
1027 /* Whole way. */ | |
1028 *input_offset = feed_set_pos(mh, frame_index_find(mh, SEEKFRAME(mh), &pos)); | |
1029 mh->num = pos-1; /* The next read frame will have num = pos. */ | |
1030 if(*input_offset < 0) return MPG123_ERR; | |
1031 | |
1032 feedseekend: | |
1033 return mpg123_tell(mh); | |
1034 } | |
1035 | |
1036 off_t attribute_align_arg mpg123_seek_frame(mpg123_handle *mh, off_t offset, int whence) | |
1037 { | |
1038 int b; | |
1039 off_t pos = 0; | |
1040 ALIGNCHECK(mh); | |
1041 if(mh == NULL) return MPG123_ERR; | |
1042 if((b=init_track(mh)) < 0) return b; | |
1043 | |
1044 /* Could play games here with to_decode... */ | |
1045 pos = mh->num; | |
1046 switch(whence) | |
1047 { | |
1048 case SEEK_CUR: pos += offset; break; | |
1049 case SEEK_SET: pos = offset; break; | |
1050 case SEEK_END: | |
1051 if(mh->track_frames > 0) pos = mh->track_frames - offset; | |
1052 else | |
1053 { | |
1054 mh->err = MPG123_NO_SEEK_FROM_END; | |
1055 return MPG123_ERR; | |
1056 } | |
1057 break; | |
1058 default: | |
1059 mh->err = MPG123_BAD_WHENCE; | |
1060 return MPG123_ERR; | |
1061 } | |
1062 if(pos < 0) pos = 0; | |
1063 /* Hm, do we need to seek right past the end? */ | |
1064 else if(mh->track_frames > 0 && pos >= mh->track_frames) pos = mh->track_frames; | |
1065 | |
1066 frame_set_frameseek(mh, pos); | |
1067 pos = do_the_seek(mh); | |
1068 if(pos < 0) return pos; | |
1069 | |
1070 return mpg123_tellframe(mh); | |
1071 } | |
1072 | |
1073 int attribute_align_arg mpg123_set_filesize(mpg123_handle *mh, off_t size) | |
1074 { | |
1075 ALIGNCHECK(mh); | |
1076 if(mh == NULL) return MPG123_ERR; | |
1077 | |
1078 mh->rdat.filelen = size; | |
1079 return MPG123_OK; | |
1080 } | |
1081 | |
1082 off_t attribute_align_arg mpg123_length(mpg123_handle *mh) | |
1083 { | |
1084 int b; | |
1085 off_t length; | |
1086 ALIGNCHECK(mh); | |
1087 if(mh == NULL) return MPG123_ERR; | |
1088 b = init_track(mh); | |
1089 if(b<0) return b; | |
1090 if(mh->track_samples > -1) length = mh->track_samples; | |
1091 else if(mh->track_frames > 0) length = mh->track_frames*spf(mh); | |
1092 else if(mh->rdat.filelen >= 0) /* Let the case of 0 length just fall through. */ | |
1093 { | |
1094 /* A bad estimate. Ignoring tags 'n stuff. */ | |
1095 double bpf = mh->mean_framesize ? mh->mean_framesize : compute_bpf(mh); | |
1096 length = (off_t)((double)(mh->rdat.filelen)/bpf*spf(mh)); | |
1097 } | |
1098 else return MPG123_ERR; /* No length info there! */ | |
1099 | |
1100 length = frame_ins2outs(mh, length); | |
1101 #ifdef GAPLESS | |
1102 if(mh->end_os > 0 && length > mh->end_os) length = mh->end_os; | |
1103 length -= mh->begin_os; | |
1104 #endif | |
1105 return length; | |
1106 } | |
1107 | |
1108 int attribute_align_arg mpg123_scan(mpg123_handle *mh) | |
1109 { | |
1110 int b; | |
1111 off_t backframe; | |
1112 int to_decode, to_ignore; | |
1113 ALIGNCHECK(mh); | |
1114 if(mh == NULL) return MPG123_ERR; | |
1115 if(!(mh->rdat.flags & READER_SEEKABLE)){ mh->err = MPG123_NO_SEEK; return MPG123_ERR; } | |
1116 /* Scan through the _whole_ file, since the current position is no count but computed assuming constant samples per frame. */ | |
1117 /* Also, we can just keep the current buffer and seek settings. Just operate on input frames here. */ | |
1118 b = init_track(mh); /* mh->num >= 0 !! */ | |
1119 if(b<0) | |
1120 { | |
1121 if(b == MPG123_DONE) return MPG123_OK; | |
1122 else return MPG123_ERR; /* Must be error here, NEED_MORE is not for seekable streams. */ | |
1123 } | |
1124 backframe = mh->num; | |
1125 to_decode = mh->to_decode; | |
1126 to_ignore = mh->to_ignore; | |
1127 b = mh->rd->seek_frame(mh, 0); | |
1128 if(b<0 || mh->num != 0) return MPG123_ERR; | |
1129 /* One frame must be there now. */ | |
1130 mh->track_frames = 1; | |
1131 mh->track_samples = spf(mh); /* Internal samples. */ | |
1132 while(read_frame(mh) == 1) | |
1133 { | |
1134 ++mh->track_frames; | |
1135 mh->track_samples += spf(mh); | |
1136 } | |
1137 b = mh->rd->seek_frame(mh, backframe); | |
1138 if(b<0 || mh->num != backframe) return MPG123_ERR; | |
1139 mh->to_decode = to_decode; | |
1140 mh->to_ignore = to_ignore; | |
1141 return MPG123_OK; | |
1142 } | |
1143 | |
1144 int attribute_align_arg mpg123_meta_check(mpg123_handle *mh) | |
1145 { | |
1146 if(mh != NULL) return mh->metaflags; | |
1147 else return 0; | |
1148 } | |
1149 | |
1150 int attribute_align_arg mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2) | |
1151 { | |
1152 ALIGNCHECK(mh); | |
1153 if(v1 != NULL) *v1 = NULL; | |
1154 if(v2 != NULL) *v2 = NULL; | |
1155 if(mh == NULL) return MPG123_ERR; | |
1156 | |
1157 if(mh->metaflags & MPG123_ID3) | |
1158 { | |
1159 id3_link(mh); | |
1160 if(v1 != NULL && mh->rdat.flags & READER_ID3TAG) *v1 = (mpg123_id3v1*) mh->id3buf; | |
1161 if(v2 != NULL) *v2 = &mh->id3v2; | |
1162 mh->metaflags |= MPG123_ID3; | |
1163 mh->metaflags &= ~MPG123_NEW_ID3; | |
1164 } | |
1165 return MPG123_OK; | |
1166 } | |
1167 | |
1168 int attribute_align_arg mpg123_icy(mpg123_handle *mh, char **icy_meta) | |
1169 { | |
1170 ALIGNCHECK(mh); | |
1171 if(mh == NULL) return MPG123_ERR; | |
1172 if(icy_meta == NULL) | |
1173 { | |
1174 mh->err = MPG123_NULL_POINTER; | |
1175 return MPG123_ERR; | |
1176 } | |
1177 *icy_meta = NULL; | |
1178 | |
1179 if(mh->metaflags & MPG123_ICY) | |
1180 { | |
1181 *icy_meta = mh->icy.data; | |
1182 mh->metaflags |= MPG123_ICY; | |
1183 mh->metaflags &= ~MPG123_NEW_ICY; | |
1184 } | |
1185 return MPG123_OK; | |
1186 } | |
1187 | |
1188 char* attribute_align_arg mpg123_icy2utf8(const char* icy_text) | |
1189 { | |
1190 return icy2utf8(icy_text); | |
1191 } | |
1192 | |
1193 | |
1194 int attribute_align_arg mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill) | |
1195 { | |
1196 ALIGNCHECK(mh); | |
1197 if(mh == NULL) return MPG123_ERR; | |
1198 if(offsets == NULL || step == NULL || fill == NULL) | |
1199 { | |
1200 mh->err = MPG123_BAD_INDEX_PAR; | |
1201 return MPG123_ERR; | |
1202 } | |
1203 #ifdef FRAME_INDEX | |
1204 *offsets = mh->index.data; | |
1205 *step = mh->index.step; | |
1206 *fill = mh->index.fill; | |
1207 #else | |
1208 *offsets = NULL; | |
1209 *step = 0; | |
1210 *fill = 0; | |
1211 #endif | |
1212 return MPG123_OK; | |
1213 } | |
1214 | |
1215 int attribute_align_arg mpg123_close(mpg123_handle *mh) | |
1216 { | |
1217 ALIGNCHECK(mh); | |
1218 if(mh == NULL) return MPG123_ERR; | |
1219 if(mh->rd != NULL && mh->rd->close != NULL) mh->rd->close(mh); | |
1220 mh->rd = NULL; | |
1221 if(mh->new_format) | |
1222 { | |
1223 debug("Hey, we are closing a track before the new format has been queried..."); | |
1224 invalidate_format(&mh->af); | |
1225 mh->new_format = 0; | |
1226 } | |
1227 return MPG123_OK; | |
1228 } | |
1229 | |
1230 void attribute_align_arg mpg123_delete(mpg123_handle *mh) | |
1231 { | |
1232 if(mh != NULL) | |
1233 { | |
1234 mpg123_close(mh); | |
1235 frame_exit(mh); /* free buffers in frame */ | |
1236 free(mh); /* free struct; cast? */ | |
1237 } | |
1238 } | |
1239 | |
1240 static const char *mpg123_error[] = | |
1241 { | |
1242 "No error... (code 0)", | |
1243 "Unable to set up output format! (code 1)", | |
1244 "Invalid channel number specified. (code 2)", | |
1245 "Invalid sample rate specified. (code 3)", | |
1246 "Unable to allocate memory for 16 to 8 converter table! (code 4)", | |
1247 "Bad parameter id! (code 5)", | |
1248 "Bad buffer given -- invalid pointer or too small size. (code 6)", | |
1249 "Out of memory -- some malloc() failed. (code 7)", | |
1250 "You didn't initialize the library! (code 8)", | |
1251 "Invalid decoder choice. (code 9)", | |
1252 "Invalid mpg123 handle. (code 10)", | |
1253 "Unable to initialize frame buffers (out of memory?)! (code 11)", | |
1254 "Invalid RVA mode. (code 12)", | |
1255 "This build doesn't support gapless decoding. (code 13)", | |
1256 "Not enough buffer space. (code 14)", | |
1257 "Incompatible numeric data types. (code 15)", | |
1258 "Bad equalizer band. (code 16)", | |
1259 "Null pointer given where valid storage address needed. (code 17)", | |
1260 "Error reading the stream. (code 18)", | |
1261 "Cannot seek from end (end is not known). (code 19)", | |
1262 "Invalid 'whence' for seek function. (code 20)", | |
1263 "Build does not support stream timeouts. (code 21)", | |
1264 "File access error. (code 22)", | |
1265 "Seek not supported by stream. (code 23)", | |
1266 "No stream opened. (code 24)", | |
1267 "Bad parameter handle. (code 25)", | |
1268 "Invalid parameter addresses for index retrieval. (code 26)", | |
1269 "Lost track in the bytestream and did not attempt resync. (code 27)", | |
1270 "Failed to find valid MPEG data within limit on resync. (code 28)", | |
1271 "No 8bit encoding possible. (code 29)", | |
1272 "Stack alignment is not good. (code 30)", | |
1273 "You gave me a NULL buffer? (code 31)", | |
1274 "File position is screwed up, please do an absolute seek (code 32)", | |
1275 "Inappropriate NULL-pointer provided.", | |
1276 "Bad key value given.", | |
1277 "There is no frame index (disabled in this build).", | |
1278 "Frame index operation failed." | |
1279 }; | |
1280 | |
1281 const char* attribute_align_arg mpg123_plain_strerror(int errcode) | |
1282 { | |
1283 if(errcode >= 0 && errcode < sizeof(mpg123_error)/sizeof(char*)) | |
1284 return mpg123_error[errcode]; | |
1285 else switch(errcode) | |
1286 { | |
1287 case MPG123_ERR: | |
1288 return "A generic mpg123 error."; | |
1289 case MPG123_DONE: | |
1290 return "Message: I am done with this track."; | |
1291 case MPG123_NEED_MORE: | |
1292 return "Message: Feed me more input data!"; | |
1293 case MPG123_NEW_FORMAT: | |
1294 return "Message: Prepare for a changed audio format!"; | |
1295 default: | |
1296 return "I have no idea - an unknown error code!"; | |
1297 } | |
1298 } | |
1299 | |
1300 int attribute_align_arg mpg123_errcode(mpg123_handle *mh) | |
1301 { | |
1302 if(mh != NULL) return mh->err; | |
1303 return MPG123_BAD_HANDLE; | |
1304 } | |
1305 | |
1306 const char* attribute_align_arg mpg123_strerror(mpg123_handle *mh) | |
1307 { | |
1308 return mpg123_plain_strerror(mpg123_errcode(mh)); | |
1309 } |