summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-08-30 23:56:05 -0500
committersanine <sanine.not@pm.me>2022-08-30 23:56:05 -0500
commit26952167e940e900cd0e1fa7452c4f163640cbe3 (patch)
tree3b55aa3978a56dabdf957f1ac0804e0b59c61934
parenteb4e4cab2d3f24ee7f8d0be7149162084fe98392 (diff)
add stereo panning
-rw-r--r--src/channel.c11
-rw-r--r--src/channel.test.c54
2 files changed, 60 insertions, 5 deletions
diff --git a/src/channel.c b/src/channel.c
index a29e7f7..d039701 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -106,8 +106,15 @@ void channel_get_next_sample(float *left, float *right, struct channel_t *chan)
float l, r;
l = chan->sound.left[chan->pos];
r = chan->sound.right[chan->pos];
- *left = volume * l;
- *right = volume * r;
+
+ 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));
}
chan->pos += 1;
diff --git a/src/channel.test.c b/src/channel.test.c
index 150adb9..789756d 100644
--- a/src/channel.test.c
+++ b/src/channel.test.c
@@ -385,15 +385,13 @@ void test_channel_get_next_sample_mono_panned()
float l, r;
- const float gain = 0.7071; /* constant-power panning center gain */
-
lily_store_value(mock_p_mutex_trylock, pboolean, TRUE);
channel_get_next_sample(&l, &r, &chan);
lily_assert_int_equal(mock_p_mutex_trylock->n_calls, 1);
lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 1);
lily_assert_int_equal(chan.pos, 1);
lily_assert_float_equal(l, 0.0f, 0.1f);
- lily_assert_float_equal(r, gain * 0.0f, 0.1f);
+ lily_assert_float_equal(r, 0.0f, 0.1f);
lily_store_value(mock_p_mutex_trylock, pboolean, TRUE);
channel_get_next_sample(&l, &r, &chan);
@@ -414,6 +412,55 @@ void test_channel_get_next_sample_mono_panned()
}
+void test_channel_get_next_sample_panned()
+{
+ lily_mock_use(&mock_p_mutex_trylock);
+ lily_mock_use(&mock_p_mutex_unlock);
+
+ struct channel_t chan;
+ chan.active = true;
+ chan.paused = false;
+ chan.volume = 255;
+ chan.pan_left = 128;
+ chan.pan_right = 0;
+ float audio_left[] = { 0.2, 0.5, 1.0 };
+ float audio_right[] = { 1.0, 0.5, 0.2 };
+ chan.sound.left = audio_left;
+ chan.sound.right = audio_right;
+ chan.sound.mono = false;
+ chan.sound.len = 3;
+ chan.pos = 0;
+
+ float l, r;
+ const float gain = 0.7071; /* constant-power panning center gain */
+
+ lily_store_value(mock_p_mutex_trylock, pboolean, TRUE);
+ channel_get_next_sample(&l, &r, &chan);
+ lily_assert_int_equal(mock_p_mutex_trylock->n_calls, 1);
+ lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 1);
+ lily_assert_int_equal(chan.pos, 1);
+ lily_assert_float_equal(l, gain * 1.0f, 0.1f);
+ lily_assert_float_equal(r, gain * 1.0f + 0.2f, 0.1f);
+
+ lily_store_value(mock_p_mutex_trylock, pboolean, TRUE);
+ channel_get_next_sample(&l, &r, &chan);
+ lily_assert_int_equal(mock_p_mutex_trylock->n_calls, 2);
+ lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 2);
+ lily_assert_int_equal(chan.pos, 2);
+ lily_assert_float_equal(l, gain * 0.5f, 0.1f);
+ lily_assert_float_equal(r, gain * 0.5f + 0.5f, 0.1f);
+
+ lily_store_value(mock_p_mutex_trylock, pboolean, TRUE);
+ channel_get_next_sample(&l, &r, &chan);
+ lily_assert_int_equal(mock_p_mutex_trylock->n_calls, 3);
+ lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 3);
+ lily_assert_int_equal(chan.pos, 0);
+ lily_assert_int_equal(chan.active, false);
+ lily_assert_float_equal(l, gain * 0.2f, 0.1f);
+ lily_assert_float_equal(r, gain * 0.2f + 1.0f, 0.1f);
+}
+
+
void suite_channel()
{
@@ -431,6 +478,7 @@ void suite_channel()
lily_run_test(test_channel_get_next_sample_volume_0);
lily_run_test(test_channel_get_next_sample_mono);
lily_run_test(test_channel_get_next_sample_mono_panned);
+ lily_run_test(test_channel_get_next_sample_panned);
lily_mock_destroy(mock_p_mutex_new);
}