comparison SDL_sound.c @ 237:ceadd952319a

Increased ModPlug decoder's priority to be above MikMod. Fixed some coding conventions. Mutex-protected the current sample list. Fixed sample list addition code. Decoder selection in NewSample is more efficient now. Other cleanups and corrections.
author Ryan C. Gordon <icculus@icculus.org>
date Sat, 19 Jan 2002 23:31:19 +0000
parents 57e16a6d244f
children 6fe6de401b63
comparison
equal deleted inserted replaced
236:034b2e56f405 237:ceadd952319a
107 { 107 {
108 #if (defined SOUND_SUPPORTS_MP3) 108 #if (defined SOUND_SUPPORTS_MP3)
109 { 0, &__Sound_DecoderFunctions_MP3 }, 109 { 0, &__Sound_DecoderFunctions_MP3 },
110 #endif 110 #endif
111 111
112 #if (defined SOUND_SUPPORTS_MODPLUG)
113 { 0, &__Sound_DecoderFunctions_MODPLUG },
114 #endif
115
112 #if (defined SOUND_SUPPORTS_MIKMOD) 116 #if (defined SOUND_SUPPORTS_MIKMOD)
113 { 0, &__Sound_DecoderFunctions_MIKMOD }, 117 { 0, &__Sound_DecoderFunctions_MIKMOD },
114 #endif 118 #endif
115 119
116 #if (defined SOUND_SUPPORTS_MODPLUG)
117 { 0, &__Sound_DecoderFunctions_MODPLUG },
118 #endif
119
120 #if (defined SOUND_SUPPORTS_WAV) 120 #if (defined SOUND_SUPPORTS_WAV)
121 { 0, &__Sound_DecoderFunctions_WAV }, 121 { 0, &__Sound_DecoderFunctions_WAV },
122 #endif 122 #endif
123 123
124 #if (defined SOUND_SUPPORTS_AIFF) 124 #if (defined SOUND_SUPPORTS_AIFF)
161 /* General SDL_sound state ... */ 161 /* General SDL_sound state ... */
162 162
163 typedef struct __SOUND_ERRMSGTYPE__ 163 typedef struct __SOUND_ERRMSGTYPE__
164 { 164 {
165 Uint32 tid; 165 Uint32 tid;
166 int errorAvailable; 166 int error_available;
167 char errorString[128]; 167 char error_string[128];
168 struct __SOUND_ERRMSGTYPE__ *next; 168 struct __SOUND_ERRMSGTYPE__ *next;
169 } ErrMsg; 169 } ErrMsg;
170 170
171 static ErrMsg *errorMessages = NULL; 171 static ErrMsg *error_msgs = NULL;
172 static SDL_mutex *errorlist_mutex = NULL; 172 static SDL_mutex *errorlist_mutex = NULL;
173 173
174 /* !!! FIXME: This needs a mutex. */ 174 static Sound_Sample *sample_list = NULL; /* this is a linked list. */
175 static Sound_Sample *samplesList = NULL; /* this is a linked list. */ 175 static SDL_mutex *samplelist_mutex = NULL;
176
176 static const Sound_DecoderInfo **available_decoders = NULL; 177 static const Sound_DecoderInfo **available_decoders = NULL;
177 static int initialized = 0; 178 static int initialized = 0;
178 179
179 180
180 /* functions ... */ 181 /* functions ... */
195 size_t i; 196 size_t i;
196 size_t pos = 0; 197 size_t pos = 0;
197 size_t total = sizeof (decoders) / sizeof (decoders[0]); 198 size_t total = sizeof (decoders) / sizeof (decoders[0]);
198 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0); 199 BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
199 200
200 samplesList = NULL; 201 sample_list = NULL;
201 errorMessages = NULL; 202 error_msgs = NULL;
202 203
203 available_decoders = (const Sound_DecoderInfo **) 204 available_decoders = (const Sound_DecoderInfo **)
204 malloc((total) * sizeof (Sound_DecoderInfo *)); 205 malloc((total) * sizeof (Sound_DecoderInfo *));
205 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0); 206 BAIL_IF_MACRO(available_decoders == NULL, ERR_OUT_OF_MEMORY, 0);
206 207
207 SDL_Init(SDL_INIT_AUDIO); 208 SDL_Init(SDL_INIT_AUDIO);
209
208 errorlist_mutex = SDL_CreateMutex(); 210 errorlist_mutex = SDL_CreateMutex();
209 211
210 for (i = 0; decoders[i].funcs != NULL; i++) 212 for (i = 0; decoders[i].funcs != NULL; i++)
211 { 213 {
212 decoders[i].available = decoders[i].funcs->init(); 214 decoders[i].available = decoders[i].funcs->init();
230 ErrMsg *nexterr = NULL; 232 ErrMsg *nexterr = NULL;
231 size_t i; 233 size_t i;
232 234
233 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); 235 BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
234 236
235 while (((volatile Sound_Sample *) samplesList) != NULL) 237 while (((volatile Sound_Sample *) sample_list) != NULL)
236 Sound_FreeSample(samplesList); 238 Sound_FreeSample(sample_list);
237 239
238 samplesList = NULL; 240 initialized = 0;
241
242 SDL_DestroyMutex(samplelist_mutex);
243 samplelist_mutex = NULL;
244 sample_list = NULL;
239 245
240 for (i = 0; decoders[i].funcs != NULL; i++) 246 for (i = 0; decoders[i].funcs != NULL; i++)
241 { 247 {
242 if (decoders[i].available) 248 if (decoders[i].available)
243 { 249 {
250 free((void *) available_decoders); 256 free((void *) available_decoders);
251 available_decoders = NULL; 257 available_decoders = NULL;
252 258
253 /* clean up error state for each thread... */ 259 /* clean up error state for each thread... */
254 SDL_LockMutex(errorlist_mutex); 260 SDL_LockMutex(errorlist_mutex);
255 for (err = errorMessages; err != NULL; err = nexterr) 261 for (err = error_msgs; err != NULL; err = nexterr)
256 { 262 {
257 nexterr = err->next; 263 nexterr = err->next;
258 free(err); 264 free(err);
259 } /* for */ 265 } /* for */
260 errorMessages = NULL; 266 error_msgs = NULL;
261 initialized = 0;
262 SDL_UnlockMutex(errorlist_mutex); 267 SDL_UnlockMutex(errorlist_mutex);
263 SDL_DestroyMutex(errorlist_mutex); 268 SDL_DestroyMutex(errorlist_mutex);
264 errorlist_mutex = NULL; 269 errorlist_mutex = NULL;
265 270
266 return(1); 271 return(1);
276 static ErrMsg *findErrorForCurrentThread(void) 281 static ErrMsg *findErrorForCurrentThread(void)
277 { 282 {
278 ErrMsg *i; 283 ErrMsg *i;
279 Uint32 tid; 284 Uint32 tid;
280 285
281 if (errorMessages != NULL) 286 if (error_msgs != NULL)
282 { 287 {
283 tid = SDL_ThreadID(); 288 tid = SDL_ThreadID();
284 289
285 SDL_LockMutex(errorlist_mutex); 290 SDL_LockMutex(errorlist_mutex);
286 for (i = errorMessages; i != NULL; i = i->next) 291 for (i = error_msgs; i != NULL; i = i->next)
287 { 292 {
288 if (i->tid == tid) 293 if (i->tid == tid)
289 { 294 {
290 SDL_UnlockMutex(errorlist_mutex); 295 SDL_UnlockMutex(errorlist_mutex);
291 return(i); 296 return(i);
305 310
306 if (!initialized) 311 if (!initialized)
307 return(ERR_NOT_INITIALIZED); 312 return(ERR_NOT_INITIALIZED);
308 313
309 err = findErrorForCurrentThread(); 314 err = findErrorForCurrentThread();
310 if ((err != NULL) && (err->errorAvailable)) 315 if ((err != NULL) && (err->error_available))
311 { 316 {
312 retval = err->errorString; 317 retval = err->error_string;
313 err->errorAvailable = 0; 318 err->error_available = 0;
314 } /* if */ 319 } /* if */
315 320
316 return(retval); 321 return(retval);
317 } /* Sound_GetError */ 322 } /* Sound_GetError */
318 323
324 if (!initialized) 329 if (!initialized)
325 return; 330 return;
326 331
327 err = findErrorForCurrentThread(); 332 err = findErrorForCurrentThread();
328 if (err != NULL) 333 if (err != NULL)
329 err->errorAvailable = 0; 334 err->error_available = 0;
330 } /* Sound_ClearError */ 335 } /* Sound_ClearError */
331 336
332 337
333 /* 338 /*
334 * This is declared in the internal header. 339 * This is declared in the internal header.
355 360
356 memset((void *) err, '\0', sizeof (ErrMsg)); 361 memset((void *) err, '\0', sizeof (ErrMsg));
357 err->tid = SDL_ThreadID(); 362 err->tid = SDL_ThreadID();
358 363
359 SDL_LockMutex(errorlist_mutex); 364 SDL_LockMutex(errorlist_mutex);
360 err->next = errorMessages; 365 err->next = error_msgs;
361 errorMessages = err; 366 error_msgs = err;
362 SDL_UnlockMutex(errorlist_mutex); 367 SDL_UnlockMutex(errorlist_mutex);
363 } /* if */ 368 } /* if */
364 369
365 err->errorAvailable = 1; 370 err->error_available = 1;
366 strncpy(err->errorString, str, sizeof (err->errorString)); 371 strncpy(err->error_string, str, sizeof (err->error_string));
367 err->errorString[sizeof (err->errorString) - 1] = '\0'; 372 err->error_string[sizeof (err->error_string) - 1] = '\0';
368 } /* Sound_SetError */ 373 } /* Sound_SetError */
369 374
370 375
371 /* 376 /*
372 * -ansi and -pedantic flags prevent use of strcasecmp() on Linux, and 377 * -ansi and -pedantic flags prevent use of strcasecmp() on Linux, and
537 memcpy(&sample->desired, &desired, sizeof (Sound_AudioInfo)); 542 memcpy(&sample->desired, &desired, sizeof (Sound_AudioInfo));
538 internal->sdlcvt.buf = internal->buffer = sample->buffer; 543 internal->sdlcvt.buf = internal->buffer = sample->buffer;
539 internal->buffer_size = sample->buffer_size / internal->sdlcvt.len_mult; 544 internal->buffer_size = sample->buffer_size / internal->sdlcvt.len_mult;
540 internal->sdlcvt.len = internal->buffer_size; 545 internal->sdlcvt.len = internal->buffer_size;
541 546
542 /* Prepend our new Sound_Sample to the samplesList... */ 547 /* Prepend our new Sound_Sample to the sample_list... */
543 if (samplesList != NULL) 548 SDL_LockMutex(samplelist_mutex);
544 { 549 internal->next = sample_list;
545 internal->next = samplesList; 550 if (sample_list != NULL)
546 if (samplesList != NULL) 551 ((Sound_SampleInternal *) sample_list->opaque)->prev = sample;
547 internal->prev = sample; 552 sample_list = sample;
548 } /* if */ 553 SDL_UnlockMutex(samplelist_mutex);
549 samplesList = sample;
550 554
551 SNDDBG(("New sample DESIRED format: %s format, %d rate, %d channels.\n", 555 SNDDBG(("New sample DESIRED format: %s format, %d rate, %d channels.\n",
552 fmt_to_str(sample->desired.format), 556 fmt_to_str(sample->desired.format),
553 sample->desired.rate, 557 sample->desired.rate,
554 sample->desired.channels)); 558 sample->desired.channels));
590 { 594 {
591 if (__Sound_strcasecmp(*decoderExt, ext) == 0) 595 if (__Sound_strcasecmp(*decoderExt, ext) == 0)
592 { 596 {
593 if (init_sample(decoder->funcs, retval, ext, desired)) 597 if (init_sample(decoder->funcs, retval, ext, desired))
594 return(retval); 598 return(retval);
599 break; /* done with this decoder either way. */
595 } /* if */ 600 } /* if */
596 decoderExt++; 601 decoderExt++;
597 } /* while */ 602 } /* while */
598 } /* if */ 603 } /* if */
599 } /* for */ 604 } /* for */
602 /* no direct extension match? Try everything we've got... */ 607 /* no direct extension match? Try everything we've got... */
603 for (decoder = &decoders[0]; decoder->funcs != NULL; decoder++) 608 for (decoder = &decoders[0]; decoder->funcs != NULL; decoder++)
604 { 609 {
605 if (decoder->available) 610 if (decoder->available)
606 { 611 {
607 if (init_sample(decoder->funcs, retval, ext, desired)) 612 int should_try = 1;
608 return(retval); 613 const char **decoderExt = decoder->funcs->info.extensions;
614
615 /* skip if we would have tried decoder above... */
616 while (*decoderExt)
617 {
618 if (__Sound_strcasecmp(*decoderExt, ext) == 0)
619 {
620 should_try = 0;
621 break;
622 } /* if */
623 decoderExt++;
624 } /* while */
625
626 if (should_try)
627 {
628 if (init_sample(decoder->funcs, retval, ext, desired))
629 return(retval);
630 } /* if */
609 } /* if */ 631 } /* if */
610 } /* for */ 632 } /* for */
611 633
612 /* nothing could handle the sound data... */ 634 /* nothing could handle the sound data... */
613 free(retval->opaque); 635 free(retval->opaque);
657 return; 679 return;
658 } /* if */ 680 } /* if */
659 681
660 internal = (Sound_SampleInternal *) sample->opaque; 682 internal = (Sound_SampleInternal *) sample->opaque;
661 683
662 internal->funcs->close(sample); 684 SDL_LockMutex(samplelist_mutex);
663 685
664 /* update the samplesList... */ 686 /* update the sample_list... */
665 if (internal->prev != NULL) 687 if (internal->prev != NULL)
666 { 688 {
667 Sound_SampleInternal *prevInternal; 689 Sound_SampleInternal *prevInternal;
668 prevInternal = (Sound_SampleInternal *) internal->prev->opaque; 690 prevInternal = (Sound_SampleInternal *) internal->prev->opaque;
669 prevInternal->next = internal->next; 691 prevInternal->next = internal->next;
670 } /* if */ 692 } /* if */
671 else 693 else
672 { 694 {
673 assert(samplesList == sample); 695 assert(sample_list == sample);
674 samplesList = internal->next; 696 sample_list = internal->next;
675 } /* else */ 697 } /* else */
676 698
677 if (internal->next != NULL) 699 if (internal->next != NULL)
678 { 700 {
679 Sound_SampleInternal *nextInternal; 701 Sound_SampleInternal *nextInternal;
680 nextInternal = (Sound_SampleInternal *) internal->next->opaque; 702 nextInternal = (Sound_SampleInternal *) internal->next->opaque;
681 nextInternal->prev = internal->prev; 703 nextInternal->prev = internal->prev;
682 } /* if */ 704 } /* if */
683 705
706 SDL_UnlockMutex(samplelist_mutex);
707
684 /* nuke it... */ 708 /* nuke it... */
709 internal->funcs->close(sample);
710
685 if (internal->rw != NULL) /* this condition is a "just in case" thing. */ 711 if (internal->rw != NULL) /* this condition is a "just in case" thing. */
686 SDL_RWclose(internal->rw); 712 SDL_RWclose(internal->rw);
687 713
688 if ((internal->buffer != NULL) && (internal->buffer != sample->buffer)) 714 if ((internal->buffer != NULL) && (internal->buffer != sample->buffer))
689 free(internal->buffer); 715 free(internal->buffer);