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 ... */