diff --git a/src/sound.c b/src/sound.c index b9e5fc5..961ae54 100644 --- a/src/sound.c +++ b/src/sound.c @@ -7,6 +7,7 @@ #include <sys/stat.h> #include <SDL.h> +#include <SDL_thread.h> #include <SDL/SDL_mixer.h> #include "lephisto.h" @@ -72,8 +73,9 @@ static alSound* sound_list = NULL; /**< List of available sounds. */ static int sound_nlist = 0; /**< Number of available sounds. */ /* Voice linked list. */ -static alVoice* voice_active; /**< Active voices. */ -static alVoice* voice_pool; /**< Pool of free voices. */ +static SDL_mutex* voice_lock = NULL; +static alVoice* voice_active = NULL; /**< Active voices. */ +static alVoice* voice_pool = NULL; /**< Pool of free voices. */ /* General prototypes. */ static int sound_makeList(void); @@ -128,6 +130,9 @@ int sound_init(void) { /* Init the music. */ music_init(); + /* Create the voice lock. */ + voice_lock = SDL_CreateMutex(); + return 0; } @@ -140,6 +145,10 @@ void sound_exit(void) { int i; alVoice* v; + /* Close the audio. */ + Mix_CloseAudio(); + SDL_DestroyMutex(voice_lock); + /* Free the voices. */ while(voice_active != NULL) { v = voice_active; @@ -198,7 +207,7 @@ int sound_play(int sound) { if((sound < 0) || (sound > sound_nlist)) return -1; - v = voice_new(); + SDL_mutexP(voice_lock); v->channel = Mix_PlayChannel(-1, sound_list[sound].buffer, 0); @@ -277,6 +286,8 @@ int sound_updatePos(int voice, double x, double y) { if(sound_disabled) return 0; + SDL_mutexP(voice_lock); + v = voice_get(voice); if(v != NULL) { @@ -291,9 +302,13 @@ int sound_updatePos(int voice, double x, double y) { if(Mix_SetPosition(v->channel, (int)angle, (int)dist/10) < 0) { WARN("Unable to set sound position: %s", Mix_GetError()); + SDL_mutexV(voice_lock); return -1; } } + + SDL_mutexV(voice_lock); + return 0; } @@ -310,6 +325,8 @@ int sound_update(void) { if(voice_active == NULL) return 0; + SDL_mutexP(voice_lock); + /* The actualy control loop. */ for(v = voice_active; v != NULL; v = v->next) { /* Destroy and toss into pool. */ @@ -339,6 +356,9 @@ int sound_update(void) { if(v == NULL) break; } } + + SDL_mutexV(voice_lock); + return 0; } @@ -353,11 +373,15 @@ void sound_stop(int voice) { if(sound_disabled) return; + SDL_mutexP(voice_lock); + v = voice_get(voice); if(v != NULL) { Mix_HaltChannel(v->channel); v->state = VOICE_STOPPED; } + + SDL_mutexV(voice_lock); } /** @@ -592,11 +616,15 @@ void sound_stopGroup(int group) { static void voice_markStopped(int channel) { alVoice* v; + SDL_mutexP(voice_lock); + for(v = voice_active; v != NULL; v = v->next) if(v->channel == channel) { v->state = VOICE_STOPPED; - return; + break; } + + SDL_mutexV(voice_lock); } /**