diff options
Diffstat (limited to 'src/mixer.c')
-rw-r--r-- | src/mixer.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/src/mixer.c b/src/mixer.c index 3fc1ac9..ba40215 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -7,7 +7,7 @@ #include <xas/audio.h> #include <xas/mixer.h> -static void mixer_apply_int16_t_mono(int16_t *dest, +static void mixer_apply_mono_to_mono(int16_t *dest, int16_t *src, size_t count, float bias_l, @@ -19,16 +19,41 @@ static void mixer_apply_int16_t_mono(int16_t *dest, } } -static void mixer_apply_int16_t_stereo(int16_t *dest, +static void mixer_apply_mono_to_stereo(int16_t *dest, int16_t *src, size_t count, float bias_l, float bias_r) { size_t i; - for (i=0; i<2*count; i+=2) { - dest[i] += (int16_t)roundf(src[i] * bias_l); - dest[i+1] += (int16_t)roundf(src[i+1] * bias_r); + for (i=0; i<count; i++) { + dest[i] += src[i]; + dest[i+1] += src[i]; + } +} + +static void mixer_apply_stereo_to_stereo(int16_t *dest, + int16_t *src, + size_t count, + float bias_l, + float bias_r) { + size_t i; + + for (i=0; i<count; i++) { + dest[i] += src[i]; + dest[i+1] += src[i+1]; + } +} + +static void mixer_apply_stereo_to_mono(int16_t *dest, + int16_t *src, + size_t count, + float bias_l, + float bias_r) { + size_t i; + + for (i=0; i<count; i++) { + dest[i] += (src[i] + src[i+1]) / 2; } } @@ -40,24 +65,34 @@ static ssize_t mixer_fill(xas_mixer *mixer, xas_mixer_input *input = mixer->inputs; - void (*mixer_apply)(int16_t *, - int16_t *, - size_t, - float, - float) = (output->channels == 2)? - mixer_apply_int16_t_stereo: - mixer_apply_int16_t_mono; - memset(mixer->buf, '\0', output->sample_size * output->channels * output->buffer_size); while (input) { + void (*mixer_apply)(int16_t *, + int16_t *, + size_t, + float, + float); + xas_mixer_input *next = input->next; int16_t *buf; ssize_t readlen; + if (output->channels == 2 && input->stream->channels == 2) { + mixer_apply = mixer_apply_stereo_to_stereo; + } else if (output->channels == 2 && input->stream->channels == 1) { + mixer_apply = mixer_apply_mono_to_stereo; + } else if (output->channels == 1 && input->stream->channels == 1) { + mixer_apply = mixer_apply_mono_to_mono; + } else if (output->channels == 1 && input->stream->channels == 2) { + mixer_apply = mixer_apply_stereo_to_mono; + } else { + goto error_invalid_input; + } + if ((readlen = xas_audio_stream_read(input->stream, (void **)&buf, count)) < 0) { @@ -83,6 +118,7 @@ static ssize_t mixer_fill(xas_mixer *mixer, return total; +error_invalid_input: error_audio_read_stream: return -1; } @@ -140,6 +176,7 @@ void xas_mixer_destroy(xas_mixer *mixer) { xas_audio_stream_destroy(mixer->output); + free(mixer->buf); free(mixer); } |