[Add] Sound System [Phase 1] Cleaned up and made a few fixed ready for [phase 2.]
This commit is contained in:
parent
65e25f6ce0
commit
6870dd2057
@ -128,6 +128,8 @@ int conf_loadConfig(const char* file) {
|
|||||||
conf_loadInt("afterburn", input_afterburnSensibility);
|
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||||
|
|
||||||
// Sound.
|
// Sound.
|
||||||
|
conf_loadBool("nosound", i);
|
||||||
|
nosound = i; i = 0;
|
||||||
conf_loadFloat("sound", d);
|
conf_loadFloat("sound", d);
|
||||||
if(d) { sound_volume(d); d = 0.; }
|
if(d) { sound_volume(d); d = 0.; }
|
||||||
conf_loadFloat("music", d);
|
conf_loadFloat("music", d);
|
||||||
|
@ -169,7 +169,6 @@ static int stream_loadBuffer(ALuint buffer) {
|
|||||||
// Init/Exit.
|
// Init/Exit.
|
||||||
int music_init(void) {
|
int music_init(void) {
|
||||||
music_vorbis_lock = SDL_CreateMutex();
|
music_vorbis_lock = SDL_CreateMutex();
|
||||||
music_find();
|
|
||||||
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
||||||
|
|
||||||
SDL_mutexP(sound_lock);
|
SDL_mutexP(sound_lock);
|
||||||
@ -185,6 +184,10 @@ int music_init(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int music_makeList(void) {
|
||||||
|
return music_find();
|
||||||
|
}
|
||||||
|
|
||||||
void music_exit(void) {
|
void music_exit(void) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ void music_kill(void);
|
|||||||
|
|
||||||
// Init/Exit.
|
// Init/Exit.
|
||||||
int music_init(void);
|
int music_init(void);
|
||||||
|
int music_makeList(void);
|
||||||
void music_exit(void);
|
void music_exit(void);
|
||||||
|
|
||||||
// Music control.
|
// Music control.
|
||||||
|
130
src/sound.c
130
src/sound.c
@ -18,6 +18,37 @@
|
|||||||
// right now.
|
// right now.
|
||||||
// ==============================================
|
// ==============================================
|
||||||
|
|
||||||
|
// ==============================================
|
||||||
|
// Sound Overview:
|
||||||
|
// ---------------
|
||||||
|
//
|
||||||
|
// We use a priority virtual voice system with
|
||||||
|
// pre-allocated buffers.
|
||||||
|
//
|
||||||
|
// Nameing:
|
||||||
|
// -- buffer - Sound sample.
|
||||||
|
// -- source - openal object that plays sound.
|
||||||
|
// -- voice - Virtual object that wants to play sound.
|
||||||
|
//
|
||||||
|
// First we allocate all the buffers based on what
|
||||||
|
// we find inside the datafile.
|
||||||
|
// Then we allocate all the possible sources (giving
|
||||||
|
// the music system what it needs).
|
||||||
|
// Now we allow the user to dynamically create
|
||||||
|
// voices, these voices will always try to grab
|
||||||
|
// a source from the source pool. If they can't,
|
||||||
|
// they will pretend to play the buffer.
|
||||||
|
// Every so often we'll check to see if the important
|
||||||
|
// voices are being played and take away the sources
|
||||||
|
// from the lesser ones.
|
||||||
|
// ==============================================
|
||||||
|
|
||||||
|
// Sound parameters - TODO: make it variable per source.
|
||||||
|
#define SOUND_ROLLOFF_FACTOR 1.
|
||||||
|
#define SOUND_REFERENCE_DIST 500.
|
||||||
|
#define SOUND_MAX_DIST 1000.
|
||||||
|
|
||||||
|
|
||||||
#define SOUND_PREFIX "../snd/sounds/"
|
#define SOUND_PREFIX "../snd/sounds/"
|
||||||
#define SOUND_SUFFIX ".wav"
|
#define SOUND_SUFFIX ".wav"
|
||||||
|
|
||||||
@ -29,6 +60,7 @@ typedef struct alSound_ {
|
|||||||
|
|
||||||
#define VOICE_PLAYING (1<<0) // Voice is playing.
|
#define VOICE_PLAYING (1<<0) // Voice is playing.
|
||||||
#define VOICE_LOOPING (1<<1) // Voice is looping.
|
#define VOICE_LOOPING (1<<1) // Voice is looping.
|
||||||
|
#define VOICE_DONE (1<<2) // 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)
|
||||||
|
|
||||||
@ -46,10 +78,18 @@ static SDL_Thread* music_player = NULL;
|
|||||||
static alSound* sound_list = NULL;
|
static alSound* sound_list = NULL;
|
||||||
static int nsound_list = 0;
|
static int nsound_list = 0;
|
||||||
|
|
||||||
// Current sources playing.
|
typedef struct VoiceSource_ {
|
||||||
|
ALuint source; // Allocated source.
|
||||||
|
ALuint voice; // Voice id.
|
||||||
|
} VoiceSource;
|
||||||
|
static VoiceSource* source_stack = NULL; // And it's stack.
|
||||||
|
static int source_nstack = 0;
|
||||||
|
|
||||||
|
// Virtual voice stack.
|
||||||
static alVoice** voice_stack = NULL;
|
static alVoice** voice_stack = NULL;
|
||||||
static int nvoice_stack = 0;
|
static int voice_nstack = 0;
|
||||||
static int mvoice_stack = 0;
|
static int voice_mstack = 0;
|
||||||
|
#define VOICE_CHUNK 64 // Allocate by these chunks.
|
||||||
|
|
||||||
// Volume.
|
// Volume.
|
||||||
static ALfloat svolume = 0.3;
|
static ALfloat svolume = 0.3;
|
||||||
@ -60,13 +100,16 @@ static void sound_free(alSound* snd);
|
|||||||
static int voice_getSource(alVoice* voc);
|
static int voice_getSource(alVoice* voc);
|
||||||
|
|
||||||
int sound_init(void) {
|
int sound_init(void) {
|
||||||
int ret = 0;
|
int mem, ret = 0;
|
||||||
|
ALenum err;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
// We'll need a mutex.
|
||||||
sound_lock = SDL_CreateMutex();
|
sound_lock = SDL_CreateMutex();
|
||||||
|
|
||||||
SDL_mutexP(sound_lock);
|
SDL_mutexP(sound_lock);
|
||||||
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||||
DEBUG("OpenAL using device '%s'", device);
|
|
||||||
// Open the default device.
|
// Open the default device.
|
||||||
al_device = alcOpenDevice(NULL);
|
al_device = alcOpenDevice(NULL);
|
||||||
if(al_device == NULL) {
|
if(al_device == NULL) {
|
||||||
@ -99,15 +142,43 @@ int sound_init(void) {
|
|||||||
// Set the distance model.
|
// Set the distance model.
|
||||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||||
|
|
||||||
|
// We can unlock now.
|
||||||
SDL_mutexV(sound_lock);
|
SDL_mutexV(sound_lock);
|
||||||
|
|
||||||
// Load up all the sounds.
|
|
||||||
sound_makeList();
|
|
||||||
|
|
||||||
// Start the music server.
|
// Start the music server.
|
||||||
music_init();
|
music_init();
|
||||||
music_player = SDL_CreateThread(music_thread, NULL);
|
music_player = SDL_CreateThread(music_thread, NULL);
|
||||||
|
|
||||||
|
// Start allocating the sources - music has already taken this.
|
||||||
|
alGetError(); // Another error clear.
|
||||||
|
mem = 0;
|
||||||
|
while(((err = alGetError()) == AL_NO_ERROR) && (source_nstack < 128)) {
|
||||||
|
if(mem < source_nstack+1) {
|
||||||
|
// Allocate more memory.
|
||||||
|
mem += 32;
|
||||||
|
source_stack = realloc(source_stack, sizeof(VoiceSource) * mem);
|
||||||
|
}
|
||||||
|
alGenSources(1, &source_stack[source_nstack].source);
|
||||||
|
source_stack[source_nstack].voice = 0;
|
||||||
|
source_nstack++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use minimal ram.
|
||||||
|
source_stack = realloc(source_stack, sizeof(VoiceSource) * source_nstack);
|
||||||
|
|
||||||
|
// Debug magic.
|
||||||
|
DEBUG("OpenAL: %s", device);
|
||||||
|
DEBUG("Sources: %d", source_nstack);
|
||||||
|
DEBUG("Renderer: %s", alGetString(AL_RENDERER));
|
||||||
|
DEBUG("Version: %s", alGetString(AL_VERSION));
|
||||||
|
|
||||||
|
// Load up all the sounds.
|
||||||
|
sound_makeList();
|
||||||
|
music_makeList(); // And music.
|
||||||
|
|
||||||
|
// Now start the music thread.
|
||||||
|
music_player = SDL_CreateThread(music_thread, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
snderr_act:
|
snderr_act:
|
||||||
@ -120,6 +191,7 @@ snderr_dev:
|
|||||||
SDL_mutexV(sound_lock);
|
SDL_mutexV(sound_lock);
|
||||||
SDL_DestroyMutex(sound_lock);
|
SDL_DestroyMutex(sound_lock);
|
||||||
sound_lock = NULL;
|
sound_lock = NULL;
|
||||||
|
ERR("Sound failed to initialize.");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +317,7 @@ static void sound_free(alSound* snd) {
|
|||||||
|
|
||||||
SDL_mutexP(sound_lock);
|
SDL_mutexP(sound_lock);
|
||||||
|
|
||||||
|
// Free the stuff.
|
||||||
if(snd->name) free(snd->name);
|
if(snd->name) free(snd->name);
|
||||||
alDeleteBuffers(1, &snd->buffer);
|
alDeleteBuffers(1, &snd->buffer);
|
||||||
|
|
||||||
@ -256,11 +329,9 @@ void sound_update(void) {
|
|||||||
if(sound_lock == NULL) return;
|
if(sound_lock == NULL) return;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// TODO: Prioritize the things.
|
|
||||||
|
|
||||||
SDL_mutexP(sound_lock);
|
SDL_mutexP(sound_lock);
|
||||||
|
|
||||||
for(i = 0; i < nvoice_stack; i++) {
|
for(i = 0; i < voice_nstack; i++) {
|
||||||
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
|
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
|
||||||
// Update position.
|
// Update position.
|
||||||
alSource3f(voice_stack[i]->source, AL_POSITION,
|
alSource3f(voice_stack[i]->source, AL_POSITION,
|
||||||
@ -282,7 +353,7 @@ void sound_volume(const double vol) {
|
|||||||
svolume = (ALfloat) vol;
|
svolume = (ALfloat) vol;
|
||||||
|
|
||||||
SDL_mutexP(sound_lock);
|
SDL_mutexP(sound_lock);
|
||||||
for(i = 0; i < nvoice_stack; i++)
|
for(i = 0; i < voice_nstack; i++)
|
||||||
if(voice_set(voice_stack[i], VOICE_PLAYING))
|
if(voice_set(voice_stack[i], VOICE_PLAYING))
|
||||||
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
|
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
|
||||||
SDL_mutexV(sound_lock);
|
SDL_mutexV(sound_lock);
|
||||||
@ -311,8 +382,9 @@ static int voice_getSource(alVoice* voc) {
|
|||||||
alSourcei(voc->source, AL_BUFFER, voc->buffer);
|
alSourcei(voc->source, AL_BUFFER, voc->buffer);
|
||||||
|
|
||||||
// Distance model.
|
// Distance model.
|
||||||
alSourcef(voc->source, AL_MAX_DISTANCE, 200.);
|
alSourcef(voc->source, AL_ROLLOFF_FACTOR, SOUND_ROLLOFF_FACTOR);
|
||||||
alSourcef(voc->source, AL_REFERENCE_DISTANCE, 50.);
|
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);
|
alSourcei(voc->source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||||
alSourcef(voc->source, AL_GAIN, svolume);
|
alSourcef(voc->source, AL_GAIN, svolume);
|
||||||
@ -339,23 +411,22 @@ alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy
|
|||||||
|
|
||||||
(void)vx;
|
(void)vx;
|
||||||
(void)vy;
|
(void)vy;
|
||||||
|
alVoice* voc;
|
||||||
|
|
||||||
if(sound_lock == NULL) return NULL;
|
if(sound_lock == NULL) return NULL;
|
||||||
|
|
||||||
alVoice* voc;
|
voice_nstack++;
|
||||||
|
if(voice_nstack > voice_mstack)
|
||||||
nvoice_stack++;
|
voice_stack = realloc(voice_stack, ++voice_mstack*sizeof(alVoice*));
|
||||||
if(nvoice_stack > mvoice_stack)
|
|
||||||
voice_stack = realloc(voice_stack, ++mvoice_stack*sizeof(alVoice*));
|
|
||||||
|
|
||||||
voc = malloc(sizeof(alVoice));
|
voc = malloc(sizeof(alVoice));
|
||||||
voice_stack[nvoice_stack-1] = voc;
|
voice_stack[voice_nstack-1] = voc;
|
||||||
|
|
||||||
// Set the data.
|
// Set the data.
|
||||||
voc->priority = priority;
|
voc->priority = priority;
|
||||||
voc->start = SDL_GetTicks();
|
voc->start = SDL_GetTicks();
|
||||||
voc->buffer = buffer;
|
voc->buffer = buffer;
|
||||||
if(looping) voice_set(voc, VOICE_LOOPING);
|
if(looping != 0) voice_set(voc, VOICE_LOOPING);
|
||||||
voc->px = px;
|
voc->px = px;
|
||||||
voc->py = py;
|
voc->py = py;
|
||||||
//voc->vx = vx;
|
//voc->vx = vx;
|
||||||
@ -371,21 +442,26 @@ void sound_delVoice(alVoice* voice) {
|
|||||||
ALint stat;
|
ALint stat;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < nvoice_stack; i++)
|
// Linear search.
|
||||||
|
for(i = 0; i < voice_nstack; i++)
|
||||||
if(voice == voice_stack[i])
|
if(voice == voice_stack[i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// No match found.
|
// No match found.
|
||||||
if(i >= nvoice_stack) {
|
if(i >= voice_nstack) {
|
||||||
WARN("Unable to find voice to free from stack");
|
WARN("Unable to find voice to free from stack");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Source must exist.
|
||||||
if(voice->source) {
|
if(voice->source) {
|
||||||
SDL_mutexP(sound_lock);
|
SDL_mutexP(sound_lock);
|
||||||
|
|
||||||
|
// Stop it if playing.
|
||||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||||
if(stat == AL_PLAYING) alSourceStop(voice->source);
|
if(stat == AL_PLAYING) alSourceStop(voice->source);
|
||||||
|
|
||||||
|
// Clear it and get rid of it.
|
||||||
alDeleteSources(1, &voice->source);
|
alDeleteSources(1, &voice->source);
|
||||||
voice->source = 0;
|
voice->source = 0;
|
||||||
|
|
||||||
@ -393,11 +469,12 @@ void sound_delVoice(alVoice* voice) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(voice_stack[i]);
|
free(voice_stack[i]);
|
||||||
nvoice_stack--;
|
voice_nstack--;
|
||||||
for(; i < nvoice_stack; i++)
|
for(; i < voice_nstack; i++)
|
||||||
voice_stack[i] = voice_stack[i+1];
|
voice_stack[i] = voice_stack[i+1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update voice position, should be run once per frame.
|
||||||
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) vx;
|
(void) vx;
|
||||||
(void) vy;
|
(void) vy;
|
||||||
@ -418,11 +495,12 @@ void sound_listener(double dir, double px, double py, double vx, double vy) {
|
|||||||
|
|
||||||
SDL_mutexP(sound_lock);
|
SDL_mutexP(sound_lock);
|
||||||
|
|
||||||
|
// Set orientation.
|
||||||
ALfloat ori[] = { 0., 0., 0., 0., 0., 1. };
|
ALfloat ori[] = { 0., 0., 0., 0., 0., 1. };
|
||||||
ori[0] = cos(dir);
|
ori[0] = cos(dir);
|
||||||
ori[1] = sin(dir);
|
ori[1] = sin(dir);
|
||||||
alListenerfv(AL_ORIENTATION, ori);
|
alListenerfv(AL_ORIENTATION, ori);
|
||||||
alListener3f(AL_POSITION, px, py, 0.);
|
alListener3f(AL_POSITION, px, py, 1.);
|
||||||
//alListener3f(AL_VELOCITY, vx, vy, 0.);
|
//alListener3f(AL_VELOCITY, vx, vy, 0.);
|
||||||
|
|
||||||
SDL_mutexV(sound_lock);
|
SDL_mutexV(sound_lock);
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include "physics.h"
|
#include "physics.h"
|
||||||
|
|
||||||
#define SOUND_REFERENCE_DIST 500.
|
|
||||||
#define SOUND_MAX_DIST 1000.
|
|
||||||
|
|
||||||
// Virtual voice.
|
// Virtual voice.
|
||||||
typedef struct alVoice_ {
|
typedef struct alVoice_ {
|
||||||
|
ALuint id; // Unique id for the voice.
|
||||||
ALuint source; // Source itself, 0 if not set.
|
ALuint source; // Source itself, 0 if not set.
|
||||||
ALuint buffer; // Buffer.
|
ALuint buffer; // Buffer.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user