[Fix] Some sound cleanup and fixed potential bugs.

This commit is contained in:
Allanis 2013-06-04 19:43:39 +01:00
parent 7fc15f650c
commit 7f74fbfff4
4 changed files with 101 additions and 43 deletions

View File

@ -31,7 +31,6 @@ typedef enum DamageType_ {
DAMAGE_TYPE_NULL = 0, DAMAGE_TYPE_NULL = 0,
DAMAGE_TYPE_ENERGY = 1, DAMAGE_TYPE_ENERGY = 1,
DAMAGE_TYPE_KINETIC = 2 DAMAGE_TYPE_KINETIC = 2
} DamageType; } DamageType;
// An outfit depends a lot on the type. // An outfit depends a lot on the type.

View File

@ -58,9 +58,9 @@ typedef struct alSound_ {
ALuint buffer; // Associated OpenAL buffer. ALuint buffer; // Associated OpenAL buffer.
} alSound; } alSound;
#define VOICE_PLAYING (1<<0) // Voice is playing. // Voice private flags (public in sound.h).
#define VOICE_LOOPING (1<<1) // Voice is looping. #define VOICE_PLAYING (1<<0) // Voice is playing.
#define VOICE_DONE (1<<2) // Voice is done - must remove. #define VOICE_DONE (1<<1) // Voice is done - must remove.
#define voice_set(v,f) ((v)->flags |= f) #define voice_set(v,f) ((v)->flags |= f)
#define voice_is(v,f) ((v)->flags & f) #define voice_is(v,f) ((v)->flags & f)
@ -71,7 +71,7 @@ SDL_mutex* sound_lock = NULL;
static ALCcontext* al_context = NULL; static ALCcontext* al_context = NULL;
static ALCdevice* al_device = NULL; static ALCdevice* al_device = NULL;
// Music player thread to assure streaming is perfect. // Threads.
static SDL_Thread* music_player = NULL; static SDL_Thread* music_player = NULL;
// List of sounds available (All preloaded into a buffer). // List of sounds available (All preloaded into a buffer).
@ -109,7 +109,10 @@ static int sound_makeList(void);
static int sound_load(ALuint* buffer, char* filename); static int sound_load(ALuint* buffer, char* filename);
static void sound_free(alSound* snd); static void sound_free(alSound* snd);
static int voice_getSource(alVoice* voc); static int voice_getSource(alVoice* voc);
static void voice_init(alVoice* voice);
static int voice_play(alVoice* voice);
static void voice_rm(alVoice* prev, alVoice* voice); static void voice_rm(alVoice* prev, alVoice* voice);
static void voice_parseFlags(alVoice* voice, const int flags);
int sound_init(void) { int sound_init(void) {
int mem, ret = 0; int mem, ret = 0;
@ -354,6 +357,7 @@ static void sound_free(alSound* snd) {
// Update the sounds and prioritize them. // Update the sounds and prioritize them.
void sound_update(void) { void sound_update(void) {
ALint stat;
alVoice* voice, *prev, *next; alVoice* voice, *prev, *next;
if(sound_lock == NULL) return; // Sound system is off. if(sound_lock == NULL) return; // Sound system is off.
@ -367,11 +371,16 @@ void sound_update(void) {
do { do {
next = voice->next; next = voice->next;
if(!voice_is(voice, VOICE_DONE)) { // Still working. if(!voice_is(voice, VOICE_DONE)) { // Still working.
// Update position. // Voice has a source.
alSource3f(voice->source, AL_POSITION, if(voice->source != 0) {
voice->px, voice->py, 0.); alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
/*alSource3f(voice->source, AL_VELOCITY,
voice->vx, voice->vy, 0.);*/ alSource3f(voice->source, AL_POSITION,
voice->px, voice->py, 0.);
/*alSource3f(voice->source, AL_VELOCITY,
voice->vx, voice->vy, 0.);*/
}
prev = voice; // Only case where voice will stay. prev = voice; // Only case where voice will stay.
} else // Delete them. } else // Delete them.
voice_rm(prev, voice); voice_rm(prev, voice);
@ -413,9 +422,10 @@ void sound_volume(const double vol) {
// Attempt to alloc a source for a voice. // Attempt to alloc a source for a voice.
static int voice_getSource(alVoice* voc) { static int voice_getSource(alVoice* voc) {
if(sound_lock == NULL) return -1;
int ret; int ret;
ALenum err;
// Sound system isn't on.
if(sound_lock == NULL) return -1;
ret = 0; // Default return. ret = 0; // Default return.
@ -426,28 +436,9 @@ static int voice_getSource(alVoice* voc) {
// We must pull it from the free source vector. // We must pull it from the free source vector.
voc->source = source_stack[--source_nstack]; voc->source = source_stack[--source_nstack];
// Set the properties. // Initialize and play.
alSourcei(voc->source, AL_BUFFER, voc->buffer); voice_init(voc);
ret = voice_play(voc);
// Distance model.
alSourcef(voc->source, AL_ROLLOFF_FACTOR, SOUND_ROLLOFF_FACTOR);
alSourcef(voc->source, AL_MAX_DISTANCE, SOUND_MAX_DIST);
alSourcef(voc->source, AL_REFERENCE_DISTANCE, SOUND_REFERENCE_DIST);
alSourcei(voc->source, AL_SOURCE_RELATIVE, AL_FALSE);
alSourcef(voc->source, AL_GAIN, svolume);
alSource3f(voc->source, AL_POSITION, voc->px, voc->py, 0.);
//alSource3f(voc->source, AL_VELOCITY, voc->vx, voc->vy, 0.);
if(voice_is(voc, VOICE_LOOPING))
alSourcei(voc->source, AL_LOOPING, AL_TRUE);
else
alSourcei(voc->source, AL_LOOPING, AL_FALSE);
// Try to play the source.
alSourcePlay(voc->source);
err = alGetError();
if(err == AL_NO_ERROR) voice_set(voc, VOICE_PLAYING);
else ret = 2;
} else } else
voc->source = 0; voc->source = 0;
SDL_mutexV(sound_lock); SDL_mutexV(sound_lock);
@ -455,8 +446,26 @@ static int voice_getSource(alVoice* voc) {
return ret; return ret;
} }
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy, // Must lock becore calling.
const ALuint buffer, const int looping) { static void voice_init(alVoice* voice) {
// Distance model.
alSourcef(voice->source, AL_ROLLOFF_FACTOR, SOUND_ROLLOFF_FACTOR);
alSourcef(voice->source, AL_MAX_DISTANCE, SOUN_MAX_DIST);
alSourcef(voice->source, AL_REFERENCE_DISTANCE, SOUND_REFERENCE_DIST);
alSourcei(voice->source, AL_SOURCE_RELATIVE, AL_FALSE);
alSourcef(voice->source, AL_GAIN, svolume);
alSource3f(voice->source, AL_POSITION, voice->px, voice->py, 0.);
//alSource3f(voice->source, AL_VELOCITY, voice->vx, voice->vy, 0.);
if(voice_is(voice, VOICE_LOOPING))
alSourcei(voice->source, AL_LOOPING, AL_TRUE);
else
alSourcei(voice->source, AL_LOOPING, AL_FALSE);
}
// Create a dynamic moving piece.
alVoice* sound_addVoice(int priority, double px, double py,
double vx, double vy, const ALuint buffer, const int flags) {
(void)vx; (void)vx;
(void)vy; (void)vy;
@ -472,13 +481,17 @@ alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy
voc->priority = priority; voc->priority = priority;
voc->start = SDL_GetTicks(); voc->start = SDL_GetTicks();
voc->buffer = buffer; voc->buffer = buffer;
voc->flags = 0;
if(looping != 0) voice_set(voc, VOICE_LOOPING); // Handle positions.
voc->px = px; voc->px = px;
voc->py = py; voc->py = py;
//voc->vx = vx; //voc->vx = vx;
//voc->vy = vy; //voc->vy = vy;
// Handle the flags.
voice_parseFlags(voc, flags);
// Get the source.
voice_getSource(voc); voice_getSource(voc);
if(voice_start == NULL) { if(voice_start == NULL) {
@ -512,6 +525,45 @@ void voice_update(alVoice* voice, double px, double py, double vx, double vy) {
//voice->vy = vy; //voice->vy = vy;
} }
// Changes the voice's buffer.
void voice_buffer(alVoice* voice, const ALuint buffer, const int flags) {
voice->buffer = buffer;
voice_parseFlags(voice, flags);
// Start playing.
SDL_mutexP(sound_lock);
voice_play(voice);
SDL_mutexV(sound_lock);
}
// Handle flags.
static void voice_parseFlags(alVoice* voice, const int flags) {
voice->flags = 0; // Defaults.
// Looping.
if(flags & VOICE_LOOPING)
voice_set(voice, VOICE_LOOPING);
}
// Make a voice play. Must lock before calling.
static int voice_play(alVoice* voice) {
ALenum err;
// Must have buffer.
if(voice->buffer != 0) {
// Set buffer.
alSourcei(voice->source, AL_BUFFER, voice->buffer);
// Try to play the source.
alSourcePlay(voice->source);
err = alGetError();
if(err == AL_NO_ERROR) voice_set(voice, VOICE_PLAYING);
else return 2;
}
return 0;
}
void sound_listener(double dir, double px, double py, double vx, double vy) { void sound_listener(double dir, double px, double py, double vx, double vy) {
(void)vx; (void)vx;
(void)vy; (void)vy;

View File

@ -2,6 +2,8 @@
#include <AL/al.h> #include <AL/al.h>
#include "physics.h" #include "physics.h"
#define VOICE_LOOPING (1<<10)
struct alVoice; struct alVoice;
typedef struct alVoice alVoice; typedef struct alVoice alVoice;
@ -15,10 +17,14 @@ ALuint sound_get(char* name);
void sound_volume(const double vol); void sound_volume(const double vol);
// Voice manipulation function. // Voice manipulation function.
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy, alVoice* sound_addVoice(int priority, double px, double py,
const ALuint buffer, const int looping); double vx, double vy, const ALuint buffer, const int flags);
void sound_delVoice(alVoice(alVoice* voice); // Delete voice.
void sound_delVoice(alVoice* voice);
void voice_update(alVoice* voice, double px, double py, double vx, double vy); void voice_update(alVoice* voice, double px, double py, double vx, double vy);
void voice_buffer(alVoice* voice, const ALuint buffer, const int flags);
// Listener manipulation.
void sound_listener(double dir, double px, double py, double vx, double vy); void sound_listener(double dir, double px, double py, double vx, double vy);

View File

@ -15,8 +15,9 @@
#define weapon_isSmart(w) (w->think) #define weapon_isSmart(w) (w->think)
#define VOICE_PRIORITY_BOLT 10 // Default. #define VOICE_PRIORITY_BOLT 10 // Default.
#define VOICE_PRIORITY_AMMO 8 // Higher. #define VOICE_PRIORITY_AMMO 8 // Higher.
#define VOICE_PRIORITY_BEAM 6 // Even higher.
#define WEAPON_CHUNK 32 #define WEAPON_CHUNK 32