summaryrefslogtreecommitdiff
path: root/src/channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/channel.c')
-rw-r--r--src/channel.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/channel.c b/src/channel.c
new file mode 100644
index 0000000..169b245
--- /dev/null
+++ b/src/channel.c
@@ -0,0 +1,85 @@
+#include <stdlib.h>
+#include <string.h>
+#include "mutex.h"
+#include "channel.h"
+
+
+void mossrose_channel_init(struct mossrose_channel_t *chan)
+{
+ mossrose_mutex_init(&(chan->mutex));
+ chan->left = NULL;
+ chan->right = NULL;
+ chan->n_samples = 0;
+ chan->pos = 0;
+}
+
+
+int mossrose_channel_set(struct mossrose_channel_t *chan, float *left, float *right, size_t len, int force)
+{
+ int result = 0;
+ mossrose_mutex_lock(&(chan->mutex));
+ if (chan->n_samples != 0 && !force) {
+ /* channel is still playing! */
+ result = 1; goto unlock;
+ }
+
+ chan->n_samples = len;
+ chan->pos = 0;
+
+ /* left channel */
+ if (chan->left != NULL) free(chan->left);
+ if (left == NULL)
+ chan->left = NULL;
+ else {
+ chan->left = malloc(len * sizeof(float));
+ if (chan->left == NULL) { result = 2; goto unlock; }
+ memcpy(chan->left, left, len * sizeof(float));
+ }
+
+ /* right channel */
+ if (chan->right != NULL) free(chan->right);
+ if (right == NULL)
+ chan->right = NULL;
+ else {
+ chan->right = malloc(len * sizeof(float));
+ if (chan->right == NULL) { result = 3; goto unlock; }
+ memcpy(chan->right, right, len * sizeof(float));
+ }
+
+ unlock:
+ mossrose_mutex_unlock(&(chan->mutex));
+ return result;
+}
+
+
+void mossrose_channel_reset(struct mossrose_channel_t *chan)
+{
+ chan->n_samples = 0;
+ chan->pos = 0;
+}
+
+
+int mossrose_channel_advance(float *left, float *right, struct mossrose_channel_t *chan)
+{
+ if (chan->pos >= chan->n_samples) return 1;
+ if (chan->left != NULL)
+ *left = chan->left[chan->pos];
+ else
+ *left = 0;
+ if (chan->right != NULL)
+ *right = chan->right[chan->pos];
+ else
+ *right = 0;
+ chan->pos += 1;
+ return 0;
+}
+
+
+void mossrose_channel_destroy(struct mossrose_channel_t *chan)
+{
+ mossrose_mutex_destroy(&(chan->mutex));
+ if (chan->left != NULL) free(chan->left);
+ if (chan->right != NULL) free(chan->right);
+}
+
+