diff options
| author | XANTRONIX Development | 2022-02-23 00:21:38 -0500 | 
|---|---|---|
| committer | XANTRONIX Development | 2022-02-23 00:21:38 -0500 | 
| commit | 52b99333c5e8cf3b757cd6e88fca13d420b54979 (patch) | |
| tree | 9b231c40eb4bd7d53ce07cedb50f8a40c589d2d7 | |
| parent | fc378a22b3294bcb696b8600e6fd8f9f639c36fc (diff) | |
| download | xas-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.c | 27 | ||||
| -rw-r--r-- | include/xas/bank.h | 34 | ||||
| -rw-r--r-- | src/bank.c | 111 | 
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 */ @@ -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);  } | 
 
    