diff options
| author | XANTRONIX Development | 2022-02-09 00:00:51 -0500 | 
|---|---|---|
| committer | XANTRONIX Development | 2022-02-09 00:56:29 -0500 | 
| commit | 77976d03699f95ea28278b5fdbba392f198b5f52 (patch) | |
| tree | f540fc87d774e4e7b3b99fc2d4611a963d86bfaf | |
| parent | a5c70a6adfaac0088e992caed5db5e3df2744ee0 (diff) | |
| download | xas-77976d03699f95ea28278b5fdbba392f198b5f52.tar.gz xas-77976d03699f95ea28278b5fdbba392f198b5f52.tar.bz2 xas-77976d03699f95ea28278b5fdbba392f198b5f52.zip | |
Implement xas_audio_format type
Changes:
    * Implement xas_audio_format struct to provide sample size,
      channels, and sample rate
    * Refactor argument order for most functions to allow a reasonable
      reading of argument types, when replacing three separate size_t
      arguments with one xas_audio_format object
| -rw-r--r-- | examples/open.c | 6 | ||||
| -rw-r--r-- | examples/say.c | 50 | ||||
| -rw-r--r-- | examples/test.c | 36 | ||||
| -rw-r--r-- | include/xas/audio.h | 38 | ||||
| -rw-r--r-- | include/xas/bank.h | 13 | ||||
| -rw-r--r-- | include/xas/mixer.h | 5 | ||||
| -rw-r--r-- | include/xas/riff.h | 4 | ||||
| -rw-r--r-- | include/xas/synth.h | 11 | ||||
| -rw-r--r-- | include/xas/vox.h | 12 | ||||
| -rw-r--r-- | src/audio.c | 107 | ||||
| -rw-r--r-- | src/bank.c | 44 | ||||
| -rw-r--r-- | src/mixer.c | 45 | ||||
| -rw-r--r-- | src/riff.c | 123 | ||||
| -rw-r--r-- | src/synth.c | 27 | ||||
| -rw-r--r-- | src/vox.c | 51 | 
15 files changed, 279 insertions, 293 deletions
| diff --git a/examples/open.c b/examples/open.c index 4bf036b..27ededd 100644 --- a/examples/open.c +++ b/examples/open.c @@ -37,9 +37,9 @@ int main(int argc, char **argv) {      }      printf("channels %zu sample rate %zu sample size %zu\n", -           wave->channels, -           wave->sample_rate, -           wave->sample_size); +           wave->format.channels, +           wave->format.sample_rate, +           wave->format.sample_size);      xas_audio_stream_destroy(wave); diff --git a/examples/say.c b/examples/say.c index 19dcb08..e0aea9a 100644 --- a/examples/say.c +++ b/examples/say.c @@ -41,13 +41,14 @@ static void usage(int argc, char **argv, const char *message, ...) {  }  static int16_t sine_sample(xas_synth *synth, synth_sine *sine) { -    int16_t ret;      static float tau = 2.0f * M_PI; +    int16_t ret; +      if (sine->flags & SYNTH_STATUS_ON) {          ret = (int16_t)roundf((INT16_MAX >> 2) * sinf(sine->phase)); -        sine->phase += tau / (synth->sample_rate / sine->frequency); +        sine->phase += tau / (synth->format.sample_rate / sine->frequency);          if (sine->phase > tau) {              sine->phase -= tau; @@ -80,9 +81,14 @@ int main(int argc, char **argv) {                         *synth_r,                         *output; -    size_t sample_rate     = 44100, -           buffer_size     =   735, -           duration_frames =  3600, +    xas_audio_format format = { +        .channels    = XAS_AUDIO_STEREO, +        .sample_size = XAS_AUDIO_PCM_16_BIT, +        .sample_rate = 44100 +    }; + +    size_t buffer_size     = 735, +           duration_frames = 3600,             i;      if (argc != 2) { @@ -90,24 +96,17 @@ int main(int argc, char **argv) {      }      if ((vox = xas_vox_new("/usr/bin/text2wave", -                             XAS_AUDIO_PCM_16_BIT, -                             sample_rate, -                             buffer_size, -                             NULL)) == NULL) { +                             format, +                             buffer_size)) == NULL) {          goto error_vox_new;      } -    if ((bank = xas_bank_new(XAS_AUDIO_PCM_16_BIT, -                               44100, -                               2646000, -                               4)) == NULL) { +    if ((bank = xas_bank_new(format, 2646000, 4)) == NULL) {          goto error_bank_new;      }      if ((output = xas_riff_new_file(argv[1], -                                      XAS_AUDIO_STEREO, -                                      XAS_AUDIO_PCM_16_BIT, -                                      sample_rate, +                                      format,                                        O_WRONLY | O_CREAT | O_TRUNC)) == NULL) {          goto error_riff_new_file;      } @@ -120,28 +119,23 @@ int main(int argc, char **argv) {          goto error_bank_stream_new;      } -    if ((synth_l = xas_synth_new(XAS_AUDIO_PCM_16_BIT, -                                   sample_rate, -                                   buffer_size, -                                   (xas_synth_callback_sample)sine_sample, +    if ((synth_l = xas_synth_new((xas_synth_callback_sample)sine_sample,                                     (xas_synth_callback_cleanup)sine_cleanup, +                                   format, +                                   buffer_size,                                     &sine_channels[0])) == NULL) {          goto error_synth_new_l;      } -    if ((synth_r = xas_synth_new(XAS_AUDIO_PCM_16_BIT, -                                   sample_rate, -                                   buffer_size, -                                   (xas_synth_callback_sample)sine_sample, +    if ((synth_r = xas_synth_new((xas_synth_callback_sample)sine_sample,                                     (xas_synth_callback_cleanup)sine_cleanup, +                                   format, +                                   buffer_size,                                     &sine_channels[1])) == NULL) {          goto error_synth_new_r;      } -    if ((mixer = xas_mixer_new(XAS_AUDIO_STEREO, -                                 XAS_AUDIO_PCM_16_BIT, -                                 sample_rate, -                                 buffer_size)) == NULL) { +    if ((mixer = xas_mixer_new(format, buffer_size)) == NULL) {          goto error_mixer_new;      } diff --git a/examples/test.c b/examples/test.c index 24e6ba1..1fbd8c4 100644 --- a/examples/test.c +++ b/examples/test.c @@ -45,7 +45,7 @@ static int16_t sine_sample(xas_synth *synth, synth_sine *sine) {      if (sine->flags & SYNTH_STATUS_ON) {          ret = (int16_t)roundf((INT16_MAX >> 2) * sinf(sine->phase)); -        sine->phase += tau / (synth->sample_rate / sine->frequency); +        sine->phase += tau / (synth->format.sample_rate / sine->frequency);          if (sine->phase > tau) {              sine->phase -= tau; @@ -73,8 +73,13 @@ int main(int argc, char **argv) {          { SYNTH_STATUS_ON, 0.0f, 420 },      }; -    size_t sample_rate = 44100, -           buffer_size =  4096, +    xas_audio_format format = { +        .channels    = XAS_AUDIO_STEREO, +        .sample_size = XAS_AUDIO_PCM_16_BIT, +        .sample_rate = 44100 +    }; + +    size_t buffer_size =  4096,             duration_s  =    60,             i; @@ -83,35 +88,28 @@ int main(int argc, char **argv) {      }      if ((wave = xas_riff_new_file(argv[1], -                                    XAS_AUDIO_STEREO, -                                    XAS_AUDIO_PCM_16_BIT, -                                    sample_rate, +                                    format,                                      O_WRONLY | O_CREAT | O_TRUNC)) == NULL) {          goto error_riff_new_file;      } -    if ((synth_l = xas_synth_new(XAS_AUDIO_PCM_16_BIT, -                                   sample_rate, -                                   buffer_size, -                                   (xas_synth_callback_sample)sine_sample, +    if ((synth_l = xas_synth_new((xas_synth_callback_sample)sine_sample,                                     (xas_synth_callback_cleanup)sine_cleanup, +                                   format, +                                   buffer_size,                                     &sine_channels[0])) == NULL) {          goto error_synth_new_l;      } -    if ((synth_r = xas_synth_new(XAS_AUDIO_PCM_16_BIT, -                                   sample_rate, -                                   buffer_size, -                                   (xas_synth_callback_sample)sine_sample, +    if ((synth_r = xas_synth_new((xas_synth_callback_sample)sine_sample,                                     (xas_synth_callback_cleanup)sine_cleanup, +                                   format, +                                   buffer_size,                                     &sine_channels[1])) == NULL) {          goto error_synth_new_r;      } -    if ((mixer = xas_mixer_new(XAS_AUDIO_STEREO, -                                 XAS_AUDIO_PCM_16_BIT, -                                 sample_rate, -                                 buffer_size)) == NULL) { +    if ((mixer = xas_mixer_new(format, buffer_size)) == NULL) {          goto error_mixer_new;      } @@ -129,7 +127,7 @@ int main(int argc, char **argv) {          if ((readlen = xas_audio_stream_read(mixer->output,                                                 &buf, -                                               sample_rate)) < 0) { +                                               buffer_size)) < 0) {              goto error_audio_stream_read;          } diff --git a/include/xas/audio.h b/include/xas/audio.h index 5a92a50..b18a2d2 100644 --- a/include/xas/audio.h +++ b/include/xas/audio.h @@ -30,12 +30,16 @@ typedef ssize_t (*xas_audio_fill)(void *ctx,  typedef void (*xas_audio_cleanup)(void *ctx,                                      xas_audio_stream *stream); -struct _xas_audio_stream { -    enum xas_audio_stream_type type; - +typedef struct _xas_audio_format {      size_t channels,             sample_size,             sample_rate; +} xas_audio_format; + +struct _xas_audio_stream { +    enum xas_audio_stream_type type; + +    xas_audio_format format;      size_t buffer_size,             buffer_count; @@ -51,21 +55,29 @@ struct _xas_audio_stream {      void *ctx;  }; +void xas_audio_zero(xas_audio_format format, +                      void *dest, +                      size_t index, +                      size_t count); + +void xas_audio_copy(xas_audio_format format, +                      void *dest, +                      void *src, +                      size_t index_dest, +                      size_t index_src, +                      size_t count); +  xas_audio_stream *xas_audio_stream_new_sink(xas_audio_drain drain,                                                  xas_audio_cleanup cleanup, -                                                void *ctx, -                                                size_t channels, -                                                size_t sample_size, -                                                size_t sample_rate, -                                                size_t buffer_size); +                                                xas_audio_format format, +                                                size_t buffer_size, +                                                void *ctx);  xas_audio_stream *xas_audio_stream_new_source(xas_audio_fill fill,                                                    xas_audio_cleanup cleanup, -                                                  void *ctx, -                                                  size_t channels, -                                                  size_t sample_size, -                                                  size_t sample_rate, -                                                  size_t buffer_size); +                                                  xas_audio_format format, +                                                  size_t buffer_size, +                                                  void *ctx);  void xas_audio_stream_destroy(xas_audio_stream *stream); diff --git a/include/xas/bank.h b/include/xas/bank.h index ec3cb99..9f877d0 100644 --- a/include/xas/bank.h +++ b/include/xas/bank.h @@ -13,26 +13,25 @@ typedef struct _xas_bank_entry {  } xas_bank_entry;  typedef struct _xas_bank { -    size_t sample_size, -           sample_rate, -           entry_size, +    xas_audio_format format; + +    size_t entry_size,             entry_count;      int flags; -    float force; +    float gain;      size_t entry,             index;  } xas_bank; -xas_bank *xas_bank_new(size_t sample_size, -                           size_t sample_rate, +xas_bank *xas_bank_new(xas_audio_format format,                             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); +int xas_bank_play(xas_bank *bank, size_t entry, float gain);  void xas_bank_stop(xas_bank *bank); diff --git a/include/xas/mixer.h b/include/xas/mixer.h index 73fd363..3769272 100644 --- a/include/xas/mixer.h +++ b/include/xas/mixer.h @@ -25,10 +25,7 @@ typedef struct _xas_mixer {      size_t buffer_size;  } xas_mixer; -xas_mixer *xas_mixer_new(size_t channels, -                             size_t sample_size, -                             size_t sample_rate, -                             size_t buffer_size); +xas_mixer *xas_mixer_new(xas_audio_format format, size_t buffer_size);  void xas_mixer_destroy(xas_mixer *mixer); diff --git a/include/xas/riff.h b/include/xas/riff.h index f78e9e9..5a5d4ed 100644 --- a/include/xas/riff.h +++ b/include/xas/riff.h @@ -50,9 +50,7 @@ typedef struct _xas_riff xas_riff;  #pragma pack(pop)  xas_audio_stream *xas_riff_new_file(const char *path, -                                        size_t channels, -                                        size_t sample_size, -                                        size_t sample_rate, +                                        xas_audio_format format,                                          int flags);  xas_audio_stream *xas_riff_open_file(const char *path, int flags); diff --git a/include/xas/synth.h b/include/xas/synth.h index 1d070aa..20446cd 100644 --- a/include/xas/synth.h +++ b/include/xas/synth.h @@ -13,19 +13,16 @@ typedef int16_t (*xas_synth_callback_sample)(xas_synth *synth, void *ctx);  typedef void (*xas_synth_callback_cleanup)(xas_synth *synth, void *ctx);  struct _xas_synth { -    size_t sample_size, -           sample_rate; - +    xas_audio_format format;      xas_synth_callback_sample  sample;      xas_synth_callback_cleanup cleanup;      void *ctx;  }; -xas_audio_stream *xas_synth_new(size_t sample_size, -                                    size_t sample_rate, -                                    size_t buffer_size, -                                    xas_synth_callback_sample  sample, +xas_audio_stream *xas_synth_new(xas_synth_callback_sample  sample,                                      xas_synth_callback_cleanup cleanup, +                                    xas_audio_format format, +                                    size_t buffer_size,                                      void *ctx);  #endif /* _XAS_SYNTH_H */ diff --git a/include/xas/vox.h b/include/xas/vox.h index 85d8d20..fd442a8 100644 --- a/include/xas/vox.h +++ b/include/xas/vox.h @@ -13,11 +13,9 @@  typedef struct _xas_vox {      const char *text2wave_path; -    size_t sample_size, -           sample_rate, -           buffer_size; +    xas_audio_format format; -    void *ctx; +    size_t buffer_size;      int flags; @@ -29,10 +27,8 @@ typedef struct _xas_vox {  } xas_vox;  xas_vox *xas_vox_new(const char *text2wave_path, -                         size_t sample_size, -                         size_t sample_rate, -                         size_t buffer_size, -                         void *ctx); +                         xas_audio_format format, +                         size_t buffer_size);  void xas_vox_destroy(xas_vox *vox); diff --git a/src/audio.c b/src/audio.c index 001d449..561870f 100644 --- a/src/audio.c +++ b/src/audio.c @@ -4,32 +4,54 @@  #include <xas/audio.h> +void xas_audio_copy(xas_audio_format format, +                      void *dest, +                      void *src, +                      size_t index_dest, +                      size_t index_src, +                      size_t count) { +    size_t stride = format.channels * format.sample_size; + +    memcpy(((uint8_t *)dest) + stride * index_dest, +           ((uint8_t *)src)  + stride * index_src, +           stride * count); +} + +void xas_audio_zero(xas_audio_format format, +                      void *dest, +                      size_t index, +                      size_t count) { +    size_t stride = format.channels * format.sample_size; + +    memset((uint8_t *)dest + stride * index, +           '\0', +           stride * count); +} +  static xas_audio_stream *stream_new(enum xas_audio_stream_type type,                                        void *callback,                                        xas_audio_cleanup cleanup, -                                      void *ctx, -                                      size_t channels, -                                      size_t sample_size, -                                      size_t sample_rate, -                                      size_t buffer_size) { +                                      xas_audio_format format, +                                      size_t buffer_size, +                                      void *ctx) {      xas_audio_stream *stream;      size_t total = sizeof(xas_audio_stream) -                 + channels * sample_size * buffer_size; +                 + format.channels * format.sample_size * buffer_size;      if ((stream = malloc(total)) == NULL) {          goto error_malloc_stream;      } -    stream->type         = type; -    stream->channels     = channels; -    stream->sample_size  = sample_size; -    stream->sample_rate  = sample_rate; -    stream->buffer_size  = buffer_size; -    stream->buffer_count = 0; -    stream->callback     = callback; -    stream->cleanup      = cleanup; -    stream->ctx          = ctx; +    stream->type               = type; +    stream->format.channels    = format.channels; +    stream->format.sample_size = format.sample_size; +    stream->format.sample_rate = format.sample_rate; +    stream->buffer_size        = buffer_size; +    stream->buffer_count       = 0; +    stream->callback           = callback; +    stream->cleanup            = cleanup; +    stream->ctx                = ctx;      return stream; @@ -39,36 +61,28 @@ error_malloc_stream:  xas_audio_stream *xas_audio_stream_new_sink(xas_audio_drain drain,                                                  xas_audio_cleanup cleanup, -                                                void *ctx, -                                                size_t channels, -                                                size_t sample_size, -                                                size_t sample_rate, -                                                size_t buffer_size) { +                                                xas_audio_format format, +                                                size_t buffer_size, +                                                void *ctx) {      return stream_new(XAS_AUDIO_STREAM_SINK,                        drain,                        cleanup, -                      ctx, -                      channels, -                      sample_size, -                      sample_rate, -                      buffer_size); +                      format, +                      buffer_size, +                      ctx);  }  xas_audio_stream *xas_audio_stream_new_source(xas_audio_fill fill,                                                    xas_audio_cleanup cleanup, -                                                  void *ctx, -                                                  size_t channels, -                                                  size_t sample_size, -                                                  size_t sample_rate, -                                                  size_t buffer_size) { +                                                  xas_audio_format format, +                                                  size_t buffer_size, +                                                  void *ctx) {      return stream_new(XAS_AUDIO_STREAM_SOURCE,                        fill,                        cleanup, -                      ctx, -                      channels, -                      sample_size, -                      sample_rate, -                      buffer_size); +                      format, +                      buffer_size, +                      ctx);  }  void xas_audio_stream_destroy(xas_audio_stream *stream) { @@ -100,7 +114,8 @@ error_stream_drain:  }  static inline void *ptr(xas_audio_stream *stream, void *buf, size_t index) { -    return ((uint8_t *)buf) + stream->channels * stream->sample_size * index; +    return ((uint8_t *)buf) +        + stream->format.channels * stream->format.sample_size * index;  }  ssize_t xas_audio_stream_write(xas_audio_stream *stream, @@ -116,12 +131,15 @@ ssize_t xas_audio_stream_write(xas_audio_stream *stream,           */          size_t remaining = stream->buffer_size - stream->buffer_count; -        memcpy(ptr(stream, stream + 1, stream->buffer_count), -               ptr(stream, samples,    index_i), -               remaining * stream->channels * stream->sample_size); +        xas_audio_copy(stream->format, +                         stream + 1, +                         samples, +                         stream->buffer_count, +                         index_i, +                         remaining);          if (stream->drain(stream->ctx, -                          ptr(stream, stream + 1, 0), +                          stream + 1,                            stream->buffer_size,                            stream) < 0) {              goto error_stream_drain; @@ -157,9 +175,12 @@ ssize_t xas_audio_stream_write(xas_audio_stream *stream,               * Enough of the input has been drained that it can be copied to               * the target buffer.               */ -            memcpy(ptr(stream, stream + 1, stream->buffer_count), -                   ptr(stream, samples,    index_i), -                   remaining * stream->channels * stream->sample_size); +            xas_audio_copy(stream->format, +                             stream + 1, +                             samples, +                             stream->buffer_count, +                             index_i, +                             remaining);              index_i += remaining; @@ -3,13 +3,12 @@  #include <xas/bank.h> -xas_bank *xas_bank_new(size_t sample_size, -                           size_t sample_rate, +xas_bank *xas_bank_new(xas_audio_format format,                             size_t entry_size,                             size_t entry_count) {      xas_bank *bank; -    size_t entry_size_total = sizeof(xas_bank_entry) + sample_size +    size_t entry_size_total = sizeof(xas_bank_entry) + format.sample_size                                                         * entry_size;      size_t total = sizeof(xas_bank) + entry_count @@ -21,8 +20,10 @@ xas_bank *xas_bank_new(size_t sample_size,      memset(bank, '\0', total); -    bank->sample_size = sample_size; -    bank->sample_rate = sample_rate; +    bank->format.channels    = XAS_AUDIO_MONO; +    bank->format.sample_size = format.sample_size; +    bank->format.sample_rate = format.sample_rate; +      bank->entry_size  = entry_size;      bank->entry_count = entry_count; @@ -36,9 +37,9 @@ void xas_bank_destroy(xas_bank *bank) {      free(bank);  } -int xas_bank_play(xas_bank *bank, size_t entry, float force) { +int xas_bank_play(xas_bank *bank, size_t entry, float gain) {      bank->flags |= XAS_BANK_ACTIVE; -    bank->force  = force; +    bank->gain   = gain;      bank->entry  = entry;      bank->index  = 0; @@ -47,7 +48,7 @@ int xas_bank_play(xas_bank *bank, size_t entry, float force) {  void xas_bank_stop(xas_bank *bank) {      bank->flags &= ~XAS_BANK_ACTIVE; -    bank->force  = 0.0; +    bank->gain   = 0.0;      bank->entry  = 0;      bank->index  = 0;  } @@ -56,10 +57,6 @@ int xas_bank_active(xas_bank *bank) {      return bank->flags & XAS_BANK_ACTIVE;  } -static inline void *ptr(xas_audio_stream *stream, void *buf, size_t index) { -    return ((uint8_t *)buf) + stream->channels * stream->sample_size * index; -} -  ssize_t xas_bank_record(xas_bank *bank,                            xas_audio_stream *input,                            size_t entry_index, @@ -83,9 +80,12 @@ ssize_t xas_bank_record(xas_bank *bank,              goto error_audio_stream_read;          } -        memcpy(ptr(input, entry + 1, index_o), -               ptr(input, buf,       0), -               readlen * bank->sample_size); +        xas_audio_copy(bank->format, +                         entry + 1, +                         buf, +                         index_o, +                         0, +                         readlen);          left    -= readlen;          index_o += readlen; @@ -117,7 +117,7 @@ static ssize_t stream_fill(xas_bank *bank,              size_t i;              for (i=0; i<amount; i++) { -                dest[index_o + i] = bank->force * src[bank->index + i]; +                dest[index_o + i] = bank->gain * src[bank->index + i];              }              left        -= amount; @@ -128,9 +128,7 @@ static ssize_t stream_fill(xas_bank *bank,                  xas_bank_stop(bank);              }          } else { -            memset(ptr(stream, dest, index_o), -                   '\0', -                   left * stream->channels * stream->sample_size); +            xas_audio_zero(bank->format, dest, index_o, left);              index_o += left;              left     = 0; @@ -147,9 +145,7 @@ void stream_cleanup(xas_bank *bank, xas_audio_stream *stream) {  xas_audio_stream *xas_bank_stream_new(xas_bank *bank) {      return xas_audio_stream_new_source((xas_audio_fill)stream_fill,                                           (xas_audio_cleanup)stream_cleanup, -                                         bank, -                                         XAS_AUDIO_MONO, -                                         bank->sample_size, -                                         bank->sample_rate, -                                         bank->entry_size); +                                         bank->format, +                                         bank->entry_size, +                                         bank);  } diff --git a/src/mixer.c b/src/mixer.c index b1f2e47..b4e3bf1 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -69,9 +69,7 @@ static ssize_t mixer_fill(xas_mixer *mixer,      xas_mixer_input *input = mixer->inputs; -    memset(mixer->buf, -           '\0', -           output->channels * output->sample_size * output->buffer_size); +    xas_audio_zero(output->format, mixer->buf, 0, mixer->buffer_size);      while (input) {          void (*mixer_apply)(int16_t *, @@ -86,13 +84,16 @@ static ssize_t mixer_fill(xas_mixer *mixer,          ssize_t readlen; -        if (output->channels == 2 && input->stream->channels == 2) { +        size_t channels_in  = input->stream->format.channels, +               channels_out = output->format.channels; + +        if (channels_in == 2 && channels_out == 2) {              mixer_apply = mixer_apply_stereo_to_stereo; -        } else if (output->channels == 2 && input->stream->channels == 1) { +        } else if (channels_in == 1 && channels_out == 2) {              mixer_apply = mixer_apply_mono_to_stereo; -        } else if (output->channels == 1 && input->stream->channels == 1) { +        } else if (channels_in == 1 && channels_out == 1) {              mixer_apply = mixer_apply_mono_to_mono; -        } else if (output->channels == 1 && input->stream->channels == 2) { +        } else if (channels_in == 2 && channels_out == 2) {              mixer_apply = mixer_apply_stereo_to_mono;          } else {              goto error_invalid_input; @@ -118,9 +119,12 @@ static ssize_t mixer_fill(xas_mixer *mixer,          input = next;      } -    memcpy(samples, -           mixer->buf, -           total * output->channels * output->sample_size); +    xas_audio_copy(output->format, +                     samples, +                     mixer->buf, +                     0, +                     0, +                     total);      return total; @@ -129,27 +133,24 @@ error_audio_read_stream:      return -1;  } -xas_mixer *xas_mixer_new(size_t channels, -                             size_t sample_size, -                             size_t sample_rate, -                             size_t buffer_size) { +xas_mixer *xas_mixer_new(xas_audio_format format, size_t buffer_size) {      xas_mixer *mixer; +    size_t total = buffer_size * format.channels * format.sample_size; +      if ((mixer = malloc(sizeof(*mixer))) == NULL) {          goto error_malloc_mixer;      } -    if ((mixer->buf = malloc(channels * sample_size * buffer_size)) == NULL) { +    if ((mixer->buf = malloc(total)) == NULL) {          goto error_malloc_buf;      }      if ((mixer->output = xas_audio_stream_new_source((xas_audio_fill)mixer_fill,                                                         NULL, -                                                       mixer, -                                                       channels, -                                                       sample_size, -                                                       sample_rate, -                                                       buffer_size)) == NULL) { +                                                       format, +                                                       buffer_size, +                                                       mixer)) == NULL) {          goto error_audio_stream_new_source;      } @@ -217,8 +218,8 @@ xas_mixer_input *xas_mixer_input_add(xas_mixer *mixer,                                           float pan) {      xas_mixer_input *input; -    if (stream->sample_size != mixer->output->sample_size -     || stream->sample_rate != mixer->output->sample_rate) { +    if (stream->format.sample_size != mixer->output->format.sample_size +     || stream->format.sample_rate != mixer->output->format.sample_rate) {          errno = EINVAL;          goto error_invalid_stream; @@ -12,9 +12,7 @@ struct _xas_riff {      int fd;      size_t size; -    size_t channels, -           sample_size, -           sample_rate; +    xas_audio_format format;  };  static int header_write(xas_riff *riff) { @@ -38,11 +36,13 @@ static int header_write(xas_riff *riff) {              },              .type             = XAS_RIFF_WAVE_DEFAULT_TYPE, -            .channels         = riff->channels, -            .sample_rate      = riff->sample_rate, -            .byte_rate        = riff->channels * riff->sample_size * riff->sample_rate, -            .sample_size      = riff->sample_size, -            .sample_size_bits = riff->sample_size << 3 +            .channels         = riff->format.channels, +            .sample_rate      = riff->format.sample_rate, +            .sample_size      = riff->format.sample_size, +            .sample_size_bits = riff->format.sample_size << 3, +            .byte_rate        = riff->format.channels +                              * riff->format.sample_size +                              * riff->format.sample_rate          },          { @@ -70,9 +70,7 @@ error_io:  }  static xas_riff *new_file(const char *path, -                            size_t channels, -                            size_t sample_size, -                            size_t sample_rate, +                            xas_audio_format format,                              int flags) {      xas_riff *riff; @@ -86,11 +84,12 @@ static xas_riff *new_file(const char *path,          goto error_open;      } -    riff->file        = path; -    riff->size        = 0; -    riff->channels    = channels; -    riff->sample_size = sample_size; -    riff->sample_rate = sample_rate; +    riff->file = path; +    riff->size = 0; + +    riff->format.channels    = format.channels; +    riff->format.sample_size = format.sample_size; +    riff->format.sample_rate = format.sample_rate;      if (header_write(riff) < 0) {          goto error_header_write; @@ -167,9 +166,9 @@ static int wave_header_parse(xas_riff *riff,          goto error_invalid_wave_data_format_id;      } -    riff->channels    = header->wave.channels; -    riff->sample_size = header->wave.sample_size; -    riff->sample_rate = header->wave.sample_rate; +    riff->format.channels    = header->wave.channels; +    riff->format.sample_size = header->wave.sample_size; +    riff->format.sample_rate = header->wave.sample_rate;      return 0; @@ -196,12 +195,13 @@ static xas_riff *open_fd(int fd) {          goto error_malloc_riff;      } -    riff->file        = NULL; -    riff->fd          = fd; -    riff->size        = 0; -    riff->channels    = 0; -    riff->sample_size = 0; -    riff->sample_rate = 0; +    riff->file = NULL; +    riff->fd   = fd; +    riff->size = 0; + +    riff->format.channels    = 0; +    riff->format.sample_size = 0; +    riff->format.sample_rate = 0;      if ((readlen = read(fd, &header, sizeof(header))) < 0) {          goto error_read; @@ -244,11 +244,12 @@ static xas_riff *open_file(const char *path, int flags) {          goto error_open;      } -    riff->file        = path; -    riff->size        = 0; -    riff->channels    = 0; -    riff->sample_size = 0; -    riff->sample_rate = 0; +    riff->file = path; +    riff->size = 0; + +    riff->format.channels    = 0; +    riff->format.sample_size = 0; +    riff->format.sample_rate = 0;      if (lseek(riff->fd, 0, SEEK_SET) < 0) {          goto error_lseek; @@ -299,8 +300,8 @@ static ssize_t audio_drain(xas_riff *riff,                             void *samples,                             size_t count,                             xas_audio_stream *stream) { -    size_t len = count * stream->channels -                       * stream->sample_size; +    size_t stride = stream->format.channels * stream->format.sample_size, +           len    = stride * count;      ssize_t wrlen; @@ -310,7 +311,7 @@ static ssize_t audio_drain(xas_riff *riff,      riff->size += wrlen; -    return wrlen / stream->channels / stream->sample_size; +    return wrlen / stride;  error_write:      return -1; @@ -320,8 +321,8 @@ static ssize_t audio_fill(xas_riff *riff,                            void *samples,                            size_t count,                            xas_audio_stream *stream) { -    size_t len = count * stream->channels -                       * stream->sample_size; +    size_t stride = stream->format.channels * stream->format.sample_size, +           len    = count * stride;      ssize_t rdlen; @@ -329,46 +330,36 @@ static ssize_t audio_fill(xas_riff *riff,          goto error_read;      } -    return rdlen / stream->channels / stream->sample_size; +    return rdlen / stride;  error_read:      return -1;  }  xas_audio_stream *xas_riff_new_file(const char *path, -                                        size_t channels, -                                        size_t sample_size, -                                        size_t sample_rate, +                                        xas_audio_format format,                                          int flags) {      xas_audio_stream *stream;      xas_riff *riff; -    if ((riff = new_file(path, -                         channels, -                         sample_size, -                         sample_rate, -                         flags)) == NULL) { +    if ((riff = new_file(path, format, flags)) == NULL) {          goto error_new_file;      }      if (flags & (O_RDWR | O_WRONLY)) {          if ((stream = xas_audio_stream_new_sink((xas_audio_drain)audio_drain,                                                    (xas_audio_cleanup)close_file, -                                                  riff, -                                                  channels, -                                                  sample_size, -                                                  sample_rate, -                                                  4096)) == NULL) { +                                                  format, +                                                  4096, +                                                  riff)) == NULL) {              goto error_audio_stream_new_sink;          }      } else {          if ((stream = xas_audio_stream_new_source((xas_audio_fill)audio_fill,                                                      (xas_audio_cleanup)close_file, -                                                    riff, -                                                    channels, -                                                    sample_size, -                                                    sample_rate, -                                                    4096)) == NULL) { +                                                    format, +                                                    4096, +                                                    riff)) == NULL) {              goto error_audio_stream_new_sink;          }      } @@ -393,21 +384,17 @@ xas_audio_stream *xas_riff_open_file(const char *path, int flags) {      if (flags & (O_RDWR | O_WRONLY)) {          if ((stream = xas_audio_stream_new_sink((xas_audio_drain)audio_drain,                                                    (xas_audio_cleanup)close_file, -                                                  riff, -                                                  riff->channels, -                                                  riff->sample_size, -                                                  riff->sample_rate, -                                                  4096)) == NULL) { +                                                  riff->format, +                                                  4096, +                                                  riff)) == NULL) {              goto error_audio_stream_new_sink;          }      } else {          if ((stream = xas_audio_stream_new_source((xas_audio_fill)audio_fill,                                                      (xas_audio_cleanup)close_file, -                                                    riff, -                                                    riff->channels, -                                                    riff->sample_size, -                                                    riff->sample_rate, -                                                    4096)) == NULL) { +                                                    riff->format, +                                                    4096, +                                                    riff)) == NULL) {              goto error_audio_stream_new_sink;          }      } @@ -431,11 +418,9 @@ xas_audio_stream *xas_riff_open_fd(int fd) {      if ((stream = xas_audio_stream_new_source((xas_audio_fill)audio_fill,                                                  (xas_audio_cleanup)close_file, -                                                riff, -                                                riff->channels, -                                                riff->sample_size, -                                                riff->sample_rate, -                                                4096)) == NULL) { +                                                riff->format, +                                                4096, +                                                riff)) == NULL) {          goto error_audio_stream_new_sink;      } diff --git a/src/synth.c b/src/synth.c index 6dd14ea..d96c1b5 100644 --- a/src/synth.c +++ b/src/synth.c @@ -23,11 +23,10 @@ static void synth_cleanup(xas_synth *synth, xas_audio_stream *stream) {      free(synth);  } -xas_audio_stream *xas_synth_new(size_t sample_size, -                                    size_t sample_rate, -                                    size_t buffer_size, -                                    xas_synth_callback_sample  sample, +xas_audio_stream *xas_synth_new(xas_synth_callback_sample  sample,                                      xas_synth_callback_cleanup cleanup, +                                    xas_audio_format format, +                                    size_t buffer_size,                                      void *ctx) {      xas_audio_stream *stream;      xas_synth *synth; @@ -36,19 +35,19 @@ xas_audio_stream *xas_synth_new(size_t sample_size,          goto error_malloc_synth;      } -    synth->sample_size = sample_size; -    synth->sample_rate = sample_rate; -    synth->sample      = sample; -    synth->cleanup     = cleanup; -    synth->ctx         = ctx; +    synth->format.channels    = XAS_AUDIO_MONO; +    synth->format.sample_size = format.sample_size; +    synth->format.sample_rate = format.sample_rate; + +    synth->sample  = sample; +    synth->cleanup = cleanup; +    synth->ctx     = ctx;      if ((stream = xas_audio_stream_new_source((xas_audio_fill)synth_fill,                                                  (xas_audio_cleanup)synth_cleanup, -                                                synth, -                                                XAS_AUDIO_MONO, -                                                sample_size, -                                                sample_rate, -                                                buffer_size)) == NULL) { +                                                synth->format, +                                                buffer_size, +                                                synth)) == NULL) {          goto error_audio_stream_new_source;      } @@ -64,7 +64,7 @@ static int vox_start(xas_vox *vox) {          NULL      }; -    snprintf(sample_rate, sizeof(sample_rate)-1, "%zu", vox->sample_rate); +    snprintf(sample_rate, sizeof(sample_rate)-1, "%zu", vox->format.sample_rate);      (void)vox_stop(vox); @@ -144,17 +144,15 @@ static ssize_t vox_fill(xas_vox *vox,      ssize_t readlen,              readcount; -    size_t i; -      if (!(vox->flags & XAS_VOX_ACTIVE)) { -        memset(samples, '\0', count * vox->sample_size); +        xas_audio_zero(vox->format, samples, 0, count);          return count;      }      if ((readlen = read(vox->stdout,                          samples, -                        count * vox->sample_size)) < 0) { +                        count * vox->format.sample_size)) < 0) {          goto error_read;      } @@ -162,11 +160,9 @@ static ssize_t vox_fill(xas_vox *vox,          vox_stop(vox);      } -    readcount = readlen / vox->sample_size; +    readcount = readlen / vox->format.sample_size; -    for (i=readcount; i<count-readcount; i++) { -        samples[i] = 0; -    } +    xas_audio_zero(vox->format, samples, readcount, count-readcount);      return count; @@ -175,10 +171,8 @@ error_read:  }  xas_vox *xas_vox_new(const char *text2wave_path, -                         size_t sample_size, -                         size_t sample_rate, -                         size_t buffer_size, -                         void *ctx) { +                         xas_audio_format format, +                         size_t buffer_size) {      xas_vox *vox;      if ((vox = malloc(sizeof(*vox))) == NULL) { @@ -186,16 +180,17 @@ xas_vox *xas_vox_new(const char *text2wave_path,      }      vox->text2wave_path = text2wave_path; -    vox->sample_size    = sample_size; -    vox->sample_rate    = sample_rate; -    vox->buffer_size    = buffer_size; -    vox->ctx            = ctx; -    vox->flags          = XAS_VOX_IDLE; -    vox->pid    = -1; -    vox->stdin  = -1; -    vox->stdout = -1; -    vox->in     = NULL; +    vox->format.channels    = XAS_AUDIO_MONO; +    vox->format.sample_size = format.sample_size; +    vox->format.sample_rate = format.sample_rate; + +    vox->buffer_size = buffer_size; +    vox->flags       = XAS_VOX_IDLE; +    vox->pid         = -1; +    vox->stdin       = -1; +    vox->stdout      = -1; +    vox->in          = NULL;      return vox; @@ -229,8 +224,8 @@ int xas_vox_generate(xas_vox *vox) {          goto error_riff_open_fd;      } -    if (output->sample_size != vox->sample_size -     || output->sample_rate != vox->sample_rate) { +    if (output->format.sample_size != vox->format.sample_size +     || output->format.sample_rate != vox->format.sample_rate) {          errno = EINVAL;          goto error_invalid_stream; @@ -274,9 +269,7 @@ int xas_vox_say(xas_vox *vox, const char *message) {  xas_audio_stream *xas_vox_stream_new(xas_vox *vox) {      return xas_audio_stream_new_source((xas_audio_fill)vox_fill,                                           (xas_audio_cleanup)vox_cleanup, -                                         vox, -                                         XAS_AUDIO_MONO, -                                         vox->sample_size, -                                         vox->sample_rate, -                                         vox->buffer_size); +                                         vox->format, +                                         vox->buffer_size, +                                         vox);  } | 
 
    