#include "test/mossrose-test.h" #include 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_() { mock_p_mutex_new->n_calls += 1; return 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); struct channel_t chan; channel_init(&chan); lily_assert_int_equal(mock_p_mutex_new->n_calls, 1); lily_assert_int_equal(chan.active, false); lily_assert_int_equal(chan.paused, false); lily_assert_int_equal(chan.volume, 255); lily_assert_int_equal(chan.pan_left, -128); lily_assert_int_equal(chan.pan_right, 128); lily_assert_null(chan.sound.left); lily_assert_null(chan.sound.right); lily_assert_int_equal(chan.pos, 0); } void test_channel_reset() { struct channel_t chan; chan.pos = 255; chan.active = true; chan.paused = true; chan.volume = 5; chan.pan_left = 30; chan.pan_right = 30; channel_reset(&chan); lily_assert_int_equal(chan.pos, 0); lily_assert_int_equal(chan.active, false); lily_assert_int_equal(chan.paused, false); lily_assert_int_equal(chan.volume, 255); lily_assert_int_equal(chan.pan_left, -128); lily_assert_int_equal(chan.pan_right, 128); } void test_channel_pause() { struct channel_t chan; chan.paused = false; channel_pause(&chan); lily_assert_int_equal(chan.paused, true); } void test_channel_resume() { struct channel_t chan; chan.paused = true; channel_resume(&chan); lily_assert_int_equal(chan.paused, false); } void test_channel_set_volume() { struct channel_t chan; chan.volume = 255; channel_set_volume(&chan, 0.0f); lily_assert_int_equal(chan.volume, 0); channel_set_volume(&chan, 0.5f); lily_assert_int_equal(chan.volume, 127); channel_set_volume(&chan, 1.0f); lily_assert_int_equal(chan.volume, 255); /* oob */ channel_set_volume(&chan, -1.0f); lily_assert_int_equal(chan.volume, 0); channel_set_volume(&chan, 2.0f); lily_assert_int_equal(chan.volume, 255); } void test_channel_set_pan() { struct channel_t chan; chan.pan_left = 255; chan.pan_right = 255; channel_set_pan(&chan, -1.0f, 1.0f); lily_assert_int_equal(chan.pan_left, -128); lily_assert_int_equal(chan.pan_right, 128); channel_set_pan(&chan, -0.5f, 0.5f); lily_assert_int_equal(chan.pan_left, -64); lily_assert_int_equal(chan.pan_right, 64); channel_set_pan(&chan, 0.0f, 0.0f); lily_assert_int_equal(chan.pan_left, 0); lily_assert_int_equal(chan.pan_right, 0); channel_set_pan(&chan, 0.5f, -0.5f); lily_assert_int_equal(chan.pan_left, 64); lily_assert_int_equal(chan.pan_right, -64); channel_set_pan(&chan, 1.0f, -1.0f); lily_assert_int_equal(chan.pan_left, 128); lily_assert_int_equal(chan.pan_right, -128); /* oob */ channel_set_pan(&chan, -10.0f, 2.0f); lily_assert_int_equal(chan.pan_left, -128); lily_assert_int_equal(chan.pan_right, 128); channel_set_pan(&chan, 2.0f, -10.0f); lily_assert_int_equal(chan.pan_left, 128); lily_assert_int_equal(chan.pan_right, -128); } /* get_next_sample tests */ 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_left = -128; chan.pan_right = 128; 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.mono = false; 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 test_channel_get_next_sample_volume_0() { 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 = 0; chan.pan_left = -128; chan.pan_right = 128; 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.mono = false; 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, 0.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.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); 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, 0.0f, 0.1f); lily_assert_float_equal(r, 0.0f, 0.1f); } void test_channel_get_next_sample_mono() { 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 = 0; chan.pan_right = 128; float audio[] = { 0.0, 0.5, 1.0 }; chan.sound.left = audio; chan.sound.right = NULL; chan.sound.mono = true; 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 * 0.0f, 0.1f); lily_assert_float_equal(r, gain * 0.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, gain * 0.5f, 0.1f); lily_assert_float_equal(r, gain * 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 * 1.0f, 0.1f); lily_assert_float_equal(r, gain * 1.0f, 0.1f); } void test_channel_get_next_sample_mono_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 = 128; float audio[] = { 0.0, 0.5, 1.0 }; chan.sound.left = audio; chan.sound.right = NULL; chan.sound.mono = true; 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, 0.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.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, 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 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() { lily_run_test(test_channel_init); lily_run_test(test_channel_reset); lily_run_test(test_channel_pause); lily_run_test(test_channel_resume); lily_run_test(test_channel_set_volume); lily_run_test(test_channel_set_pan); 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_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); }