mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 02:15:31 +00:00
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
This commit is contained in:
parent
8a8b12189e
commit
4d47d43a13
1 changed files with 65 additions and 42 deletions
|
@ -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;
|
||||
|
||||
/* 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] = 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];
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue