channelmix: simplify API a little
authorWim Taymans <wtaymans@redhat.com>
Fri, 6 Nov 2015 15:03:20 +0000 (16:03 +0100)
committerWim Taymans <wtaymans@redhat.com>
Fri, 6 Nov 2015 15:03:20 +0000 (16:03 +0100)
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.

gst/audioconvert/audioconvert.c
gst/audioconvert/gstchannelmix.c
gst/audioconvert/gstchannelmix.h

index 7c7f84f..0e62e85 100644 (file)
@@ -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 */
index 832951e..de3ceea 100644 (file)
 
 #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);
 }
index d7f6a10..cbd0ddc 100644 (file)
@@ -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);