summaryrefslogtreecommitdiff
path: root/src/channel.c
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-09-03 18:17:53 -0500
committersanine <sanine.not@pm.me>2022-09-03 18:17:53 -0500
commita416cfb6881b8ff99c29ba87c1d940d6143e44b1 (patch)
treea6fc26bed9f1efb34f19d8709569dc40d17366a2 /src/channel.c
parentd3ffd2e969b078a04fea2a5a5eb9cc7f26963917 (diff)
only perform atomic operations at the beginning of a callback run
Diffstat (limited to 'src/channel.c')
-rw-r--r--src/channel.c87
1 files changed, 48 insertions, 39 deletions
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;