summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio.c107
-rw-r--r--src/bank.c44
-rw-r--r--src/mixer.c45
-rw-r--r--src/riff.c123
-rw-r--r--src/synth.c27
-rw-r--r--src/vox.c51
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;
diff --git a/src/bank.c b/src/bank.c
index d38822f..ff7c071 100644
--- a/src/bank.c
+++ b/src/bank.c
@@ -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;
diff --git a/src/riff.c b/src/riff.c
index ce788f5..5f63ff4 100644
--- a/src/riff.c
+++ b/src/riff.c
@@ -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;
}
diff --git a/src/vox.c b/src/vox.c
index 6739ee0..94d41dc 100644
--- a/src/vox.c
+++ b/src/vox.c
@@ -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);
}