summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/channel.c30
-rw-r--r--src/channel.h1
-rw-r--r--src/channel.test.c137
-rw-r--r--src/test/lily-test.c12
4 files changed, 174 insertions, 6 deletions
diff --git a/src/channel.c b/src/channel.c
index e6e6c3f..b9242c4 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -26,3 +26,33 @@ void channel_reset(struct channel_t *chan)
chan->pos = 0;
p_atomic_int_set(&(chan->active), false);
}
+
+
+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) {
+ /* skip this channel */
+ *left = 0;
+ *right = 0;
+ return;
+ }
+
+ if (!p_mutex_trylock(chan->sound_mutex)) {
+ /* can't lock mutex, skip */
+ *left = 0;
+ *right = 0;
+ return;
+ }
+
+ *left = chan->sound.left[chan->pos];
+ *right = chan->sound.right[chan->pos];
+ chan->pos += 1;
+
+ if (chan->pos >= chan->sound.len) {
+ channel_reset(chan);
+ }
+
+ p_mutex_unlock(chan->sound_mutex);
+}
diff --git a/src/channel.h b/src/channel.h
index 4d0800b..2bc45d2 100644
--- a/src/channel.h
+++ b/src/channel.h
@@ -21,6 +21,7 @@ struct channel_t {
void channel_init(struct channel_t *chan);
void channel_reset(struct channel_t *chan);
+void channel_get_next_sample(float *left, float *right, struct channel_t *chan);
#endif
diff --git a/src/channel.test.c b/src/channel.test.c
index e7f7e06..532d153 100644
--- a/src/channel.test.c
+++ b/src/channel.test.c
@@ -2,12 +2,18 @@
#include <plibsys.h>
PMutex * mock_p_mutex_new_();
+pboolean mock_p_mutex_trylock_();
+pboolean mock_p_mutex_unlock_();
#define p_mutex_new mock_p_mutex_new_
+#define p_mutex_trylock mock_p_mutex_trylock_
+#define p_mutex_unlock mock_p_mutex_unlock_
#include "channel.c"
#undef p_mutex_new
+/* ~~~~~~~~ mocks ~~~~~~~~ */
+
lily_mock_t *mock_p_mutex_new = NULL;
PMutex * mock_p_mutex_new_()
{
@@ -16,6 +22,26 @@ PMutex * mock_p_mutex_new_()
}
+lily_mock_t *mock_p_mutex_trylock = NULL;
+pboolean mock_p_mutex_trylock_(PMutex *m)
+{
+ mock_p_mutex_trylock->n_calls += 1;
+ pboolean result;
+ lily_get_value(mock_p_mutex_trylock, pboolean, &result);
+ return result;
+}
+
+
+lily_mock_t *mock_p_mutex_unlock = NULL;
+pboolean mock_p_mutex_unlock_(PMutex *m)
+{
+ mock_p_mutex_unlock->n_calls += 1;
+ return TRUE;
+}
+
+
+/* ~~~~~~~~ tests ~~~~~~~~ */
+
void test_channel_init()
{
lily_mock_use(&mock_p_mutex_new);
@@ -55,10 +81,121 @@ void test_channel_reset()
}
+void test_channel_get_next_sample_inactive()
+{
+ lily_mock_use(&mock_p_mutex_trylock);
+ lily_mock_use(&mock_p_mutex_unlock);
+
+ struct channel_t chan;
+ chan.active = false;
+ chan.pos = 0;
+ float l = 22; float r = 22;
+ channel_get_next_sample(&l, &r, &chan);
+
+ lily_assert_int_equal(mock_p_mutex_trylock->n_calls, 0);
+ lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 0);
+ lily_assert_int_equal(chan.pos, 0);
+ lily_assert_float_equal(l, 0.0f, 0.1f);
+ lily_assert_float_equal(r, 0.0f, 0.1f);
+}
+
+
+void test_channel_get_next_sample_paused()
+{
+ lily_mock_use(&mock_p_mutex_trylock);
+ lily_mock_use(&mock_p_mutex_unlock);
+
+ struct channel_t chan;
+ chan.active = true;
+ chan.paused = true;
+ chan.pos = 0;
+ float l = 22; float r = 22;
+ channel_get_next_sample(&l, &r, &chan);
+
+ lily_assert_int_equal(mock_p_mutex_trylock->n_calls, 0);
+ lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 0);
+ lily_assert_int_equal(chan.pos, 0);
+ lily_assert_float_equal(l, 0.0f, 0.1f);
+ lily_assert_float_equal(r, 0.0f, 0.1f);
+}
+
+
+void test_channel_get_next_sample_nolock()
+{
+ 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.pos = 0;
+ float l = 22; float r = 22;
+
+ lily_store_value(mock_p_mutex_trylock, pboolean, FALSE);
+ 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, 0);
+
+ lily_assert_int_equal(chan.pos, 0);
+ lily_assert_float_equal(l, 0.0f, 0.1f);
+ lily_assert_float_equal(r, 0.0f, 0.1f);
+}
+
+
+void test_channel_get_next_sample_normal()
+{
+ 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 = 0;
+ float audio_left[] = { 0.0, 0.5, 1.0 };
+ float audio_right[] = { 1.0, 0.5, 0.0 };
+ chan.sound.left = audio_left;
+ chan.sound.right = audio_right;
+ chan.sound.len = 3;
+ chan.pos = 0;
+
+ float l, r;
+
+ 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, 1.0f, 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, 0.5f, 0.1f);
+ lily_assert_float_equal(r, 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, 1.0f, 0.1f);
+ lily_assert_float_equal(r, 0.0f, 0.1f);
+}
+
+
void suite_channel()
{
lily_run_test(test_channel_init);
lily_run_test(test_channel_reset);
+ lily_run_test(test_channel_get_next_sample_inactive);
+ lily_run_test(test_channel_get_next_sample_paused);
+ lily_run_test(test_channel_get_next_sample_normal);
+ lily_run_test(test_channel_get_next_sample_nolock);
lily_mock_destroy(mock_p_mutex_new);
}
diff --git a/src/test/lily-test.c b/src/test/lily-test.c
index 2f43a28..a8381d0 100644
--- a/src/test/lily-test.c
+++ b/src/test/lily-test.c
@@ -209,7 +209,7 @@ void _lily_assert_int_not_equal(const char *name_a, const char *name_b,
void _lily_assert_float_equal(const char *name_a, const char *name_b,
double a, double b, double epsilon, const char *location)
{
- lily_assert_msg(abs(a - b) <= epsilon,
+ lily_assert_msg(abs(a - b) <= epsilon, location,
"%s (%f) is not equal to %s (%f) (epsilon: %f)",
name_a, a, name_b, b, epsilon);
}
@@ -218,7 +218,7 @@ void _lily_assert_float_equal(const char *name_a, const char *name_b,
void _lily_assert_float_not_equal(const char *name_a, const char *name_b,
double a, double b, double epsilon, const char *location)
{
- lily_assert_msg(abs(a - b) > epsilon,
+ lily_assert_msg(abs(a - b) > epsilon, location,
"%s (%f) is equal to %s (%f) (epsilon: %f)",
name_a, a, name_b, b, epsilon);
}
@@ -227,7 +227,7 @@ void _lily_assert_float_not_equal(const char *name_a, const char *name_b,
void _lily_assert_string_equal(const char *name_a, const char *name_b,
char *a, char *b, const char *location)
{
- lily_assert_msg(strcmp(a, b) == 0,
+ lily_assert_msg(strcmp(a, b) == 0, location,
"%s ('%s') is not equal to %s ('%s')",
name_a, a, name_b, b);
}
@@ -236,7 +236,7 @@ void _lily_assert_string_equal(const char *name_a, const char *name_b,
void _lily_assert_string_not_equal(const char *name_a, const char *name_b,
char *a, char *b, const char *location)
{
- lily_assert_msg(strcmp(a, b) != 0,
+ lily_assert_msg(strcmp(a, b) != 0, location,
"%s ('%s') is equal to %s",
name_a, a, name_b);
}
@@ -245,7 +245,7 @@ void _lily_assert_string_not_equal(const char *name_a, const char *name_b,
void _lily_assert_memory_equal(const char *name_a, const char *name_b,
void *a, void *b, size_t size, const char *location)
{
- lily_assert_msg(memcmp(a, b, size) == 0,
+ lily_assert_msg(memcmp(a, b, size) == 0, location,
"%s and %s contain different data", name_a, name_b);
}
@@ -253,7 +253,7 @@ void _lily_assert_memory_equal(const char *name_a, const char *name_b,
void _lily_assert_memory_not_equal(const char *name_a, const char *name_b,
void *a, void *b, size_t size, const char *location)
{
- lily_assert_msg(memcmp(a, b, size) == 0,
+ lily_assert_msg(memcmp(a, b, size) == 0, location,
"%s contains the same data s %s", name_a, name_b);
}