summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio.c6
-rw-r--r--src/mixer.c38
-rw-r--r--src/synth.c60
3 files changed, 73 insertions, 31 deletions
diff --git a/src/audio.c b/src/audio.c
index 85f417d..d0a1e63 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -161,10 +161,12 @@ error_stream_flush:
}
ssize_t xas_audio_stream_read(xas_audio_stream *stream,
- void *samples,
+ void **samples,
size_t count) {
+ *samples = stream + 1;
+
return stream->fill(stream->ctx,
- samples,
+ *samples,
count,
stream);
}
diff --git a/src/mixer.c b/src/mixer.c
index 8007cae..3fc1ac9 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -34,11 +34,11 @@ static void mixer_apply_int16_t_stereo(int16_t *dest,
static ssize_t mixer_fill(xas_mixer *mixer,
void *samples,
- size_t count) {
- ssize_t ret = 0;
+ size_t count,
+ xas_audio_stream *output) {
+ ssize_t total = 0;
- xas_mixer_input *input = mixer->inputs,
- *output = mixer->output;
+ xas_mixer_input *input = mixer->inputs;
void (*mixer_apply)(int16_t *,
int16_t *,
@@ -54,29 +54,34 @@ static ssize_t mixer_fill(xas_mixer *mixer,
while (input) {
xas_mixer_input *next = input->next;
+ int16_t *buf;
ssize_t readlen;
if ((readlen = xas_audio_stream_read(input->stream,
- mixer->buf,
+ (void **)&buf,
count)) < 0) {
goto error_audio_read_stream;
}
- mixer_apply((int16_t *)mixer->buf,
- (int16_t *)(input + 1),
+ mixer_apply((int16_t *)(mixer->buf),
+ buf,
readlen,
input->bias_l,
input->bias_r);
- if (ret < readlen) {
- ret = readlen;
+ if (total < readlen) {
+ total = readlen;
}
input = next;
}
- return ret;
+ memcpy(samples,
+ mixer->buf,
+ total * output->sample_size * output->channels);
+
+ return total;
error_audio_read_stream:
return -1;
@@ -126,7 +131,7 @@ void xas_mixer_destroy(xas_mixer *mixer) {
xas_mixer_input *input = mixer->inputs;
while (input) {
- xas_mixer_input *next = input;
+ xas_mixer_input *next = input->next;
free(input);
@@ -138,6 +143,10 @@ void xas_mixer_destroy(xas_mixer *mixer) {
free(mixer);
}
+xas_audio_stream *xas_mixer_output(xas_mixer *mixer) {
+ return mixer->output;
+}
+
static inline void input_set_pan(xas_mixer_input *input, float pan) {
float angle,
term,
@@ -165,7 +174,6 @@ xas_mixer_input *xas_mixer_input_add(xas_mixer *mixer,
if (stream->sample_size != mixer->output->sample_size
|| stream->sample_rate != mixer->output->sample_rate
- || stream->channels != mixer->output->channels
|| stream->buffer_size != mixer->buffer_size) {
errno = EINVAL;
@@ -178,12 +186,16 @@ xas_mixer_input *xas_mixer_input_add(xas_mixer *mixer,
input->stream = stream;
input->gain = gain;
+ input->next = NULL;
input_set_pan(input, pan);
if (mixer->inputs == NULL) {
mixer->inputs = input;
- mixer->last = NULL;
+ mixer->last = input;
+ } else {
+ mixer->last->next = input;
+ mixer->last = input;
}
return input;
diff --git a/src/synth.c b/src/synth.c
index 9b18daf..a482875 100644
--- a/src/synth.c
+++ b/src/synth.c
@@ -2,33 +2,61 @@
#include <xas/synth.h>
-xas_synth *xas_synth_new(size_t sample_rate,
- xas_synth_callback_sample sample,
- xas_synth_callback_destroy destroy,
- void *ctx) {
+static ssize_t synth_fill(xas_synth *synth,
+ int16_t *samples,
+ size_t count,
+ xas_audio_stream *stream) {
+ size_t i;
+
+ for (i=0; i<count; i++) {
+ samples[i] = synth->sample(synth, synth->ctx);
+ }
+
+ return count;
+}
+
+static void synth_cleanup(xas_synth *synth, xas_audio_stream *stream) {
+ if (synth->cleanup) {
+ synth->cleanup(synth, synth->ctx);
+ }
+
+ 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_synth_callback_cleanup cleanup,
+ void *ctx) {
+ xas_audio_stream *stream;
xas_synth *synth;
if ((synth = malloc(sizeof(*synth))) == NULL) {
goto error_malloc_synth;
}
+ synth->sample_size = sample_size;
synth->sample_rate = sample_rate;
synth->sample = sample;
- synth->destroy = destroy;
+ synth->cleanup = cleanup;
synth->ctx = ctx;
- return synth;
+ if ((stream = xas_audio_stream_new_source((xas_audio_fill)synth_fill,
+ (xas_audio_cleanup)synth_cleanup,
+ synth,
+ sample_size,
+ sample_rate,
+ XAS_AUDIO_STREAM_MONO,
+ buffer_size)) == NULL) {
+ goto error_audio_stream_new_source;
+ }
-error_malloc_synth:
- return NULL;
-}
+ return stream;
-void xas_synth_destroy(xas_synth *synth) {
- if (synth->destroy) {
- synth->destroy(synth, synth->ctx);
- }
-}
+error_audio_stream_new_source:
+ free(synth);
-int16_t xas_synth_sample(xas_synth *synth) {
- return synth->sample(synth, synth->ctx);
+error_malloc_synth:
+ return NULL;
}