diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/bank.c | 109 |
2 files changed, 111 insertions, 2 deletions
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); +} |