From 52b99333c5e8cf3b757cd6e88fca13d420b54979 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Wed, 23 Feb 2022 00:21:38 -0500 Subject: Implement xas_bank_player type Changes: * Implement xas_bank_player type to decouple player state from sample storage, to allow multiple concurrent players against a single sample bank * Refactor examples/say.c to use xas_bank_player --- src/bank.c | 111 ++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/bank.c b/src/bank.c index ff7c071..19e3514 100644 --- a/src/bank.c +++ b/src/bank.c @@ -37,26 +37,6 @@ void xas_bank_destroy(xas_bank *bank) { free(bank); } -int xas_bank_play(xas_bank *bank, size_t entry, float gain) { - bank->flags |= XAS_BANK_ACTIVE; - bank->gain = gain; - bank->entry = entry; - bank->index = 0; - - return 0; -} - -void xas_bank_stop(xas_bank *bank) { - bank->flags &= ~XAS_BANK_ACTIVE; - bank->gain = 0.0; - bank->entry = 0; - bank->index = 0; -} - -int xas_bank_active(xas_bank *bank) { - return bank->flags & XAS_BANK_ACTIVE; -} - ssize_t xas_bank_record(xas_bank *bank, xas_audio_stream *input, size_t entry_index, @@ -97,35 +77,92 @@ error_audio_stream_read: return -1; } -static ssize_t stream_fill(xas_bank *bank, +xas_bank_player *xas_bank_player_new(xas_bank *bank) { + xas_bank_player *player; + + if ((player = malloc(sizeof(*player))) == NULL) { + goto error_malloc_player; + } + + player->bank = bank; + player->status = XAS_BANK_PLAYER_STOPPED; + player->gain = 0.0f; + player->entry = 0; + player->index = 0; + + return player; + +error_malloc_player: + return NULL; +} + +void xas_bank_player_destroy(xas_bank_player *player) { + free(player); +} + +int xas_bank_player_start(xas_bank_player *player, + size_t entry, + float gain) { + if (player->status == XAS_BANK_PLAYER_PLAYING) { + return 0; + } + + player->status = XAS_BANK_PLAYER_PLAYING; + player->gain = gain; + player->entry = entry; + player->index = 0; + + return 0; +} + +int xas_bank_player_stop(xas_bank_player *player) { + if (player->status == XAS_BANK_PLAYER_STOPPED) { + return 0; + } + + player->status = XAS_BANK_PLAYER_STOPPED; + player->gain = 0.0; + player->entry = 0; + player->index = 0; + + return 1; +} + +int xas_bank_player_playing(xas_bank_player *player) { + return player->status == XAS_BANK_PLAYER_PLAYING; +} + +static ssize_t stream_fill(xas_bank_player *player, int16_t *dest, size_t count, xas_audio_stream *stream) { - size_t index_o = 0, - left = count; + xas_bank *bank = player->bank; + + size_t index_o = 0, + left = count; while (left) { - if (bank->flags & XAS_BANK_ACTIVE) { + if (player->status == XAS_BANK_PLAYER_PLAYING) { xas_bank_entry *entry = - &((xas_bank_entry *)(bank + 1))[bank->entry]; + &((xas_bank_entry *)(bank + 1))[player->entry]; int16_t *src = (int16_t *)(entry + 1); - size_t remaining = entry->duration - bank->index, + size_t remaining = entry->duration - player->index, amount = remaining < left? remaining: left; size_t i; for (i=0; igain * src[bank->index + i]; + dest[index_o + i] = player->gain * src[player->index + i]; } - left -= amount; - bank->index += amount; - index_o += amount; + left -= amount; + player->index += amount; + index_o += amount; - if (bank->index == entry->duration) { - xas_bank_stop(bank); + if (player->index == entry->duration) { + xas_bank_player_stop(player); } } else { xas_audio_zero(bank->format, dest, index_o, left); @@ -138,14 +175,14 @@ static ssize_t stream_fill(xas_bank *bank, return count; } -void stream_cleanup(xas_bank *bank, xas_audio_stream *stream) { +void stream_cleanup(xas_bank_player *player, xas_audio_stream *stream) { return; } -xas_audio_stream *xas_bank_stream_new(xas_bank *bank) { +xas_audio_stream *xas_bank_player_stream_new(xas_bank_player *player) { return xas_audio_stream_new_source((xas_audio_fill)stream_fill, (xas_audio_cleanup)stream_cleanup, - bank->format, - bank->entry_size, - bank); + player->bank->format, + player->bank->entry_size, + player); } -- cgit v1.2.3