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