summaryrefslogtreecommitdiff
path: root/gst/audioconvert
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2015-11-06 16:03:20 +0100
committerWim Taymans <wtaymans@redhat.com>2015-11-06 16:03:20 +0100
commit9fbe0386d0b5c29c0e8b308dc08ef4d91e58eb0c (patch)
treee6bf0080d39ceae62eaf64c334419d7fc6190d09 /gst/audioconvert
parent7f5104f52fca6b8a1e74d2d3c3913ced6059b11e (diff)
channelmix: simplify API a little
Remove the format and layout from the mix_samples function and use the format when creating the channel mixer object. Also use a flag to handle the unlikely case of non-interleaved samples like we do elsewhere.
Diffstat (limited to 'gst/audioconvert')
-rw-r--r--gst/audioconvert/audioconvert.c8
-rw-r--r--gst/audioconvert/gstchannelmix.c177
-rw-r--r--gst/audioconvert/gstchannelmix.h9
3 files changed, 102 insertions, 92 deletions
diff --git a/gst/audioconvert/audioconvert.c b/gst/audioconvert/audioconvert.c
index 7c7f84f92..0e62e8543 100644
--- a/gst/audioconvert/audioconvert.c
+++ b/gst/audioconvert/audioconvert.c
@@ -76,7 +76,6 @@ struct _GstAudioConverter
AudioConvertFunc convert_in;
- GstAudioFormat mix_format;
gboolean mix_passthrough;
GstAudioChannelMix *mix;
@@ -263,8 +262,8 @@ gst_audio_converter_new (GstAudioInfo * in, GstAudioInfo * out,
}
/* step 3, channel mix */
- convert->mix_format = format;
- convert->mix = gst_audio_channel_mix_new (flags, in->channels, in->position,
+ convert->mix =
+ gst_audio_channel_mix_new (flags, format, in->channels, in->position,
out->channels, out->position);
convert->mix_passthrough =
gst_audio_channel_mix_is_passthrough (convert->mix);
@@ -427,8 +426,7 @@ gst_audio_converter_samples (GstAudioConverter * convert,
else
outbuf = tmpbuf;
- gst_audio_channel_mix_samples (convert->mix, convert->mix_format,
- convert->in.layout, src, outbuf, samples);
+ gst_audio_channel_mix_samples (convert->mix, src, outbuf, samples);
src = outbuf;
}
/* step 4, optional convert F64 -> S32 for quantize */
diff --git a/gst/audioconvert/gstchannelmix.c b/gst/audioconvert/gstchannelmix.c
index 832951e7d..de3ceea85 100644
--- a/gst/audioconvert/gstchannelmix.c
+++ b/gst/audioconvert/gstchannelmix.c
@@ -31,9 +31,13 @@
#define INT_MATRIX_FACTOR_EXPONENT 10
+typedef void (*MixFunc) (GstAudioChannelMix * mix, const gpointer src,
+ gpointer dst, gint samples);
+
struct _GstAudioChannelMix
{
GstAudioChannelMixFlags flags;
+ GstAudioFormat format;
gint in_channels;
gint out_channels;
@@ -49,6 +53,8 @@ struct _GstAudioChannelMix
* this is matrix * (2^10) as integers */
gint **matrix_int;
+ MixFunc func;
+
gpointer tmp;
};
@@ -681,72 +687,6 @@ gst_audio_channel_mix_setup_matrix (GstAudioChannelMix * mix)
#endif
}
-/**
- * gst_audio_channel_mix_new:
- * @flags:
- * @in_channels:
- * @in_position:
- * @out_channels:
- * @out_position:
- *
- * Create a new channel mixer object.
- *
- * Returns: a new #GstAudioChannelMix object. Free with gst_audio_channel_mix_free()
- * after usage.
- */
-GstAudioChannelMix *
-gst_audio_channel_mix_new (GstAudioChannelMixFlags flags,
- gint in_channels,
- GstAudioChannelPosition in_position[64],
- gint out_channels, GstAudioChannelPosition out_position[64])
-{
- GstAudioChannelMix *mix;
- gint i;
-
- mix = g_slice_new0 (GstAudioChannelMix);
- mix->flags = flags;
- mix->in_channels = in_channels;
- mix->out_channels = out_channels;
- for (i = 0; i < 64; i++) {
- mix->in_position[i] = in_position[i];
- mix->out_position[i] = out_position[i];
- }
- gst_audio_channel_mix_setup_matrix (mix);
-
- return mix;
-}
-
-/**
- * gst_audio_channel_mix_is_passthrough:
- * @mix: a #GstAudioChannelMix
- *
- * Check if @mix is in passthrough.
- *
- * Returns: %TRUE is @mix is passthrough.
- */
-gboolean
-gst_audio_channel_mix_is_passthrough (GstAudioChannelMix * mix)
-{
- gint i;
- guint64 in_mask, out_mask;
-
- /* only NxN matrices can be identities */
- if (mix->in_channels != mix->out_channels)
- return FALSE;
-
- /* passthrough for 1->1 channels (MONO and NONE position are the same here) */
- if (mix->in_channels == 1 && mix->out_channels == 1)
- return TRUE;
-
- /* passthrough if both channel masks are the same */
- in_mask = out_mask = 0;
- for (i = 0; i < mix->in_channels; i++) {
- in_mask |= mix->in_position[i];
- out_mask |= mix->out_position[i];
- }
- return in_mask == out_mask;
-}
-
/* IMPORTANT: out_data == in_data is possible, make sure to not overwrite data
* you might need later on! */
static void
@@ -829,6 +769,91 @@ gst_audio_channel_mix_mix_double (GstAudioChannelMix * mix,
}
/**
+ * gst_audio_channel_mix_new:
+ * @flags:
+ * @in_channels:
+ * @in_position:
+ * @out_channels:
+ * @out_position:
+ *
+ * Create a new channel mixer object.
+ *
+ * Returns: a new #GstAudioChannelMix object. Free with gst_audio_channel_mix_free()
+ * after usage.
+ */
+GstAudioChannelMix *
+gst_audio_channel_mix_new (GstAudioChannelMixFlags flags,
+ GstAudioFormat format,
+ gint in_channels,
+ GstAudioChannelPosition in_position[64],
+ gint out_channels, GstAudioChannelPosition out_position[64])
+{
+ GstAudioChannelMix *mix;
+ gint i;
+
+ g_return_val_if_fail (format == GST_AUDIO_FORMAT_S32
+ || format == GST_AUDIO_FORMAT_F64, NULL);
+ g_return_val_if_fail (in_channels > 0, NULL);
+ g_return_val_if_fail (out_channels > 0, NULL);
+
+ mix = g_slice_new0 (GstAudioChannelMix);
+ mix->flags = flags;
+ mix->format = format;
+ mix->in_channels = in_channels;
+ mix->out_channels = out_channels;
+
+ for (i = 0; i < 64; i++) {
+ mix->in_position[i] = in_position[i];
+ mix->out_position[i] = out_position[i];
+ }
+ gst_audio_channel_mix_setup_matrix (mix);
+
+ switch (mix->format) {
+ case GST_AUDIO_FORMAT_S32:
+ mix->func = (MixFunc) gst_audio_channel_mix_mix_int;
+ break;
+ case GST_AUDIO_FORMAT_F64:
+ mix->func = (MixFunc) gst_audio_channel_mix_mix_double;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ return mix;
+}
+
+/**
+ * gst_audio_channel_mix_is_passthrough:
+ * @mix: a #GstAudioChannelMix
+ *
+ * Check if @mix is in passthrough.
+ *
+ * Returns: %TRUE is @mix is passthrough.
+ */
+gboolean
+gst_audio_channel_mix_is_passthrough (GstAudioChannelMix * mix)
+{
+ gint i;
+ guint64 in_mask, out_mask;
+
+ /* only NxN matrices can be identities */
+ if (mix->in_channels != mix->out_channels)
+ return FALSE;
+
+ /* passthrough for 1->1 channels (MONO and NONE position are the same here) */
+ if (mix->in_channels == 1 && mix->out_channels == 1)
+ return TRUE;
+
+ /* passthrough if both channel masks are the same */
+ in_mask = out_mask = 0;
+ for (i = 0; i < mix->in_channels; i++) {
+ in_mask |= mix->in_position[i];
+ out_mask |= mix->out_position[i];
+ }
+ return in_mask == out_mask;
+}
+
+/**
* gst_audio_channel_mix_samples:
* @mix: a #GstAudioChannelMix
* @format: a #GstAudioFormat
@@ -841,25 +866,11 @@ gst_audio_channel_mix_mix_double (GstAudioChannelMix * mix,
* @in_data and @out_data need to be in @format and @layout.
*/
void
-gst_audio_channel_mix_samples (GstAudioChannelMix * mix, GstAudioFormat format,
- GstAudioLayout layout, const gpointer in_data, gpointer out_data,
- gint samples)
+gst_audio_channel_mix_samples (GstAudioChannelMix * mix,
+ const gpointer in_data, gpointer out_data, gint samples)
{
g_return_if_fail (mix != NULL);
g_return_if_fail (mix->matrix != NULL);
- g_return_if_fail (layout == GST_AUDIO_LAYOUT_INTERLEAVED);
- switch (format) {
- case GST_AUDIO_FORMAT_S32:
- gst_audio_channel_mix_mix_int (mix, (const gint32 *) in_data,
- (gint32 *) out_data, samples);
- break;
- case GST_AUDIO_FORMAT_F64:
- gst_audio_channel_mix_mix_double (mix, (const gdouble *) in_data,
- (gdouble *) out_data, samples);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
+ mix->func (mix, in_data, out_data, samples);
}
diff --git a/gst/audioconvert/gstchannelmix.h b/gst/audioconvert/gstchannelmix.h
index d7f6a1030..cbd0ddc6c 100644
--- a/gst/audioconvert/gstchannelmix.h
+++ b/gst/audioconvert/gstchannelmix.h
@@ -31,6 +31,7 @@ typedef struct _GstAudioChannelMix GstAudioChannelMix;
/**
* GstAudioChannelMixFlags:
* @GST_AUDIO_CHANNEL_MIX_FLAGS_NONE: no flag
+ * @GST_AUDIO_CHANNEL_MIX_FLAGS_NON_INTERLEAVED: channels are not interleaved
* @GST_AUDIO_CHANNEL_MIX_FLAGS_UNPOSITIONED_IN: input channels are explicitly unpositioned
* @GST_AUDIO_CHANNEL_MIX_FLAGS_UNPOSITIONED_OUT: output channels are explicitly unpositioned
*
@@ -38,11 +39,13 @@ typedef struct _GstAudioChannelMix GstAudioChannelMix;
*/
typedef enum {
GST_AUDIO_CHANNEL_MIX_FLAGS_NONE = 0,
- GST_AUDIO_CHANNEL_MIX_FLAGS_UNPOSITIONED_IN = (1 << 0),
- GST_AUDIO_CHANNEL_MIX_FLAGS_UNPOSITIONED_OUT = (1 << 1)
+ GST_AUDIO_CHANNEL_MIX_FLAGS_NON_INTERLEAVED = (1 << 0),
+ GST_AUDIO_CHANNEL_MIX_FLAGS_UNPOSITIONED_IN = (1 << 1),
+ GST_AUDIO_CHANNEL_MIX_FLAGS_UNPOSITIONED_OUT = (1 << 2)
} GstAudioChannelMixFlags;
GstAudioChannelMix * gst_audio_channel_mix_new (GstAudioChannelMixFlags flags,
+ GstAudioFormat format,
gint in_channels,
GstAudioChannelPosition in_position[64],
gint out_channels,
@@ -58,8 +61,6 @@ gboolean gst_audio_channel_mix_is_passthrough (GstAudioChannelMix *mix);
* Do actual mixing.
*/
void gst_audio_channel_mix_samples (GstAudioChannelMix * mix,
- GstAudioFormat format,
- GstAudioLayout layout,
const gpointer in_data,
gpointer out_data,
gint samples);