From 7f52b9c23cb6e70c90cd01316f4a703962c3f92f Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Wed, 2 Feb 2022 21:52:47 -0500 Subject: Initial implementation of src/bank.c Initial implementation of src/bank.c to act as a sample bank --- include/xas/bank.h | 46 ++++++++++++++++++++++ src/Makefile | 4 +- src/bank.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 include/xas/bank.h create mode 100644 src/bank.c 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 + +#include + +#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 +#include + +#include + +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); +} -- cgit v1.2.3