Mercurial > SDL_sound_CoreAudio
comparison decoders/flac.c @ 231:d3dc34315ac7
Rewind method implemented by Torbj�rn.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 19 Jan 2002 16:58:34 +0000 |
parents | c9772a9f5271 |
children | c97be6e1bd27 |
comparison
equal
deleted
inserted
replaced
230:aa4137f121e4 | 231:d3dc34315ac7 |
---|---|
42 | 42 |
43 #include "SDL_sound.h" | 43 #include "SDL_sound.h" |
44 | 44 |
45 #define __SDL_SOUND_INTERNAL__ | 45 #define __SDL_SOUND_INTERNAL__ |
46 #include "SDL_sound_internal.h" | 46 #include "SDL_sound_internal.h" |
47 | |
48 /* | |
49 * libFLAC 1.0.1 added a seekable stream decoder, but if I understand the | |
50 * documentation correctly it's still much easier for us to handle the rewind | |
51 * method ourselves. | |
52 */ | |
47 | 53 |
48 #include "FLAC/stream_decoder.h" | 54 #include "FLAC/stream_decoder.h" |
49 | 55 |
50 | 56 |
51 static int FLAC_init(void); | 57 static int FLAC_init(void); |
78 typedef struct | 84 typedef struct |
79 { | 85 { |
80 FLAC__StreamDecoder *decoder; | 86 FLAC__StreamDecoder *decoder; |
81 SDL_RWops *rw; | 87 SDL_RWops *rw; |
82 Sound_Sample *sample; | 88 Sound_Sample *sample; |
89 Uint32 data_starting_offset; | |
83 Uint32 frame_size; | 90 Uint32 frame_size; |
84 Uint8 is_flac; | 91 Uint8 is_flac; |
85 } flac_t; | 92 } flac_t; |
86 | 93 |
87 | 94 |
300 | 307 |
301 internal->decoder_private = f; | 308 internal->decoder_private = f; |
302 FLAC__stream_decoder_init(decoder); | 309 FLAC__stream_decoder_init(decoder); |
303 | 310 |
304 /* | 311 /* |
312 * Annoyingly, the rewind method will put the FLAC decoder in a state | |
313 * where it expects to read metadata, so we have to set this marker | |
314 * before the metadata block. | |
315 */ | |
316 f->data_starting_offset = SDL_RWtell(f->rw); | |
317 | |
318 /* | |
305 * If we are not sure this is a FLAC stream, check for the STREAMINFO | 319 * If we are not sure this is a FLAC stream, check for the STREAMINFO |
306 * metadata block. If not, we'd have to peek at the first audio frame | 320 * metadata block. If not, we'd have to peek at the first audio frame |
307 * and get the sound format from there, but that is not yet | 321 * and get the sound format from there, but that is not yet |
308 * implemented. | 322 * implemented. |
309 */ | 323 */ |
340 { | 354 { |
341 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | 355 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
342 flac_t *f = (flac_t *) internal->decoder_private; | 356 flac_t *f = (flac_t *) internal->decoder_private; |
343 Uint32 len; | 357 Uint32 len; |
344 | 358 |
345 if (FLAC__stream_decoder_get_state(f->decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) | |
346 { | |
347 sample->flags |= SOUND_SAMPLEFLAG_EOF; | |
348 return(0); | |
349 } /* if */ | |
350 | |
351 if (!FLAC__stream_decoder_process_one_frame(f->decoder)) | 359 if (!FLAC__stream_decoder_process_one_frame(f->decoder)) |
352 { | 360 { |
353 Sound_SetError("FLAC: Couldn't decode frame."); | 361 Sound_SetError("FLAC: Couldn't decode frame."); |
354 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | 362 sample->flags |= SOUND_SAMPLEFLAG_ERROR; |
355 return(0); | 363 return(0); |
356 } /* if */ | 364 } /* if */ |
357 | 365 |
366 if (FLAC__stream_decoder_get_state(f->decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) | |
367 { | |
368 sample->flags |= SOUND_SAMPLEFLAG_EOF; | |
369 return(0); | |
370 } /* if */ | |
371 | |
358 /* An error may have been signalled through the error callback. */ | 372 /* An error may have been signalled through the error callback. */ |
359 if (sample->flags & SOUND_SAMPLEFLAG_ERROR) | 373 if (sample->flags & SOUND_SAMPLEFLAG_ERROR) |
360 return(0); | 374 return(0); |
361 | 375 |
362 return(f->frame_size); | 376 return(f->frame_size); |
363 } /* FLAC_read */ | 377 } /* FLAC_read */ |
364 | 378 |
365 | 379 |
366 static int FLAC_rewind(Sound_Sample *sample) | 380 static int FLAC_rewind(Sound_Sample *sample) |
367 { | 381 { |
368 /* !!! FIXME. */ | 382 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
369 SNDDBG(("FLAC_rewind(): Write me!\n")); | 383 flac_t *f = (flac_t *) internal->decoder_private; |
370 assert(0); | 384 int rc = SDL_RWseek(f->rw, f->data_starting_offset, SEEK_SET); |
371 return(0); | 385 |
386 BAIL_IF_MACRO(rc != f->data_starting_offset, ERR_IO_ERROR, 0); | |
387 BAIL_IF_MACRO(!FLAC__stream_decoder_reset(f->decoder), | |
388 "FLAC: could not reset decoder", 0); | |
389 FLAC__stream_decoder_process_metadata(f->decoder); | |
390 return(1); | |
372 } /* FLAC_rewind */ | 391 } /* FLAC_rewind */ |
373 | 392 |
374 #endif /* SOUND_SUPPORTS_FLAC */ | 393 #endif /* SOUND_SUPPORTS_FLAC */ |
375 | 394 |
376 | 395 |