diff options
author | sanine <sanine.not@pm.me> | 2022-09-03 21:32:25 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-09-03 21:32:25 -0500 |
commit | 2cf000fb7cbe653c2e96e0b3b8f3c1425401d3fc (patch) | |
tree | e172ef67b253d1eaa0fb22186b5901edd4de793a /src | |
parent | a416cfb6881b8ff99c29ba87c1d940d6143e44b1 (diff) |
add looping
Diffstat (limited to 'src')
-rw-r--r-- | src/channel.c | 10 | ||||
-rw-r--r-- | src/channel.h | 3 | ||||
-rw-r--r-- | src/channel.test.c | 56 | ||||
-rw-r--r-- | src/mossrose.c | 7 |
4 files changed, 58 insertions, 18 deletions
diff --git a/src/channel.c b/src/channel.c index 1d0b63b..8615265 100644 --- a/src/channel.c +++ b/src/channel.c @@ -25,7 +25,12 @@ void channel_init(struct channel_t *chan) void channel_reset(struct channel_t *chan) { - p_atomic_int_set(&(chan->shared.active), false); + chan->pos = 0; + int loops = channel_atomic_get(chan->shared.loops); + if (loops) { + if (p_atomic_int_dec_and_test(&(chan->shared.loops))) + channel_atomic_set(chan->shared.active, false); + } } @@ -63,7 +68,7 @@ void channel_set_pan(struct channel_t *chan, float pan_left, float pan_right) } -int channel_sound_load(struct channel_t *chan, struct mossrose_sound_t *sound, bool force) +int channel_sound_load(struct channel_t *chan, struct mossrose_sound_t *sound, bool force, int loops) { if (!force && channel_atomic_get(chan->shared.active)) /* active, fail! */ @@ -74,6 +79,7 @@ int channel_sound_load(struct channel_t *chan, struct mossrose_sound_t *sound, b chan->pos = 0; p_atomic_int_set(&(chan->shared.paused), false); + p_atomic_int_set(&(chan->shared.loops), loops); if (!force) { /* overwrite channel settings */ diff --git a/src/channel.h b/src/channel.h index ae9c24b..5be42a2 100644 --- a/src/channel.h +++ b/src/channel.h @@ -13,6 +13,7 @@ struct channel_shared_t { volatile pint volume; /* 0-255 */ volatile pint pan_left; /* -255-255 */ volatile pint pan_right; /* -255-255 */ + volatile pint loops; }; @@ -34,7 +35,7 @@ void channel_pause(struct channel_t *chan); void channel_resume(struct channel_t *chan); void channel_set_volume(struct channel_t *chan, float volume); void channel_set_pan(struct channel_t *chan, float pan_left, float pan_right); -int channel_sound_load(struct channel_t *chan, struct mossrose_sound_t *sound, bool force); +int channel_sound_load(struct channel_t *chan, struct mossrose_sound_t *sound, bool force, int loops); void channel_get_next_sample(float *left, float *right, struct channel_t *chan); diff --git a/src/channel.test.c b/src/channel.test.c index 4591b43..067879f 100644 --- a/src/channel.test.c +++ b/src/channel.test.c @@ -71,15 +71,11 @@ void test_channel_init() } -void test_channel_reset() +void test_channel_reset_last_loop() { struct channel_t chan; - chan.pos = 255; chan.shared.active = true; - chan.shared.paused = true; - chan.shared.volume = 5; - chan.shared.pan_left = 30; - chan.shared.pan_right = 30; + chan.shared.loops = 1; channel_reset(&chan); @@ -87,6 +83,36 @@ void test_channel_reset() } +void test_channel_reset_penultimate_loop() +{ + struct channel_t chan; + chan.shared.active = true; + chan.shared.loops = 2; + chan.pos = 98; + + channel_reset(&chan); + + lily_assert_int_equal(chan.shared.active, true); + lily_assert_int_equal(chan.shared.loops, 1); + lily_assert_int_equal(chan.pos, 0); +} + + +void test_channel_reset_infinite_loop() +{ + struct channel_t chan; + chan.shared.active = true; + chan.shared.loops = 0; + chan.pos = 17; + + channel_reset(&chan); + + lily_assert_int_equal(chan.shared.active, true); + lily_assert_int_equal(chan.shared.loops, 0); + lily_assert_int_equal(chan.pos, 0); +} + + void test_channel_pause() { struct channel_t chan; @@ -180,7 +206,7 @@ void test_channel_sound_load() chan.sound.right = NULL; chan.pos = 5; - int result = channel_sound_load(&chan, &sound, false); + int result = channel_sound_load(&chan, &sound, false, 1); lily_assert_int_equal(mock_p_mutex_lock->n_calls, 1); lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 1); @@ -216,7 +242,7 @@ void test_channel_sound_load_mono() chan.sound.left = NULL; chan.sound.right = NULL; - int result = channel_sound_load(&chan, &sound, false); + int result = channel_sound_load(&chan, &sound, false, 1); lily_assert_int_equal(mock_p_mutex_lock->n_calls, 1); lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 1); @@ -256,7 +282,7 @@ void test_channel_sound_load_preserve() chan.shared.pan_left = 0; chan.shared.pan_right = 64; - int result = channel_sound_load(&chan, &sound, true); + int result = channel_sound_load(&chan, &sound, true, 1); lily_assert_int_equal(mock_p_mutex_lock->n_calls, 1); lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 1); @@ -299,7 +325,7 @@ void test_channel_sound_fail() chan.sound.mono = true; chan.pos = 6; - int result = channel_sound_load(&chan, &sound, false); + int result = channel_sound_load(&chan, &sound, false, 1); lily_assert_int_equal(mock_p_mutex_lock->n_calls, 0); lily_assert_int_equal(mock_p_mutex_unlock->n_calls, 0); @@ -391,6 +417,7 @@ void test_channel_get_next_sample_normal() struct channel_t chan; chan.shared.active = true; chan.shared.paused = false; + chan.shared.loops = 1; chan.shared.volume = 255; chan.shared.pan_left = -128; chan.shared.pan_right = 128; @@ -441,6 +468,7 @@ void test_channel_get_next_sample_volume_0() struct channel_t chan; chan.shared.active = true; chan.shared.paused = false; + chan.shared.loops = 1; chan.shared.volume = 0; chan.shared.pan_left = -128; chan.shared.pan_right = 128; @@ -491,6 +519,7 @@ void test_channel_get_next_sample_mono() struct channel_t chan; chan.shared.active = true; chan.shared.paused = false; + chan.shared.loops = 1; chan.shared.volume = 255; chan.shared.pan_left = 0; chan.shared.pan_right = 128; @@ -542,6 +571,7 @@ void test_channel_get_next_sample_mono_panned() struct channel_t chan; chan.shared.active = true; chan.shared.paused = false; + chan.shared.loops = 1; chan.shared.volume = 255; chan.shared.pan_left = -128; chan.shared.pan_right = 128; @@ -591,6 +621,7 @@ void test_channel_get_next_sample_panned() struct channel_t chan; chan.shared.active = true; chan.shared.paused = false; + chan.shared.loops = 1; chan.shared.volume = 255; chan.shared.pan_left = 128; chan.shared.pan_right = 0; @@ -638,12 +669,15 @@ void test_channel_get_next_sample_panned() 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_reset_last_loop); + lily_run_test(test_channel_reset_penultimate_loop); + lily_run_test(test_channel_reset_infinite_loop); + lily_run_test(test_channel_sound_load); lily_run_test(test_channel_sound_load_mono); lily_run_test(test_channel_sound_load_preserve); diff --git a/src/mossrose.c b/src/mossrose.c index 04770f5..cd1b98d 100644 --- a/src/mossrose.c +++ b/src/mossrose.c @@ -21,7 +21,6 @@ static int callback( PaStreamCallbackFlags status_flags, void *user_data) { - printf("frame count: %d\n", frame_count); float *out = output; float *left, *right; float l, r; @@ -88,11 +87,11 @@ int mossrose_init(double sample_rate, int n_channels, bool init_plibsys) }; -int mossrose_play(struct mossrose_sound_t *sound, int channel) +int mossrose_play(struct mossrose_sound_t *sound, int channel, int loops) { if (channel >= 0) { /* play on specified channel */ - if (channel_sound_load(mossrose_global.channels + channel, sound, true) == 0) + if (channel_sound_load(mossrose_global.channels + channel, sound, true, loops) == 0) return channel; else return -1; @@ -101,7 +100,7 @@ int mossrose_play(struct mossrose_sound_t *sound, int channel) /* play on first available channel */ for (int i=0; i<mossrose_global.n_channels; i++) { struct channel_t *chan = mossrose_global.channels + i; - if (channel_sound_load(chan, sound, false) == 0) return i; + if (channel_sound_load(chan, sound, false, loops) == 0) return i; } return -1; } |