summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2016-01-12 11:43:20 +0100
committerWim Taymans <wtaymans@redhat.com>2016-01-12 11:43:20 +0100
commit4d47d43a13411d04ae3210465880daceb50dfd8e (patch)
tree2e8f6d591dca28296cdea438a318394f597148ca
parent8a8b12189e9f3e7c7c37ab9f8cfdcd1d837ae723 (diff)
audio-channel-mixer: add more formats
Add support for float and int16 mixing Remove in-place processing, this simplifies things as we won't be using it. Don't do clipping for float audio formats
-rw-r--r--gst-libs/gst/audio/audio-channel-mixer.c105
1 files changed, 64 insertions, 41 deletions
diff --git a/gst-libs/gst/audio/audio-channel-mixer.c b/gst-libs/gst/audio/audio-channel-mixer.c
index a850630ae..bb010d059 100644
--- a/gst-libs/gst/audio/audio-channel-mixer.c
+++ b/gst-libs/gst/audio/audio-channel-mixer.c
@@ -710,46 +710,76 @@ gst_audio_channel_mixer_setup_matrix (GstAudioChannelMixer * mix)
#endif
}
-/* IMPORTANT: out_data == in_data is possible, make sure to not overwrite data
- * you might need later on! */
static void
-gst_audio_channel_mixer_mix_int (GstAudioChannelMixer * mix,
+gst_audio_channel_mixer_mix_int16 (GstAudioChannelMixer * mix,
+ const gint16 * in_data, gint16 * out_data, gint samples)
+{
+ gint in, out, n;
+ gint32 res;
+ gint inchannels, outchannels;
+
+ inchannels = mix->in_channels;
+ outchannels = mix->out_channels;
+
+ for (n = 0; n < samples; n++) {
+ for (out = 0; out < outchannels; out++) {
+ /* convert */
+ res = 0;
+ for (in = 0; in < inchannels; in++)
+ res += in_data[n * inchannels + in] * mix->matrix_int[in][out];
+
+ /* remove factor from int matrix */
+ res = res >> INT_MATRIX_FACTOR_EXPONENT;
+ out_data[n * outchannels + out] = CLAMP (res, G_MININT16, G_MAXINT16);
+ }
+ }
+}
+
+static void
+gst_audio_channel_mixer_mix_int32 (GstAudioChannelMixer * mix,
const gint32 * in_data, gint32 * out_data, gint samples)
{
gint in, out, n;
gint64 res;
- gboolean backwards;
gint inchannels, outchannels;
- gint32 *tmp = (gint32 *) mix->tmp;
-
- g_return_if_fail (mix->tmp != NULL);
inchannels = mix->in_channels;
outchannels = mix->out_channels;
- backwards = outchannels > inchannels;
- /* FIXME: use orc here? */
- for (n = (backwards ? samples - 1 : 0); n < samples && n >= 0;
- backwards ? n-- : n++) {
+ for (n = 0; n < samples; n++) {
for (out = 0; out < outchannels; out++) {
/* convert */
res = 0;
- for (in = 0; in < inchannels; in++) {
+ for (in = 0; in < inchannels; in++)
res += in_data[n * inchannels + in] * (gint64) mix->matrix_int[in][out];
- }
/* remove factor from int matrix */
res = res >> INT_MATRIX_FACTOR_EXPONENT;
+ out_data[n * outchannels + out] = CLAMP (res, G_MININT32, G_MAXINT32);
+ }
+ }
+}
+
+static void
+gst_audio_channel_mixer_mix_float (GstAudioChannelMixer * mix,
+ const gfloat * in_data, gfloat * out_data, gint samples)
+{
+ gint in, out, n;
+ gfloat res;
+ gint inchannels, outchannels;
+
+ inchannels = mix->in_channels;
+ outchannels = mix->out_channels;
+
+ for (n = 0; n < samples; n++) {
+ for (out = 0; out < outchannels; out++) {
+ /* convert */
+ res = 0.0;
+ for (in = 0; in < inchannels; in++)
+ res += in_data[n * inchannels + in] * mix->matrix[in][out];
- /* clip (shouldn't we use doubles instead as intermediate format?) */
- if (res < G_MININT32)
- res = G_MININT32;
- else if (res > G_MAXINT32)
- res = G_MAXINT32;
- tmp[out] = res;
+ out_data[n * outchannels + out] = res;
}
- memcpy (&out_data[n * outchannels], mix->tmp,
- sizeof (gint32) * outchannels);
}
}
@@ -759,35 +789,20 @@ gst_audio_channel_mixer_mix_double (GstAudioChannelMixer * mix,
{
gint in, out, n;
gdouble res;
- gboolean backwards;
gint inchannels, outchannels;
- gdouble *tmp = (gdouble *) mix->tmp;
-
- g_return_if_fail (mix->tmp != NULL);
inchannels = mix->in_channels;
outchannels = mix->out_channels;
- backwards = outchannels > inchannels;
- /* FIXME: use orc here? */
- for (n = (backwards ? samples - 1 : 0); n < samples && n >= 0;
- backwards ? n-- : n++) {
+ for (n = 0; n < samples; n++) {
for (out = 0; out < outchannels; out++) {
/* convert */
res = 0.0;
- for (in = 0; in < inchannels; in++) {
+ for (in = 0; in < inchannels; in++)
res += in_data[n * inchannels + in] * mix->matrix[in][out];
- }
- /* clip (shouldn't we use doubles instead as intermediate format?) */
- if (res < -1.0)
- res = -1.0;
- else if (res > 1.0)
- res = 1.0;
- tmp[out] = res;
+ out_data[n * outchannels + out] = res;
}
- memcpy (&out_data[n * outchannels], mix->tmp,
- sizeof (gdouble) * outchannels);
}
}
@@ -814,7 +829,9 @@ gst_audio_channel_mixer_new (GstAudioChannelMixerFlags flags,
GstAudioChannelMixer *mix;
gint i;
- g_return_val_if_fail (format == GST_AUDIO_FORMAT_S32
+ g_return_val_if_fail (format == GST_AUDIO_FORMAT_S16
+ || format == GST_AUDIO_FORMAT_S32
+ || format == GST_AUDIO_FORMAT_F32
|| format == GST_AUDIO_FORMAT_F64, NULL);
g_return_val_if_fail (in_channels > 0 && in_channels < 64, NULL);
g_return_val_if_fail (out_channels > 0 && out_channels < 64, NULL);
@@ -833,8 +850,14 @@ gst_audio_channel_mixer_new (GstAudioChannelMixerFlags flags,
gst_audio_channel_mixer_setup_matrix (mix);
switch (mix->format) {
+ case GST_AUDIO_FORMAT_S16:
+ mix->func = (MixerFunc) gst_audio_channel_mixer_mix_int16;
+ break;
case GST_AUDIO_FORMAT_S32:
- mix->func = (MixerFunc) gst_audio_channel_mixer_mix_int;
+ mix->func = (MixerFunc) gst_audio_channel_mixer_mix_int32;
+ break;
+ case GST_AUDIO_FORMAT_F32:
+ mix->func = (MixerFunc) gst_audio_channel_mixer_mix_float;
break;
case GST_AUDIO_FORMAT_F64:
mix->func = (MixerFunc) gst_audio_channel_mixer_mix_double;