From a416cfb6881b8ff99c29ba87c1d940d6143e44b1 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 3 Sep 2022 18:17:53 -0500 Subject: only perform atomic operations at the beginning of a callback run --- src/channel.c | 87 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 39 deletions(-) (limited to 'src/channel.c') diff --git a/src/channel.c b/src/channel.c index 62e32fc..1d0b63b 100644 --- a/src/channel.c +++ b/src/channel.c @@ -5,14 +5,16 @@ #include "channel.h" #include "sound.h" +#define channel_atomic_get(var) p_atomic_int_get(&(var)) +#define channel_atomic_set(var, value) p_atomic_int_set(&(var), (value)) void channel_init(struct channel_t *chan) { - chan->active = false; - chan->paused = false; - chan->volume = 255; - chan->pan_left = -128; - chan->pan_right = 128; + chan->shared.active = false; + chan->shared.paused = false; + chan->shared.volume = 255; + chan->shared.pan_left = -128; + chan->shared.pan_right = 128; chan->sound_mutex = p_mutex_new(); chan->sound.left = NULL; @@ -23,21 +25,19 @@ void channel_init(struct channel_t *chan) void channel_reset(struct channel_t *chan) { - p_atomic_int_set(&(chan->paused), false); - chan->pos = 0; - p_atomic_int_set(&(chan->active), false); + p_atomic_int_set(&(chan->shared.active), false); } void channel_pause(struct channel_t *chan) { - p_atomic_int_set(&(chan->paused), true); + p_atomic_int_set(&(chan->shared.paused), true); } void channel_resume(struct channel_t *chan) { - p_atomic_int_set(&(chan->paused), false); + p_atomic_int_set(&(chan->shared.paused), false); } @@ -46,7 +46,7 @@ void channel_set_volume(struct channel_t *chan, float volume) if (volume > 1.0f) volume = 1.0f; if (volume < 0.0f) volume = 0.0f; - p_atomic_int_set(&(chan->volume), 255*volume); + p_atomic_int_set(&(chan->shared.volume), 255*volume); } @@ -58,14 +58,14 @@ void channel_set_pan(struct channel_t *chan, float pan_left, float pan_right) if (pan_right > 1.0f) pan_right = 1.0f; if (pan_right < -1.0f) pan_right = -1.0f; - p_atomic_int_set(&(chan->pan_left), 128*pan_left); - p_atomic_int_set(&(chan->pan_right), 128*pan_right); + p_atomic_int_set(&(chan->shared.pan_left), 128*pan_left); + p_atomic_int_set(&(chan->shared.pan_right), 128*pan_right); } int channel_sound_load(struct channel_t *chan, struct mossrose_sound_t *sound, bool force) { - if (!force && p_atomic_int_get(&(chan->active))) + if (!force && channel_atomic_get(chan->shared.active)) /* active, fail! */ return 1; @@ -73,24 +73,24 @@ int channel_sound_load(struct channel_t *chan, struct mossrose_sound_t *sound, b sound_copy(&(chan->sound), sound); chan->pos = 0; - p_atomic_int_set(&(chan->paused), false); + p_atomic_int_set(&(chan->shared.paused), false); if (!force) { /* overwrite channel settings */ - p_atomic_int_set(&(chan->volume), 255); + p_atomic_int_set(&(chan->shared.volume), 255); if (sound->mono) { - p_atomic_int_set(&(chan->pan_left), 0); - p_atomic_int_set(&(chan->pan_right), 0); + p_atomic_int_set(&(chan->shared.pan_left), 0); + p_atomic_int_set(&(chan->shared.pan_right), 0); } else { /* stereo */ - p_atomic_int_set(&(chan->pan_left), -128); - p_atomic_int_set(&(chan->pan_right), 128); + p_atomic_int_set(&(chan->shared.pan_left), -128); + p_atomic_int_set(&(chan->shared.pan_right), 128); } } p_mutex_unlock(chan->sound_mutex); - p_atomic_int_set(&(chan->active), true); + p_atomic_int_set(&(chan->shared.active), true); return 0; } @@ -104,11 +104,31 @@ static void pan_gain(float *gain_l, float *gain_r, float pan) } +void channel_update_shared(struct channel_t *chan) +{ + if (channel_atomic_get(chan->shared.paused) || !channel_atomic_get(chan->shared.active)) + chan->skip = true; + else + chan->skip = false; + + float vol = ((float)channel_atomic_get(chan->shared.volume))/255; + + float pan_l = ((float)channel_atomic_get(chan->shared.pan_left))/128; + float pan_r = ((float)channel_atomic_get(chan->shared.pan_right))/128; + + pan_gain(&(chan->gain_ll), &(chan->gain_lr), pan_l); + pan_gain(&(chan->gain_rl), &(chan->gain_rr), pan_r); + + chan->gain_ll *= vol; + chan->gain_lr *= vol; + chan->gain_rl *= vol; + chan->gain_rr *= vol; +} + + void channel_get_next_sample(float *left, float *right, struct channel_t *chan) { - bool active = p_atomic_int_get(&(chan->active)); - bool paused = p_atomic_int_get(&(chan->paused)); - if (!active || paused) { + if (chan->skip) { /* skip this channel */ *left = 0; *right = 0; @@ -122,29 +142,18 @@ void channel_get_next_sample(float *left, float *right, struct channel_t *chan) return; } - float volume = ((float)p_atomic_int_get(&(chan->volume)))/255; - if (chan->sound.mono) { float x = chan->sound.left[chan->pos]; - float pan = ((float)p_atomic_int_get(&(chan->pan_left)))/128; - float gain_l, gain_r; - pan_gain(&gain_l, &gain_r, pan); - *left = volume * gain_l * x; - *right = volume * gain_r * x; + *left = chan->gain_ll * x; + *right = chan->gain_lr * x; } else { float l, r; l = chan->sound.left[chan->pos]; r = chan->sound.right[chan->pos]; - float pan_l = ((float)p_atomic_int_get(&(chan->pan_left)))/128; - float pan_r = ((float)p_atomic_int_get(&(chan->pan_right)))/128; - float gain_ll, gain_lr, gain_rl, gain_rr; - pan_gain(&gain_ll, &gain_lr, pan_l); - pan_gain(&gain_rl, &gain_rr, pan_r); - - *left = volume * ((gain_ll * l) + (gain_rl * r)); - *right = volume * ((gain_lr * l) + (gain_rr * r)); + *left = (chan->gain_ll * l) + (chan->gain_rl * r); + *right = (chan->gain_lr * l) + (chan->gain_rr * r); } chan->pos += 1; -- cgit v1.2.1