Mercurial > SDL_sound_CoreAudio
comparison SDL_sound.c @ 48:c4b8c39a9798
Individual decoders are now initialized during Sound_Init(), and deinitialized
during Sound_Quit(). Those that fail initialization are flagged as
unavailable. Removed MULTIPLE_STREAMS_PER_RWOPS. Added MOD entry.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 22 Sep 2001 14:46:44 +0000 |
parents | f27bcbcaeab1 |
children | b13fafb976be |
comparison
equal
deleted
inserted
replaced
47:ea58bc3b15d7 | 48:c4b8c39a9798 |
---|---|
46 | 46 |
47 #if (defined SOUND_SUPPORTS_MP3) | 47 #if (defined SOUND_SUPPORTS_MP3) |
48 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MP3; | 48 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MP3; |
49 #endif | 49 #endif |
50 | 50 |
51 #if (defined SOUND_SUPPORTS_MOD) | |
52 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_MOD; | |
53 #endif | |
54 | |
51 #if (defined SOUND_SUPPORTS_WAV) | 55 #if (defined SOUND_SUPPORTS_WAV) |
52 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV; | 56 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV; |
53 #endif | 57 #endif |
54 | 58 |
55 #if (defined SOUND_SUPPORTS_AIFF) | 59 #if (defined SOUND_SUPPORTS_AIFF) |
66 | 70 |
67 #if (defined SOUND_SUPPORTS_RAW) | 71 #if (defined SOUND_SUPPORTS_RAW) |
68 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_RAW; | 72 extern const Sound_DecoderFunctions __Sound_DecoderFunctions_RAW; |
69 #endif | 73 #endif |
70 | 74 |
71 static const Sound_DecoderFunctions *decoderFuncs[] = | 75 |
76 | |
77 typedef struct | |
78 { | |
79 int available; | |
80 const Sound_DecoderFunctions *funcs; | |
81 } decoder_element; | |
82 | |
83 static decoder_element decoders[] = | |
72 { | 84 { |
73 #if (defined SOUND_SUPPORTS_MP3) | 85 #if (defined SOUND_SUPPORTS_MP3) |
74 &__Sound_DecoderFunctions_MP3, | 86 { 0, &__Sound_DecoderFunctions_MP3 }, |
87 #endif | |
88 | |
89 #if (defined SOUND_SUPPORTS_MOD) | |
90 { 0, &__Sound_DecoderFunctions_MOD }, | |
75 #endif | 91 #endif |
76 | 92 |
77 #if (defined SOUND_SUPPORTS_WAV) | 93 #if (defined SOUND_SUPPORTS_WAV) |
78 &__Sound_DecoderFunctions_WAV, | 94 { 0, &__Sound_DecoderFunctions_WAV }, |
79 #endif | 95 #endif |
80 | 96 |
81 #if (defined SOUND_SUPPORTS_AIFF) | 97 #if (defined SOUND_SUPPORTS_AIFF) |
82 &__Sound_DecoderFunctions_AIFF, | 98 { 0, &__Sound_DecoderFunctions_AIFF }, |
83 #endif | 99 #endif |
84 | 100 |
85 #if (defined SOUND_SUPPORTS_OGG) | 101 #if (defined SOUND_SUPPORTS_OGG) |
86 &__Sound_DecoderFunctions_OGG, | 102 { 0, &__Sound_DecoderFunctions_OGG }, |
87 #endif | 103 #endif |
88 | 104 |
89 #if (defined SOUND_SUPPORTS_VOC) | 105 #if (defined SOUND_SUPPORTS_VOC) |
90 &__Sound_DecoderFunctions_VOC, | 106 { 0, &__Sound_DecoderFunctions_VOC }, |
91 #endif | 107 #endif |
92 | 108 |
93 #if (defined SOUND_SUPPORTS_RAW) | 109 #if (defined SOUND_SUPPORTS_RAW) |
94 &__Sound_DecoderFunctions_RAW, | 110 { 0, &__Sound_DecoderFunctions_RAW }, |
95 #endif | 111 #endif |
96 | |
97 NULL | |
98 }; | 112 }; |
99 | 113 |
100 | 114 |
101 | 115 |
102 /* General SDL_sound state ... */ | 116 /* General SDL_sound state ... */ |
120 | 134 |
121 | 135 |
122 int Sound_Init(void) | 136 int Sound_Init(void) |
123 { | 137 { |
124 size_t i; | 138 size_t i; |
139 size_t pos = 0; | |
140 size_t total = sizeof (decoders) / sizeof (decoders[0]); | |
125 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); | 141 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); |
126 samplesList = NULL; | 142 samplesList = NULL; |
127 | 143 |
128 SDL_Init(SDL_INIT_AUDIO); | 144 SDL_Init(SDL_INIT_AUDIO); |
129 | 145 |
130 for (i = 0; decoderFuncs[i] != NULL; i++) | |
131 ; /* do nothing. */ | |
132 | |
133 available_decoders = (const Sound_DecoderInfo **) | 146 available_decoders = (const Sound_DecoderInfo **) |
134 malloc((i + 1) * sizeof (Sound_DecoderInfo *)); | 147 malloc((total + 1) * sizeof (Sound_DecoderInfo *)); |
135 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0); | 148 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0); |
136 | 149 |
137 for (i = 0; decoderFuncs[i] != NULL; i++) | 150 for (i = 0; i < total; i++) |
138 available_decoders[i] = &decoderFuncs[i]->info; | 151 { |
139 | 152 decoders[i].available = decoders[i].funcs->init(); |
140 available_decoders[i] = NULL; | 153 if (decoders[i].available) |
154 { | |
155 available_decoders[pos] = &(decoders[i].funcs->info); | |
156 pos++; | |
157 } /* if */ | |
158 } /* for */ | |
159 | |
160 available_decoders[pos] = NULL; | |
141 | 161 |
142 initialized = 1; | 162 initialized = 1; |
143 return(1); | 163 return(1); |
144 } /* Sound_Init */ | 164 } /* Sound_Init */ |
145 | 165 |
146 | 166 |
147 int Sound_Quit(void) | 167 int Sound_Quit(void) |
148 { | 168 { |
169 size_t total = sizeof (decoders) / sizeof (decoders[0]); | |
170 size_t i; | |
171 | |
149 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); | 172 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); |
150 | 173 |
151 while (((volatile Sound_Sample *) samplesList) != NULL) | 174 while (((volatile Sound_Sample *) samplesList) != NULL) |
152 Sound_FreeSample(samplesList); | 175 Sound_FreeSample(samplesList); |
176 | |
177 for (i = 0; i < total; i++) | |
178 { | |
179 if (decoders[i].available) | |
180 { | |
181 decoders[i].funcs->quit(); | |
182 decoders[i].available = 0; | |
183 } /* if */ | |
184 } /* for */ | |
153 | 185 |
154 if (available_decoders != NULL) | 186 if (available_decoders != NULL) |
155 free(available_decoders); | 187 free(available_decoders); |
156 available_decoders = NULL; | 188 available_decoders = NULL; |
157 | 189 |
361 if (samplesList != NULL) | 393 if (samplesList != NULL) |
362 internal->prev = sample; | 394 internal->prev = sample; |
363 } /* if */ | 395 } /* if */ |
364 samplesList = sample; | 396 samplesList = sample; |
365 | 397 |
366 #if (defined MULTIPLE_STREAMS_PER_RWOPS) | |
367 internal->pos = SDL_RWtell(internal->rw); | |
368 #endif | |
369 | |
370 _D(("New sample DESIRED format: %s format, %d rate, %d channels.\n", | 398 _D(("New sample DESIRED format: %s format, %d rate, %d channels.\n", |
371 fmt_to_str(sample->desired.format), | 399 fmt_to_str(sample->desired.format), |
372 sample->desired.rate, | 400 sample->desired.rate, |
373 sample->desired.channels)); | 401 sample->desired.channels)); |
374 | 402 |
385 | 413 |
386 | 414 |
387 Sound_Sample *Sound_NewSample(SDL_RWops *rw, const char *ext, | 415 Sound_Sample *Sound_NewSample(SDL_RWops *rw, const char *ext, |
388 Sound_AudioInfo *desired, Uint32 bSize) | 416 Sound_AudioInfo *desired, Uint32 bSize) |
389 { | 417 { |
418 size_t total = sizeof (decoders) / sizeof (decoders[0]); | |
390 size_t i; | 419 size_t i; |
391 Sound_Sample *retval; | 420 Sound_Sample *retval; |
392 | 421 |
393 /* sanity checks. */ | 422 /* sanity checks. */ |
394 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL); | 423 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, NULL); |
398 if (!retval) | 427 if (!retval) |
399 return(NULL); /* alloc_sample() sets error message... */ | 428 return(NULL); /* alloc_sample() sets error message... */ |
400 | 429 |
401 if (ext != NULL) | 430 if (ext != NULL) |
402 { | 431 { |
403 for (i = 0; decoderFuncs[i] != NULL; i++) | 432 for (i = 0; i < total; i++) |
404 { | 433 { |
405 const char *decoderExt = decoderFuncs[i]->info.extension; | 434 if (decoders[i].available) |
406 if (__Sound_strcasecmp(decoderExt, ext) == 0) | |
407 { | 435 { |
408 if (init_sample(decoderFuncs[i], retval, ext, desired)) | 436 const char *decoderExt = decoders[i].funcs->info.extension; |
409 return(retval); | 437 if (__Sound_strcasecmp(decoderExt, ext) == 0) |
438 { | |
439 if (init_sample(decoders[i].funcs, retval, ext, desired)) | |
440 return(retval); | |
441 } /* if */ | |
410 } /* if */ | 442 } /* if */ |
411 } /* for */ | 443 } /* for */ |
412 } /* if */ | 444 } /* if */ |
413 | 445 |
414 /* no direct extension match? Try everything we've got... */ | 446 /* no direct extension match? Try everything we've got... */ |
415 for (i = 0; decoderFuncs[i] != NULL; i++) | 447 for (i = 0; i < total; i++) |
416 { | 448 { |
417 if (init_sample(decoderFuncs[i], retval, ext, desired)) | 449 if (decoders[i].available) |
418 return(retval); | 450 { |
451 if (init_sample(decoders[i].funcs, retval, ext, desired)) | |
452 return(retval); | |
453 } /* if */ | |
419 } /* for */ | 454 } /* for */ |
420 | 455 |
421 /* nothing could handle the sound data... */ | 456 /* nothing could handle the sound data... */ |
422 free(retval->opaque); | 457 free(retval->opaque); |
423 if (retval->buffer != NULL) | 458 if (retval->buffer != NULL) |
541 assert(internal->buffer != NULL); | 576 assert(internal->buffer != NULL); |
542 assert(internal->buffer_size > 0); | 577 assert(internal->buffer_size > 0); |
543 | 578 |
544 /* reset EAGAIN. Decoder can flip it back on if it needs to. */ | 579 /* reset EAGAIN. Decoder can flip it back on if it needs to. */ |
545 sample->flags &= !SOUND_SAMPLEFLAG_EAGAIN; | 580 sample->flags &= !SOUND_SAMPLEFLAG_EAGAIN; |
546 | |
547 #if (defined MULTIPLE_STREAMS_PER_RWOPS) | |
548 if (SDL_RWseek(internal->rw, internal->pos, SEEK_SET) == -1) | |
549 { | |
550 sample->flags |= SOUND_SAMPLEFLAG_ERROR; | |
551 return(0); | |
552 } /* if */ | |
553 #endif | |
554 | |
555 retval = internal->funcs->read(sample); | 581 retval = internal->funcs->read(sample); |
556 | |
557 #if (defined MULTIPLE_STREAMS_PER_RWOPS) | |
558 internal->pos = SDL_RWtell(internal->rw); | |
559 #endif | |
560 | 582 |
561 if (internal->sdlcvt.needed) | 583 if (internal->sdlcvt.needed) |
562 { | 584 { |
563 internal->sdlcvt.len = retval; | 585 internal->sdlcvt.len = retval; |
564 SDL_ConvertAudio(&internal->sdlcvt); | 586 SDL_ConvertAudio(&internal->sdlcvt); |