summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-09-03 21:32:25 -0500
committersanine <sanine.not@pm.me>2022-09-03 21:32:25 -0500
commit2cf000fb7cbe653c2e96e0b3b8f3c1425401d3fc (patch)
treee172ef67b253d1eaa0fb22186b5901edd4de793a /src
parenta416cfb6881b8ff99c29ba87c1d940d6143e44b1 (diff)
add looping
Diffstat (limited to 'src')
-rw-r--r--src/channel.c10
-rw-r--r--src/channel.h3
-rw-r--r--src/channel.test.c56
-rw-r--r--src/mossrose.c7
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;
}