summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXANTRONIX Development2022-02-23 00:21:38 -0500
committerXANTRONIX Development2022-02-23 00:21:38 -0500
commit52b99333c5e8cf3b757cd6e88fca13d420b54979 (patch)
tree9b231c40eb4bd7d53ce07cedb50f8a40c589d2d7
parentfc378a22b3294bcb696b8600e6fd8f9f639c36fc (diff)
downloadxas-52b99333c5e8cf3b757cd6e88fca13d420b54979.tar.gz
xas-52b99333c5e8cf3b757cd6e88fca13d420b54979.tar.bz2
xas-52b99333c5e8cf3b757cd6e88fca13d420b54979.zip
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
-rw-r--r--examples/say.c27
-rw-r--r--include/xas/bank.h34
-rw-r--r--src/bank.c111
3 files changed, 115 insertions, 57 deletions
diff --git a/examples/say.c b/examples/say.c
index e0aea9a..8741a10 100644
--- a/examples/say.c
+++ b/examples/say.c
@@ -75,8 +75,10 @@ int main(int argc, char **argv) {
xas_bank *bank;
xas_vox *vox;
+ xas_bank_player *player;
+
xas_audio_stream *voice,
- *bank_stream,
+ *player_stream,
*synth_l,
*synth_r,
*output;
@@ -105,6 +107,10 @@ int main(int argc, char **argv) {
goto error_bank_new;
}
+ if ((player = xas_bank_player_new(bank)) == NULL) {
+ goto error_bank_player_new;
+ }
+
if ((output = xas_riff_new_file(argv[1],
format,
O_WRONLY | O_CREAT | O_TRUNC)) == NULL) {
@@ -115,8 +121,8 @@ int main(int argc, char **argv) {
goto error_vox_stream_new;
}
- if ((bank_stream = xas_bank_stream_new(bank)) == NULL) {
- goto error_bank_stream_new;
+ if ((player_stream = xas_bank_player_stream_new(player)) == NULL) {
+ goto error_bank_player_stream_new;
}
if ((synth_l = xas_synth_new((xas_synth_callback_sample)sine_sample,
@@ -139,7 +145,7 @@ int main(int argc, char **argv) {
goto error_mixer_new;
}
- if (xas_mixer_input_add(mixer, bank_stream, 1.0, 0.0) == NULL) {
+ if (xas_mixer_input_add(mixer, player_stream, 1.0, 0.0) == NULL) {
goto error_mixer_input_add;
}
@@ -166,8 +172,8 @@ int main(int argc, char **argv) {
void *buf;
ssize_t readlen;
- if (i >= 300 && !xas_bank_active(bank)) {
- xas_bank_play(bank, 0, 1.0);
+ if (i >= 300 && !xas_bank_player_playing(player)) {
+ xas_bank_player_start(player, 0, 1.0);
}
if ((readlen = xas_audio_stream_read(mixer->output,
@@ -186,7 +192,7 @@ int main(int argc, char **argv) {
xas_mixer_destroy(mixer);
xas_audio_stream_destroy(synth_r);
xas_audio_stream_destroy(synth_l);
- xas_audio_stream_destroy(bank_stream);
+ xas_audio_stream_destroy(player_stream);
xas_audio_stream_destroy(voice);
xas_audio_stream_destroy(output);
@@ -208,15 +214,18 @@ error_synth_new_r:
xas_audio_stream_destroy(synth_l);
error_synth_new_l:
- xas_audio_stream_destroy(bank_stream);
+ xas_audio_stream_destroy(player_stream);
-error_bank_stream_new:
+error_bank_player_stream_new:
xas_audio_stream_destroy(voice);
error_vox_stream_new:
xas_audio_stream_destroy(output);
error_riff_new_file:
+ xas_bank_player_destroy(player);
+
+error_bank_player_new:
xas_bank_destroy(bank);
error_bank_new:
diff --git a/include/xas/bank.h b/include/xas/bank.h
index 9f877d0..be623f0 100644
--- a/include/xas/bank.h
+++ b/include/xas/bank.h
@@ -5,8 +5,10 @@
#include <xas/audio.h>
-#define XAS_BANK_IDLE 0
-#define XAS_BANK_ACTIVE (1 << 0)
+enum xas_bank_player_status {
+ XAS_BANK_PLAYER_STOPPED,
+ XAS_BANK_PLAYER_PLAYING,
+};
typedef struct _xas_bank_entry {
size_t duration;
@@ -17,13 +19,17 @@ typedef struct _xas_bank {
size_t entry_size,
entry_count;
+} xas_bank;
+
+typedef struct _xas_bank_player {
+ xas_bank *bank;
+ enum xas_bank_player_status status;
- int flags;
float gain;
size_t entry,
index;
-} xas_bank;
+} xas_bank_player;
xas_bank *xas_bank_new(xas_audio_format format,
size_t entry_size,
@@ -31,17 +37,23 @@ xas_bank *xas_bank_new(xas_audio_format format,
void xas_bank_destroy(xas_bank *bank);
-int xas_bank_play(xas_bank *bank, size_t entry, float gain);
-
-void xas_bank_stop(xas_bank *bank);
-
-int xas_bank_active(xas_bank *bank);
-
ssize_t xas_bank_record(xas_bank *bank,
xas_audio_stream *input,
size_t entry_index,
size_t count);
-xas_audio_stream *xas_bank_stream_new(xas_bank *bank);
+xas_bank_player *xas_bank_player_new(xas_bank *bank);
+
+void xas_bank_player_destroy(xas_bank_player *player);
+
+int xas_bank_player_start(xas_bank_player *player,
+ size_t entry,
+ float gain);
+
+int xas_bank_player_stop(xas_bank_player *player);
+
+int xas_bank_player_playing(xas_bank_player *player);
+
+xas_audio_stream *xas_bank_player_stream_new(xas_bank_player *player);
#endif /* _XAS_BANK_H */
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; i<amount; i++) {
- dest[index_o + i] = bank->gain * 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);
}