Mercurial > SDL_sound_CoreAudio
comparison decoders/flac.c @ 422:5b06e23d934e
Removed backwards compatible API nastiness from FLAC decoder.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Mon, 30 Sep 2002 08:01:26 +0000 |
parents | 9d0b5ec9cc26 |
children | 30f96c853462 |
comparison
equal
deleted
inserted
replaced
421:a65440b3a057 | 422:5b06e23d934e |
---|---|
42 #include "SDL_sound.h" | 42 #include "SDL_sound.h" |
43 | 43 |
44 #define __SDL_SOUND_INTERNAL__ | 44 #define __SDL_SOUND_INTERNAL__ |
45 #include "SDL_sound_internal.h" | 45 #include "SDL_sound_internal.h" |
46 | 46 |
47 /* | |
48 * FLAC 1.0.1 added a seekable stream decoder. To be able to reuse as much as | |
49 * possible of the non-seekable FLAC decoder, we define a set of wrapper | |
50 * macros and typedefs to map onto the right set of functions and data types. | |
51 * | |
52 * An added benefit is that we get identifiers of manageable length. | |
53 */ | |
54 | |
55 #if SOUND_SUPPORTS_SEEKABLE_FLAC | |
56 | |
57 #define FLAC_IS_SEEKABLE 1 | |
58 | |
59 #include "FLAC/seekable_stream_decoder.h" | 47 #include "FLAC/seekable_stream_decoder.h" |
60 | 48 |
61 #define D_END_OF_STREAM FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM | 49 #define D_END_OF_STREAM FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM |
62 | 50 |
63 #define d_new() FLAC__seekable_stream_decoder_new() | 51 #define d_new() FLAC__seekable_stream_decoder_new() |
64 #define d_init(x) FLAC__seekable_stream_decoder_init(x) | 52 #define d_init(x) FLAC__seekable_stream_decoder_init(x) |
65 #define d_process_metadata(x) FLAC__seekable_stream_decoder_process_metadata(x) | 53 #define d_process_metadata(x) FLAC__seekable_stream_decoder_process_until_end_of_metadata(x) |
66 #define d_process_one_frame(x) FLAC__seekable_stream_decoder_process_one_frame(x) | 54 #define d_process_one_frame(x) FLAC__seekable_stream_decoder_process_single(x) |
67 #define d_get_state(x) FLAC__seekable_stream_decoder_get_state(x) | 55 #define d_get_state(x) FLAC__seekable_stream_decoder_get_state(x) |
68 #define d_finish(x) FLAC__seekable_stream_decoder_finish(x) | 56 #define d_finish(x) FLAC__seekable_stream_decoder_finish(x) |
69 #define d_delete(x) FLAC__seekable_stream_decoder_delete(x) | 57 #define d_delete(x) FLAC__seekable_stream_decoder_delete(x) |
70 #define d_set_read_callback(x, y) FLAC__seekable_stream_decoder_set_read_callback(x, y) | 58 #define d_set_read_callback(x, y) FLAC__seekable_stream_decoder_set_read_callback(x, y) |
71 #define d_set_write_callback(x, y) FLAC__seekable_stream_decoder_set_write_callback(x, y) | 59 #define d_set_write_callback(x, y) FLAC__seekable_stream_decoder_set_write_callback(x, y) |
74 #define d_set_client_data(x, y) FLAC__seekable_stream_decoder_set_client_data(x, y) | 62 #define d_set_client_data(x, y) FLAC__seekable_stream_decoder_set_client_data(x, y) |
75 | 63 |
76 typedef FLAC__SeekableStreamDecoder decoder_t; | 64 typedef FLAC__SeekableStreamDecoder decoder_t; |
77 typedef FLAC__SeekableStreamDecoderReadStatus d_read_status_t; | 65 typedef FLAC__SeekableStreamDecoderReadStatus d_read_status_t; |
78 | 66 |
79 /* Only in the seekable decoder */ | |
80 | |
81 #define D_SEEK_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK | 67 #define D_SEEK_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK |
82 #define D_SEEK_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR | 68 #define D_SEEK_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR |
83 #define D_TELL_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK | 69 #define D_TELL_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK |
84 #define D_TELL_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR | 70 #define D_TELL_STATUS_ERROR FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR |
85 #define D_LENGTH_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK | 71 #define D_LENGTH_STATUS_OK FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK |
93 | 79 |
94 typedef FLAC__SeekableStreamDecoderSeekStatus d_seek_status_t; | 80 typedef FLAC__SeekableStreamDecoderSeekStatus d_seek_status_t; |
95 typedef FLAC__SeekableStreamDecoderTellStatus d_tell_status_t; | 81 typedef FLAC__SeekableStreamDecoderTellStatus d_tell_status_t; |
96 typedef FLAC__SeekableStreamDecoderLengthStatus d_length_status_t; | 82 typedef FLAC__SeekableStreamDecoderLengthStatus d_length_status_t; |
97 | 83 |
98 #else | |
99 | |
100 #include "FLAC/stream_decoder.h" | |
101 | |
102 #define FLAC_IS_SEEKABLE 0 | |
103 | |
104 #define D_END_OF_STREAM FLAC__STREAM_DECODER_END_OF_STREAM | |
105 | |
106 #define d_new() FLAC__stream_decoder_new() | |
107 #define d_init(x) FLAC__stream_decoder_init(x) | |
108 #define d_process_metadata(x) FLAC__stream_decoder_process_metadata(x) | |
109 #define d_process_one_frame(x) FLAC__stream_decoder_process_one_frame(x) | |
110 #define d_get_state(x) FLAC__stream_decoder_get_state(x) | |
111 #define d_finish(x) FLAC__stream_decoder_finish(x) | |
112 #define d_delete(x) FLAC__stream_decoder_delete(x) | |
113 #define d_set_read_callback(x, y) FLAC__stream_decoder_set_read_callback(x, y) | |
114 #define d_set_write_callback(x, y) FLAC__stream_decoder_set_write_callback(x, y) | |
115 #define d_set_metadata_callback(x, y) FLAC__stream_decoder_set_metadata_callback(x, y) | |
116 #define d_set_error_callback(x, y) FLAC__stream_decoder_set_error_callback(x, y) | |
117 #define d_set_client_data(x, y) FLAC__stream_decoder_set_client_data(x, y) | |
118 | |
119 typedef FLAC__StreamDecoder decoder_t; | |
120 typedef FLAC__StreamDecoderReadStatus d_read_status_t; | |
121 | |
122 /* Only in the non-seekable decoder */ | |
123 | |
124 #define d_reset(x) FLAC__stream_decoder_reset(x) | |
125 | |
126 #endif | |
127 | |
128 /* | |
129 * FLAC 1.0.3 changed some symbol names, so we need to change what we | |
130 * reference depending on what version of their headers we compile against. | |
131 * We check for a #define that was included in FLAC 1.0.3 but doesn't exist | |
132 * in 1.0.2 and earlier. Fun. --ryan. | |
133 */ | |
134 #if (defined FLAC__STREAM_SYNC_LENGTH) | |
135 #define FLAC_VERSION_102_OR_LESS 0 | |
136 #else | |
137 #define FLAC_VERSION_102_OR_LESS 1 | |
138 #endif | |
139 | |
140 | |
141 /* These are the same for both decoders, so they're just cosmetics. */ | |
142 | |
143 #if FLAC_VERSION_102_OR_LESS | |
144 #define D_WRITE_CONTINUE FLAC__STREAM_DECODER_WRITE_CONTINUE | |
145 #define D_READ_END_OF_STREAM FLAC__STREAM_DECODER_READ_END_OF_STREAM | |
146 #define D_READ_ABORT FLAC__STREAM_DECODER_READ_ABORT | |
147 #define D_READ_CONTINUE FLAC__STREAM_DECODER_READ_CONTINUE | |
148 #else | |
149 #define D_WRITE_CONTINUE FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE | 84 #define D_WRITE_CONTINUE FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE |
150 #define D_READ_END_OF_STREAM FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM | 85 #define D_READ_END_OF_STREAM FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM |
151 #define D_READ_ABORT FLAC__STREAM_DECODER_READ_STATUS_ABORT | 86 #define D_READ_ABORT FLAC__STREAM_DECODER_READ_STATUS_ABORT |
152 #define D_READ_CONTINUE FLAC__STREAM_DECODER_READ_STATUS_CONTINUE | 87 #define D_READ_CONTINUE FLAC__STREAM_DECODER_READ_STATUS_CONTINUE |
153 #endif | |
154 | 88 |
155 #define d_error_status_string FLAC__StreamDecoderErrorStatusString | 89 #define d_error_status_string FLAC__StreamDecoderErrorStatusString |
156 | 90 |
157 typedef FLAC__StreamDecoderErrorStatus d_error_status_t; | 91 typedef FLAC__StreamDecoderErrorStatus d_error_status_t; |
158 #if FLAC_VERSION_102_OR_LESS | |
159 typedef FLAC__StreamMetaData d_metadata_t; | |
160 #else | |
161 typedef FLAC__StreamMetadata d_metadata_t; | 92 typedef FLAC__StreamMetadata d_metadata_t; |
162 #endif | |
163 typedef FLAC__StreamDecoderWriteStatus d_write_status_t; | 93 typedef FLAC__StreamDecoderWriteStatus d_write_status_t; |
164 | 94 |
165 | 95 |
166 static int FLAC_init(void); | 96 static int FLAC_init(void); |
167 static void FLAC_quit(void); | 97 static void FLAC_quit(void); |
197 decoder_t *decoder; | 127 decoder_t *decoder; |
198 SDL_RWops *rw; | 128 SDL_RWops *rw; |
199 Sound_Sample *sample; | 129 Sound_Sample *sample; |
200 Uint32 frame_size; | 130 Uint32 frame_size; |
201 Uint8 is_flac; | 131 Uint8 is_flac; |
202 | |
203 #if !SOUND_SUPPORTS_SEEKABLE_FLAC | |
204 Uint32 data_offset; | |
205 #else | |
206 Uint32 stream_length; | 132 Uint32 stream_length; |
207 #endif | |
208 } flac_t; | 133 } flac_t; |
209 | 134 |
210 | 135 |
211 static void free_flac(flac_t *f) | 136 static void free_flac(flac_t *f) |
212 { | 137 { |
249 } /* read_callback */ | 174 } /* read_callback */ |
250 | 175 |
251 | 176 |
252 static d_write_status_t write_callback( | 177 static d_write_status_t write_callback( |
253 const decoder_t *decoder, const FLAC__Frame *frame, | 178 const decoder_t *decoder, const FLAC__Frame *frame, |
254 #if FLAC_VERSION_102_OR_LESS | |
255 const FLAC__int32 * buffer[], | |
256 #else | |
257 const FLAC__int32 * const buffer[], | 179 const FLAC__int32 * const buffer[], |
258 #endif | |
259 void *client_data) | 180 void *client_data) |
260 { | 181 { |
261 flac_t *f = (flac_t *) client_data; | 182 flac_t *f = (flac_t *) client_data; |
262 Uint32 i, j; | 183 Uint32 i, j; |
263 Uint32 sample; | 184 Uint32 sample; |
344 __Sound_SetError(d_error_status_string[status]); | 265 __Sound_SetError(d_error_status_string[status]); |
345 f->sample->flags |= SOUND_SAMPLEFLAG_ERROR; | 266 f->sample->flags |= SOUND_SAMPLEFLAG_ERROR; |
346 } /* error_callback */ | 267 } /* error_callback */ |
347 | 268 |
348 | 269 |
349 #if SOUND_SUPPORTS_SEEKABLE_FLAC | |
350 | |
351 static d_seek_status_t seek_callback( | 270 static d_seek_status_t seek_callback( |
352 const decoder_t *decoder, | 271 const decoder_t *decoder, |
353 FLAC__uint64 absolute_byte_offset, | 272 FLAC__uint64 absolute_byte_offset, |
354 void *client_data) | 273 void *client_data) |
355 { | 274 { |
417 } /* if */ | 336 } /* if */ |
418 | 337 |
419 return(false); | 338 return(false); |
420 } /* eof_callback */ | 339 } /* eof_callback */ |
421 | 340 |
422 #endif | |
423 | 341 |
424 static int FLAC_init(void) | 342 static int FLAC_init(void) |
425 { | 343 { |
426 SNDDBG(("FLAC: we are using libFLAC version %s 1.0.2.\n", | |
427 FLAC_VERSION_102_OR_LESS ? "<=" : ">")); | |
428 SNDDBG(("FLAC: We %shave seeking support.\n", | |
429 FLAC_IS_SEEKABLE ? "" : "do NOT ")); | |
430 | |
431 return(1); /* always succeeds. */ | 344 return(1); /* always succeeds. */ |
432 } /* FLAC_init */ | 345 } /* FLAC_init */ |
433 | 346 |
434 | 347 |
435 static void FLAC_quit(void) | 348 static void FLAC_quit(void) |
446 SDL_RWops *rw = internal->rw; | 359 SDL_RWops *rw = internal->rw; |
447 decoder_t *decoder; | 360 decoder_t *decoder; |
448 flac_t *f; | 361 flac_t *f; |
449 int i; | 362 int i; |
450 int has_extension = 0; | 363 int has_extension = 0; |
451 | |
452 #if SOUND_SUPPORTS_SEEKABLE_FLAC | |
453 Uint32 pos; | 364 Uint32 pos; |
454 #endif | |
455 | 365 |
456 /* | 366 /* |
457 * If the extension is "flac", we'll believe that this is really meant | 367 * If the extension is "flac", we'll believe that this is really meant |
458 * to be a FLAC stream, and will try to grok it from existing metadata. | 368 * to be a FLAC stream, and will try to grok it from existing metadata. |
459 * metadata searching can be a very expensive operation, however, so | 369 * metadata searching can be a very expensive operation, however, so |
492 | 402 |
493 d_set_read_callback(decoder, read_callback); | 403 d_set_read_callback(decoder, read_callback); |
494 d_set_write_callback(decoder, write_callback); | 404 d_set_write_callback(decoder, write_callback); |
495 d_set_metadata_callback(decoder, metadata_callback); | 405 d_set_metadata_callback(decoder, metadata_callback); |
496 d_set_error_callback(decoder, error_callback); | 406 d_set_error_callback(decoder, error_callback); |
497 | |
498 #if SOUND_SUPPORTS_SEEKABLE_FLAC | |
499 d_set_seek_callback(decoder, seek_callback); | 407 d_set_seek_callback(decoder, seek_callback); |
500 d_set_tell_callback(decoder, tell_callback); | 408 d_set_tell_callback(decoder, tell_callback); |
501 d_set_length_callback(decoder, length_callback); | 409 d_set_length_callback(decoder, length_callback); |
502 d_set_eof_callback(decoder, eof_callback); | 410 d_set_eof_callback(decoder, eof_callback); |
503 #endif | 411 |
504 | |
505 d_set_client_data(decoder, f); | 412 d_set_client_data(decoder, f); |
506 | 413 |
507 f->rw = internal->rw; | 414 f->rw = internal->rw; |
508 f->sample = sample; | 415 f->sample = sample; |
509 f->decoder = decoder; | 416 f->decoder = decoder; |
512 | 419 |
513 internal->decoder_private = f; | 420 internal->decoder_private = f; |
514 d_init(decoder); | 421 d_init(decoder); |
515 | 422 |
516 sample->flags = SOUND_SAMPLEFLAG_NONE; | 423 sample->flags = SOUND_SAMPLEFLAG_NONE; |
517 | |
518 #if SOUND_SUPPORTS_SEEKABLE_FLAC | |
519 | 424 |
520 pos = SDL_RWtell(f->rw); | 425 pos = SDL_RWtell(f->rw); |
521 if (SDL_RWseek(f->rw, 0, SEEK_END) > 0) | 426 if (SDL_RWseek(f->rw, 0, SEEK_END) > 0) |
522 { | 427 { |
523 f->stream_length = SDL_RWtell(f->rw); | 428 f->stream_length = SDL_RWtell(f->rw); |
527 BAIL_MACRO(ERR_IO_ERROR, 0); | 432 BAIL_MACRO(ERR_IO_ERROR, 0); |
528 } /* if */ | 433 } /* if */ |
529 sample->flags = SOUND_SAMPLEFLAG_CANSEEK; | 434 sample->flags = SOUND_SAMPLEFLAG_CANSEEK; |
530 } /* if */ | 435 } /* if */ |
531 | 436 |
532 #else | |
533 | |
534 /* | |
535 * Annoyingly, the rewind method will put the FLAC decoder in a state | |
536 * where it expects to read metadata, so we have to set this marker | |
537 * before the metadata block. | |
538 */ | |
539 f->data_offset = SDL_RWtell(f->rw); | |
540 | |
541 #endif | |
542 | |
543 | |
544 /* | 437 /* |
545 * If we are not sure this is a FLAC stream, check for the STREAMINFO | 438 * If we are not sure this is a FLAC stream, check for the STREAMINFO |
546 * metadata block. If not, we'd have to peek at the first audio frame | 439 * metadata block. If not, we'd have to peek at the first audio frame |
547 * and get the sound format from there, but that is not yet | 440 * and get the sound format from there, but that is not yet |
548 * implemented. | 441 * implemented. |
599 } /* FLAC_read */ | 492 } /* FLAC_read */ |
600 | 493 |
601 | 494 |
602 static int FLAC_rewind(Sound_Sample *sample) | 495 static int FLAC_rewind(Sound_Sample *sample) |
603 { | 496 { |
604 #if SOUND_SUPPORTS_SEEKABLE_FLAC | |
605 return FLAC_seek(sample, 0); | 497 return FLAC_seek(sample, 0); |
606 #else | 498 } /* FLAC_rewind */ |
499 | |
500 | |
501 static int FLAC_seek(Sound_Sample *sample, Uint32 ms) | |
502 { | |
607 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | 503 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
608 flac_t *f = (flac_t *) internal->decoder_private; | 504 flac_t *f = (flac_t *) internal->decoder_private; |
609 int rc = SDL_RWseek(f->rw, f->data_offset, SEEK_SET); | |
610 | |
611 BAIL_IF_MACRO(rc != f->data_offset, ERR_IO_ERROR, 0); | |
612 BAIL_IF_MACRO(!d_reset(f->decoder), "FLAC: could not reset decoder", 0); | |
613 d_process_metadata(f->decoder); | |
614 return(1); | |
615 #endif | |
616 } /* FLAC_rewind */ | |
617 | |
618 | |
619 static int FLAC_seek(Sound_Sample *sample, Uint32 ms) | |
620 { | |
621 #if SOUND_SUPPORTS_SEEKABLE_FLAC | |
622 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
623 flac_t *f = (flac_t *) internal->decoder_private; | |
624 | 505 |
625 d_seek_absolute(f->decoder, (ms * sample->actual.rate) / 1000); | 506 d_seek_absolute(f->decoder, (ms * sample->actual.rate) / 1000); |
626 return(1); | 507 return(1); |
627 #else | |
628 BAIL_MACRO("FLAC: This is the non-seekable version of the decoder!", 0); | |
629 #endif | |
630 } /* FLAC_seek */ | 508 } /* FLAC_seek */ |
631 | 509 |
632 | |
633 #endif /* SOUND_SUPPORTS_FLAC */ | 510 #endif /* SOUND_SUPPORTS_FLAC */ |
634 | 511 |
635 | |
636 /* end of flac.c ... */ | 512 /* end of flac.c ... */ |