summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/xas/bank.h46
-rw-r--r--src/Makefile4
-rw-r--r--src/bank.c109
3 files changed, 157 insertions, 2 deletions
diff --git a/include/xas/bank.h b/include/xas/bank.h
new file mode 100644
index 0000000..6d7aeb1
--- /dev/null
+++ b/include/xas/bank.h
@@ -0,0 +1,46 @@
+#ifndef _XAS_BANK_H
+#define _XAS_BANK_H
+
+#include <sys/types.h>
+
+#include <xas/audio.h>
+
+#define XAS_BANK_IDLE 0
+#define XAS_BANK_ACTIVE (1 << 0)
+
+typedef struct _xas_bank_entry {
+ size_t duration;
+} xas_bank_entry;
+
+typedef struct _xas_bank {
+ size_t sample_size,
+ sample_rate,
+ entry_size,
+ entry_count;
+
+ int flags;
+ float force;
+
+ size_t entry,
+ index;
+} xas_bank;
+
+xas_bank *xas_bank_new(size_t sample_size,
+ size_t sample_rate,
+ size_t entry_size,
+ size_t entry_count);
+
+void xas_bank_destroy(xas_bank *bank);
+
+int xas_bank_play(xas_bank *bank, size_t entry, float force);
+
+void xas_bank_stop(xas_bank *bank);
+
+ssize_t xas_bank_record(xas_bank *bank,
+ xas_audio_stream *input,
+ size_t entry,
+ size_t count);
+
+xas_audio_stream *xas_bank_stream_new(xas_bank *bank);
+
+#endif /* _XAS_BANK_H */
diff --git a/src/Makefile b/src/Makefile
index d5ddc43..b9e9150 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -7,9 +7,9 @@ CC = $(CROSS)cc
CFLAGS += -I$(INCLUDE_PATH)
LDFLAGS +=
-HEADERS = audio.h riff.h mixer.h synth.h vox.h
+HEADERS = audio.h riff.h mixer.h synth.h vox.h bank.h
-OBJS = audio.o riff.o mixer.o synth.o vox.o
+OBJS = audio.o riff.o mixer.o synth.o vox.o bank.o
VERSION_MAJOR = 0
VERSION_MINOR = 0.1
diff --git a/src/bank.c b/src/bank.c
new file mode 100644
index 0000000..8c17bb3
--- /dev/null
+++ b/src/bank.c
@@ -0,0 +1,109 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <xas/bank.h>
+
+xas_bank *xas_bank_new(size_t sample_size,
+ size_t sample_rate,
+ size_t entry_size,
+ size_t entry_count) {
+ xas_bank *bank;
+
+ size_t entry_size_total = sizeof(xas_bank_entry) + entry_size;
+
+ size_t total = sizeof(xas_bank) + sample_size
+ * entry_size_total
+ * entry_count;
+
+ if ((bank = malloc(total)) == NULL) {
+ goto error_malloc_bank;
+ }
+
+ memset(bank, '\0', total);
+
+ bank->sample_size = sample_size;
+ bank->sample_rate = sample_rate;
+ bank->entry_size = entry_size;
+ bank->entry_count = entry_count;
+
+ return bank;
+
+error_malloc_bank:
+ return NULL;
+}
+
+void xas_bank_destroy(xas_bank *bank) {
+ free(bank);
+}
+
+int xas_bank_play(xas_bank *bank, size_t entry, float force) {
+ bank->flags |= XAS_BANK_ACTIVE;
+ bank->force = force;
+ bank->entry = entry;
+ bank->index = 0;
+
+ return 0;
+}
+
+void xas_bank_stop(xas_bank *bank) {
+ bank->flags &= ~XAS_BANK_ACTIVE;
+ bank->force = 0.0;
+ bank->entry = 0;
+ bank->index = 0;
+}
+
+static inline void *ptr(xas_audio_stream *stream, void *buf, size_t index) {
+ return ((uint8_t *)buf) + stream->channels * stream->sample_size * index;
+}
+
+static ssize_t bank_fill(xas_bank *bank,
+ int16_t *samples,
+ size_t count,
+ xas_audio_stream *stream) {
+ size_t index_o = 0,
+ left = count;
+
+ if (!(bank->flags & XAS_BANK_ACTIVE)) {
+ memset(samples, '\0', count * bank->sample_size);
+
+ return count;
+ }
+
+ while (left) {
+ xas_bank_entry *entry =
+ &((xas_bank_entry *)(bank + 1))[bank->entry];
+
+ size_t remaining = bank->entry_size - bank->index,
+ amount = remaining < left? remaining: left;
+
+ memcpy(ptr(stream, samples, index_o),
+ ptr(stream, entry + 1, bank->index),
+ amount * stream->channels * stream->sample_size);
+
+ left -= amount;
+ index_o += amount;
+
+ bank->index += amount;
+
+ if (bank->index == entry->duration) {
+ bank->index = 0;
+ }
+ }
+
+ return count;
+}
+
+void bank_cleanup(xas_bank *bank,
+ xas_audio_stream *stream) {
+ return;
+}
+
+xas_audio_stream *xas_bank_stream_new(xas_bank *bank) {
+ return xas_audio_stream_new_source((xas_audio_fill)bank_fill,
+ (xas_audio_cleanup)bank_cleanup,
+ bank,
+ XAS_AUDIO_STREAM_MONO,
+ bank->sample_size,
+ bank->sample_rate,
+ bank->entry_size);
+}