summaryrefslogtreecommitdiffstats
path: root/src/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mixer.c')
-rw-r--r--src/mixer.c63
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);
}