[Fix] [Phase 2] Almost there, Don't use this build, it is unstable.

This commit is contained in:
Allanis 2013-06-04 16:32:15 +01:00
parent 6870dd2057
commit 2ac26a5aed
2 changed files with 87 additions and 76 deletions

View File

@ -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.

View File

@ -2,20 +2,8 @@
#include <AL/al.h>
#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);