From 2ac26a5aed12a90b732c39ffc79d6265ab0c8e7e Mon Sep 17 00:00:00 2001 From: Allanis Date: Tue, 4 Jun 2013 16:32:15 +0100 Subject: [PATCH] [Fix] [Phase 2] Almost there, Don't use this build, it is unstable. --- src/sound.c | 147 ++++++++++++++++++++++++++++++---------------------- src/sound.h | 16 +----- 2 files changed, 87 insertions(+), 76 deletions(-) diff --git a/src/sound.c b/src/sound.c index c47a740..39ecd8e 100644 --- a/src/sound.c +++ b/src/sound.c @@ -85,11 +85,25 @@ typedef struct VoiceSource_ { static VoiceSource* source_stack = NULL; // And it's stack. static int source_nstack = 0; -// Virtual voice stack. -static alVoice** voice_stack = NULL; -static int voice_nstack = 0; -static int voice_mstack = 0; -#define VOICE_CHUNK 64 // Allocate by these chunks. +// Virtual voice. +struct alVoice { + alVoice* next; // Yes it's a linked list. + + ALuint id; // Unique id for the voice. + + ALuint source; // Source itself, 0 if not set. + ALuint buffer; // Buffer. + + int priority; // Base priority. + + double px, py; // Position. + double vx, vy; // Velocity. + + unsigned int start; // time started in ms. + unsigned int flags; // Flags to set properties. +}; +static alVoice* voice_start = NULL; +static alVoice* voice_end = NULL; // Volume. static ALfloat svolume = 0.3; @@ -147,8 +161,8 @@ int sound_init(void) { // Start the music server. music_init(); - music_player = SDL_CreateThread(music_thread, NULL); +#if 0 // Start allocating the sources - music has already taken this. alGetError(); // Another error clear. mem = 0; @@ -165,6 +179,7 @@ int sound_init(void) { // Use minimal ram. source_stack = realloc(source_stack, sizeof(VoiceSource) * source_nstack); +#endif // Debug magic. DEBUG("OpenAL: %s", device); @@ -249,18 +264,25 @@ static int sound_makeList(void) { uint32_t nfiles, i; char tmp[64]; int len; + int mem; // Get the file list. files = pack_listfiles(data, &nfiles); // Load the profiles. + mem = 0; for(i = 0; i < nfiles; i++) if((strncmp(files[i], SOUND_PREFIX, strlen(SOUND_PREFIX))==0) && (strncmp(files[i] + strlen(files[i]) - strlen(SOUND_SUFFIX), SOUND_SUFFIX, strlen(SOUND_SUFFIX))==0)) { // Expand the selection size. - sound_list = realloc(sound_list, ++nsound_list * sizeof(alSound)); + nsound_list++; + if(nsound_list > mem) { + // We must grow. + mem += 32; // We'll overallocate most likely. + sound_list = realloc(sound_list, mem*sizeof(alSound)); + } // Remove the prefix and suffix. len = strlen(files[i]) - strlen(SOUND_SUFFIX SOUND_PREFIX); @@ -272,12 +294,15 @@ static int sound_makeList(void) { sound_load(&sound_list[nsound_list-1].buffer, files[i]); } + // Shrink to minimum ram usage. + sound_list = realloc(sound_list, nsound_list*sizeof(alSound)); + // Free the char* allocated by pack. for(i = 0; i < nfiles; i++) free(files[i]); free(files); - DEBUG("Loaded %d sound%c", nsound_list, (nsound_list==1)?' ':'s'); + DEBUG("Loaded %d sound%s", nsound_list, (nsound_list==1)?"":'s'); return 0; } @@ -326,21 +351,51 @@ static void sound_free(alSound* snd) { // Update the sounds and prioritize them. void sound_update(void) { - if(sound_lock == NULL) return; - int i; + ALint stat; + alVoice* voice, *prev, *next; + + if(sound_lock == NULL) return; // Sound system is off. + if(voice_start == NULL) return; // No voices. SDL_mutexP(sound_lock); - for(i = 0; i < voice_nstack; i++) { - if(voice_is(voice_stack[i], VOICE_PLAYING)) { + // Update sound. + prev = NULL; + voice = voice_start; + do { + next = voice->next; + if(!voice_is(voice, VOICE_DONE)) { // Still working. // Update position. - alSource3f(voice_stack[i]->source, AL_POSITION, - voice_stack[i]->px, voice_stack[i]->py, 0.); - //alSource3f(voice_stack[i]->source, AL_VELOCITY, - //voice_stack[i]->vx, voice_stack[i]->vy, 0.); + alSource3f(voice->source, AL_POSITION, + voice->px, voice->py, 0.); + /*alSource3f(voice->source, AL_VELOCITY, + voice->vx, voice->vy, 0.);*/ + } else { // Delete them. + if(voice->source != 0) { + // Sources must exist. + // Stop it if playing. + alGetSourcei(voice->source, AL_SOURCE_STATE, &stat); + if(stat == AL_PLAYING) alSourceStop(voice->source); + + // Clear it and get rid of it. + alDeleteSources(1, &voice->source); + voice->source = 0; + } + + // Delete from linked list. + if(prev == NULL) + voice_start = voice->next; + else // Not first member. + prev->next = voice->next; + if(voice_end == voice) + voice_end = prev; + free(voice); } - } + prev = voice; + voice = next; + } while(voice != NULL); + SDL_mutexV(sound_lock); } @@ -348,15 +403,7 @@ void sound_update(void) { void sound_volume(const double vol) { if(sound_lock == NULL) return; - int i; - svolume = (ALfloat) vol; - - SDL_mutexP(sound_lock); - for(i = 0; i < voice_nstack; i++) - if(voice_set(voice_stack[i], VOICE_PLAYING)) - alSourcef(voice_stack[i]->source, AL_GAIN, svolume); - SDL_mutexV(sound_lock); } // Attempt to alloc a source for a voice. @@ -415,17 +462,15 @@ alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy if(sound_lock == NULL) return NULL; - voice_nstack++; - if(voice_nstack > voice_mstack) - voice_stack = realloc(voice_stack, ++voice_mstack*sizeof(alVoice*)); - + // Allocate the voice. voc = malloc(sizeof(alVoice)); - voice_stack[voice_nstack-1] = voc; // Set the data. + voc->next = NULL; voc->priority = priority; voc->start = SDL_GetTicks(); voc->buffer = buffer; + voc->flags = 0; if(looping != 0) voice_set(voc, VOICE_LOOPING); voc->px = px; voc->py = py; @@ -434,44 +479,22 @@ alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy voice_getSource(voc); + if(voice_start == NULL) { + voice_start = voc; + voice_end = voc; + } else { + if(voice_end != NULL) + voice_end->next = voc; + voice_end = voc; + } + return voc; } void sound_delVoice(alVoice* voice) { if(sound_lock == NULL) return; - ALint stat; - int i; - // Linear search. - for(i = 0; i < voice_nstack; i++) - if(voice == voice_stack[i]) - break; - - // No match found. - if(i >= voice_nstack) { - WARN("Unable to find voice to free from stack"); - return; - } - - // Source must exist. - if(voice->source) { - SDL_mutexP(sound_lock); - - // Stop it if playing. - alGetSourcei(voice->source, AL_SOURCE_STATE, &stat); - if(stat == AL_PLAYING) alSourceStop(voice->source); - - // Clear it and get rid of it. - alDeleteSources(1, &voice->source); - voice->source = 0; - - SDL_mutexV(sound_lock); - } - - free(voice_stack[i]); - voice_nstack--; - for(; i < voice_nstack; i++) - voice_stack[i] = voice_stack[i+1]; + voice_set(voice, VOICE_DONE); } // Update voice position, should be run once per frame. diff --git a/src/sound.h b/src/sound.h index dfaab8d..fc1d01f 100644 --- a/src/sound.h +++ b/src/sound.h @@ -2,20 +2,8 @@ #include #include "physics.h" -// Virtual voice. -typedef struct alVoice_ { - ALuint id; // Unique id for the voice. - ALuint source; // Source itself, 0 if not set. - ALuint buffer; // Buffer. - - int priority; // Base priority. - - double px, py; // Position. - double vx, vy; // Velocity. - - unsigned int start; // Time started in ms. - unsigned int flags; // Flags to set properties. -} alVoice; +struct alVoice; +typedef struct alVoice alVoice; // Sound subsystem. int sound_init(void);