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 /src | |
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
Diffstat (limited to 'src')
-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 |
6 files changed, 196 insertions, 201 deletions
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); } |