Mercurial > SDL_sound_CoreAudio
comparison decoders/flac.c @ 164:77482005beb6
Now includes FLAC/stream_decoder.h instead of FLAC/all.h. More robust
stream handling; uses metadata check to see if stream is valid instead of
magic number.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Mon, 19 Nov 2001 16:39:42 +0000 |
parents | 72ff7d3a25b6 |
children | d8904267d23c |
comparison
equal
deleted
inserted
replaced
163:b6d6f994e970 | 164:77482005beb6 |
---|---|
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 | 47 |
48 #include "FLAC/all.h" | 48 #include "FLAC/stream_decoder.h" |
49 | 49 |
50 | 50 |
51 static int FLAC_init(void); | 51 static int FLAC_init(void); |
52 static void FLAC_quit(void); | 52 static void FLAC_quit(void); |
53 static int FLAC_open(Sound_Sample *sample, const char *ext); | 53 static int FLAC_open(Sound_Sample *sample, const char *ext); |
77 { | 77 { |
78 FLAC__StreamDecoder *decoder; | 78 FLAC__StreamDecoder *decoder; |
79 SDL_RWops *rw; | 79 SDL_RWops *rw; |
80 Sound_Sample *sample; | 80 Sound_Sample *sample; |
81 Uint32 frame_size; | 81 Uint32 frame_size; |
82 Uint8 metadata_found; | |
82 } flac_t; | 83 } flac_t; |
83 | 84 |
84 | 85 |
85 static FLAC__StreamDecoderReadStatus FLAC_read_callback( | 86 static FLAC__StreamDecoderReadStatus FLAC_read_callback( |
86 const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], | 87 const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], |
88 { | 89 { |
89 flac_t *f = (flac_t *) client_data; | 90 flac_t *f = (flac_t *) client_data; |
90 Uint32 retval; | 91 Uint32 retval; |
91 | 92 |
92 #if 0 | 93 #if 0 |
93 SNDDBG(("FLAC: Read callback\n")); | 94 SNDDBG(("FLAC: Read callback.\n")); |
94 #endif | 95 #endif |
95 | 96 |
96 retval = SDL_RWread(f->rw, (Uint8 *) buffer, 1, *bytes); | 97 retval = SDL_RWread(f->rw, (Uint8 *) buffer, 1, *bytes); |
97 | 98 |
98 if (retval == 0) | 99 if (retval == 0) |
99 { | 100 { |
100 SNDDBG(("FLAC: End of file\n")); | |
101 *bytes = 0; | 101 *bytes = 0; |
102 f->sample->flags |= SOUND_SAMPLEFLAG_EOF; | 102 f->sample->flags |= SOUND_SAMPLEFLAG_EOF; |
103 return(FLAC__STREAM_DECODER_READ_END_OF_STREAM); | 103 return(FLAC__STREAM_DECODER_READ_END_OF_STREAM); |
104 } /* if */ | 104 } /* if */ |
105 | 105 |
169 SNDDBG(("FLAC: Metadata callback.\n")); | 169 SNDDBG(("FLAC: Metadata callback.\n")); |
170 | 170 |
171 if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) | 171 if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) |
172 { | 172 { |
173 SNDDBG(("FLAC: Metadata is streaminfo.\n")); | 173 SNDDBG(("FLAC: Metadata is streaminfo.\n")); |
174 f->metadata_found = 1; | |
174 f->sample->actual.channels = metadata->data.stream_info.channels; | 175 f->sample->actual.channels = metadata->data.stream_info.channels; |
175 f->sample->actual.rate = metadata->data.stream_info.sample_rate; | 176 f->sample->actual.rate = metadata->data.stream_info.sample_rate; |
176 | 177 |
177 /* !!! FIXME: I believe bits_per_sample may be anywhere between | 178 /* !!! FIXME: I believe bits_per_sample may be anywhere between |
178 * 4 and 24. We can only handle 8 and 16 at present. | 179 * 4 and 24. We can only handle 8 and 16 at present. |
184 break; | 185 break; |
185 case 16: | 186 case 16: |
186 f->sample->actual.format = AUDIO_S16MSB; | 187 f->sample->actual.format = AUDIO_S16MSB; |
187 break; | 188 break; |
188 default: | 189 default: |
189 Sound_SetError("FLAC: Unsupported sample width.\n"); | 190 Sound_SetError("FLAC: Unsupported sample width."); |
190 f->sample->actual.format = 0; | 191 f->sample->actual.format = 0; |
191 break; | 192 break; |
192 } /* switch */ | 193 } /* switch */ |
193 } /* if */ | 194 } /* if */ |
194 } /* FLAC_metadata_callback */ | 195 } /* FLAC_metadata_callback */ |
197 void FLAC_error_callback( | 198 void FLAC_error_callback( |
198 const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, | 199 const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, |
199 void *client_data) | 200 void *client_data) |
200 { | 201 { |
201 flac_t *f = (flac_t *) client_data; | 202 flac_t *f = (flac_t *) client_data; |
202 | 203 |
203 SNDDBG(("FLAC: Error callback.\n")); | 204 Sound_SetError(FLAC__StreamDecoderErrorStatusString[status]); |
204 f->sample->flags |= SOUND_SAMPLEFLAG_ERROR; | 205 f->sample->flags |= SOUND_SAMPLEFLAG_ERROR; |
205 } /* FLAC_error_callback */ | 206 } /* FLAC_error_callback */ |
206 | 207 |
207 | 208 |
208 static int FLAC_init(void) | 209 static int FLAC_init(void) |
220 static int FLAC_open(Sound_Sample *sample, const char *ext) | 221 static int FLAC_open(Sound_Sample *sample, const char *ext) |
221 { | 222 { |
222 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | 223 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
223 SDL_RWops *rw = internal->rw; | 224 SDL_RWops *rw = internal->rw; |
224 FLAC__StreamDecoder *decoder; | 225 FLAC__StreamDecoder *decoder; |
225 Uint8 flac_magic[4]; | |
226 flac_t *f; | 226 flac_t *f; |
227 | |
228 if (SDL_RWread(rw, flac_magic, sizeof (flac_magic), 1) != 1) | |
229 { | |
230 Sound_SetError("FLAC: Could not read FLAC magic."); | |
231 return(0); | |
232 } /* if */ | |
233 | |
234 if (strncmp(flac_magic, "fLaC", sizeof (flac_magic)) != 0) | |
235 { | |
236 Sound_SetError("FLAC: Not a FLAC stream."); | |
237 return(0); | |
238 } /* if */ | |
239 | |
240 SDL_RWseek(internal->rw, -sizeof (flac_magic), SEEK_CUR); | |
241 | 227 |
242 f = (flac_t *) malloc(sizeof (flac_t)); | 228 f = (flac_t *) malloc(sizeof (flac_t)); |
243 BAIL_IF_MACRO(f == NULL, ERR_OUT_OF_MEMORY, 0); | 229 BAIL_IF_MACRO(f == NULL, ERR_OUT_OF_MEMORY, 0); |
244 | 230 |
245 decoder = FLAC__stream_decoder_new(); | 231 decoder = FLAC__stream_decoder_new(); |
261 f->decoder = decoder; | 247 f->decoder = decoder; |
262 | 248 |
263 FLAC__stream_decoder_init(decoder); | 249 FLAC__stream_decoder_init(decoder); |
264 internal->decoder_private = f; | 250 internal->decoder_private = f; |
265 | 251 |
266 SNDDBG(("FLAC: Accepting data stream.\n")); | 252 f->metadata_found = 0; |
267 | 253 f->sample->actual.format = 0; |
268 FLAC__stream_decoder_process_metadata(decoder); | 254 FLAC__stream_decoder_process_metadata(decoder); |
269 | 255 |
270 if (f->sample->actual.format == 0) | 256 if (f->sample->actual.format == 0) |
271 { | 257 { |
258 if (f->metadata_found == 0) | |
259 Sound_SetError("FLAC: No metadata found."); | |
272 FLAC__stream_decoder_finish(decoder); | 260 FLAC__stream_decoder_finish(decoder); |
273 FLAC__stream_decoder_delete(decoder); | 261 FLAC__stream_decoder_delete(decoder); |
274 free(f); | 262 free(f); |
275 return(0); | 263 return(0); |
276 } /* if */ | 264 } /* if */ |
265 | |
266 SNDDBG(("FLAC: Accepting data stream.\n")); | |
277 | 267 |
278 sample->flags = SOUND_SAMPLEFLAG_NONE; | 268 sample->flags = SOUND_SAMPLEFLAG_NONE; |
279 return(1); | 269 return(1); |
280 } /* FLAC_open */ | 270 } /* FLAC_open */ |
281 | 271 |
303 return(0); | 293 return(0); |
304 } /* if */ | 294 } /* if */ |
305 | 295 |
306 if (!FLAC__stream_decoder_process_one_frame(f->decoder)) | 296 if (!FLAC__stream_decoder_process_one_frame(f->decoder)) |
307 { | 297 { |
308 SNDDBG(("FLAC: Couldn't decode frame.\n")); | 298 Sound_SetError("FLAC: Couldn't decode frame."); |
309 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | 299 sample->flags |= SOUND_SAMPLEFLAG_ERROR; |
310 return(0); | 300 return(0); |
311 } /* if */ | 301 } /* if */ |
312 | 302 |
303 /* An error may have been signalled through the error callback. */ | |
304 if (sample->flags & SOUND_SAMPLEFLAG_ERROR) | |
305 return(0); | |
306 | |
313 return(f->frame_size); | 307 return(f->frame_size); |
314 } /* FLAC_read */ | 308 } /* FLAC_read */ |
315 | 309 |
316 #endif /* SOUND_SUPPORTS_FLAC */ | 310 #endif /* SOUND_SUPPORTS_FLAC */ |
317 | 311 |