diff options
| author | Joel de Vahl <joel@stalverk80.se> | 2007-10-02 16:19:25 +0000 |
|---|---|---|
| committer | Joel de Vahl <joel@stalverk80.se> | 2007-10-02 16:19:25 +0000 |
| commit | 21df126c88230f11749bc9241ed51a26d31f0810 (patch) | |
| tree | cb1975ea5c41e44f1361c96c4105c702cf865ae1 /src/engine/client/snd.c | |
| parent | 4bf60da04b668d10c53d5d3784ba3543c7a4d314 (diff) | |
| download | zcatch-21df126c88230f11749bc9241ed51a26d31f0810.tar.gz zcatch-21df126c88230f11749bc9241ed51a26d31f0810.zip | |
sound fixes and initial lock implementation
Diffstat (limited to 'src/engine/client/snd.c')
| -rw-r--r-- | src/engine/client/snd.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/src/engine/client/snd.c b/src/engine/client/snd.c index da18a3be..e11ace52 100644 --- a/src/engine/client/snd.c +++ b/src/engine/client/snd.c @@ -20,6 +20,8 @@ enum MAX_FRAMES = 1024 }; +static LOCK sound_lock = 0; + static struct sound { short *data; @@ -128,6 +130,7 @@ static inline void fill_stereo(int *out, unsigned frames, struct voice *v, float static void mix(short *out, unsigned frames) { static int main_buffer[MAX_FRAMES*2]; + unsigned locked = 0; dbg_assert(frames <= MAX_FRAMES, "too many frames to fill"); @@ -148,7 +151,9 @@ static void mix(short *out, unsigned frames) while(v) { unsigned filled = 0; - while(v->sound && filled < frames) + unsigned step = 1; + + while(v && v->sound && filled < frames) { // calculate maximum frames to fill unsigned frames_left = (v->sound->num_samples - v->tick) >> (v->sound->channels-1); @@ -214,6 +219,14 @@ static void mix(short *out, unsigned frames) v->stop -= to_fill; if(v->tick >= v->sound->num_samples || v->stop == 0) { + struct voice *vn = v->next; + if(!locked) + { + lock_wait(sound_lock); + locked = 1; + } + + if(v->next) v->next->prev = v->prev; @@ -225,15 +238,21 @@ static void mix(short *out, unsigned frames) dbg_msg("snd", "sound stopped"); reset_voice(v); + step = 0; + v = vn; } filled += to_fill; } - v = (struct voice*)v->next; + if(step) + v = (struct voice*)v->next; } } + if(locked) + lock_release(sound_lock); + // clamp accumulated values for(i = 0; i < frames; i++) { @@ -266,6 +285,8 @@ int snd_init() params.suggestedLatency = Pa_GetDeviceInfo(params.device)->defaultLowOutputLatency; params.hostApiSpecificStreamInfo = 0x0; + sound_lock = lock_create(); + err = Pa_OpenStream( &stream, /* passes back stream pointer */ 0, /* no input channels */ @@ -285,6 +306,8 @@ int snd_shutdown() Pa_StopStream(stream); Pa_Terminate(); + lock_destroy(sound_lock); + return 0; } @@ -547,9 +570,10 @@ int snd_load_wav(const char *filename) return sid; } -int snd_play(int cid, int sid, int loop, int x, int y) +int snd_play(int cid, int sid, int loop, float x, float y) { int vid; + dbg_msg("snd", "try adding sound"); for(vid = 0; vid < NUM_VOICES; vid++) { if(voices[vid].sound == 0x0) @@ -563,15 +587,18 @@ int snd_play(int cid, int sid, int loop, int x, int y) else voices[vid].loop = -1; - // add voice to channel last, to avoid threding errors + lock_wait(sound_lock); + dbg_msg("snd", "sound added"); voices[vid].next = channels[cid].first_voice; if(channels[cid].first_voice) channels[cid].first_voice->prev = &voices[vid]; channels[cid].first_voice = &voices[vid]; + lock_release(sound_lock); return vid; } } + dbg_msg("snd", "failed"); return -1; } @@ -585,3 +612,9 @@ void snd_stop(int vid) //TODO: lerp volume to 0 voices[vid].stop = 0; } + +void snd_set_listener_pos(float x, float y) +{ + center_x = x; + center_y = y; +} |