audio-resampler: add more functions
authorWim Taymans <wtaymans@redhat.com>
Wed, 10 Feb 2016 12:31:11 +0000 (13:31 +0100)
committerWim Taymans <wtaymans@redhat.com>
Mon, 28 Mar 2016 11:25:51 +0000 (13:25 +0200)
Use some macros to generate more functions

gst-libs/gst/audio/audio-resampler-x86.h
gst-libs/gst/audio/audio-resampler.c
win32/common/libgstaudio.def

index 9f96685..44981cd 100644 (file)
@@ -21,7 +21,8 @@
 #include <xmmintrin.h>
 
 static inline void
-inner_product_gfloat_none_1_sse (gfloat * o, const gfloat * a, const gfloat * b, gint len, gpointer icoeff, gint oversample)
+inner_product_gfloat_none_1_sse (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint oversample)
 {
   gint i = 0;
   __m128 sum = _mm_setzero_ps ();
@@ -40,7 +41,8 @@ inner_product_gfloat_none_1_sse (gfloat * o, const gfloat * a, const gfloat * b,
 }
 
 static inline void
-inner_product_gfloat_linear_1_sse (gfloat * o, const gfloat * a, const gfloat * b, gint len, gpointer icoeff, gint oversample)
+inner_product_gfloat_linear_1_sse (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint oversample)
 {
   gint i = 0;
   __m128 sum = _mm_setzero_ps (), t, b0;
@@ -68,7 +70,8 @@ inner_product_gfloat_linear_1_sse (gfloat * o, const gfloat * a, const gfloat *
 }
 
 static inline void
-inner_product_gfloat_none_2_sse (gfloat * o, const gfloat * a, const gfloat * b, gint len, gpointer icoeff, gint oversample)
+inner_product_gfloat_none_2_sse (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint oversample)
 {
   gint i = 0;
   __m128 sum = _mm_setzero_ps (), t;
@@ -103,7 +106,8 @@ MAKE_RESAMPLE_FUNC (gfloat, linear, 1, sse);
 #include <emmintrin.h>
 
 static inline void
-inner_product_gint16_none_1_sse2 (gint16 * o, const gint16 * a, const gint16 * b, gint len, gpointer icoeff, gint oversample)
+inner_product_gint16_none_1_sse2 (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint oversample)
 {
   gint i = 0;
   __m128i sum, ta, tb;
@@ -130,8 +134,8 @@ inner_product_gint16_none_1_sse2 (gint16 * o, const gint16 * a, const gint16 * b
 }
 
 static inline void
-inner_product_gdouble_none_1_sse2 (gdouble * o, const gdouble * a, const gdouble * b,
-    gint len, gpointer icoeff, gint oversample)
+inner_product_gdouble_none_1_sse2 (gdouble * o, const gdouble * a,
+    const gdouble * b, gint len, const gdouble * icoeff, gint oversample)
 {
   gint i = 0;
   __m128d sum = _mm_setzero_pd ();
@@ -155,7 +159,8 @@ inner_product_gdouble_none_1_sse2 (gdouble * o, const gdouble * a, const gdouble
 }
 
 static inline void
-inner_product_gint16_none_2_sse2 (gint16 * o, const gint16 * a, const gint16 * b, gint len, gpointer icoeff, gint oversample)
+inner_product_gint16_none_2_sse2 (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint oversample)
 {
   gint i = 0;
   __m128i sum, ta, tb, t1;
@@ -186,8 +191,8 @@ inner_product_gint16_none_2_sse2 (gint16 * o, const gint16 * a, const gint16 * b
 }
 
 static inline void
-inner_product_gdouble_none_2_sse2 (gdouble * o, const gdouble * a, const gdouble * b,
-    gint len, gpointer icoeff, gint oversample)
+inner_product_gdouble_none_2_sse2 (gdouble * o, const gdouble * a,
+    const gdouble * b, gint len, const gdouble * icoeff, gint oversample)
 {
   gint i = 0;
   __m128d sum = _mm_setzero_pd (), t;
@@ -222,8 +227,8 @@ MAKE_RESAMPLE_FUNC (gdouble, none, 2, sse2);
 #include <smmintrin.h>
 
 static inline void
-inner_product_gint32_none_1_sse41 (gint32 * o, const gint32 * a, const gint32 * b,
-    gint len, gpointer icoeff, gint oversample)
+inner_product_gint32_none_1_sse41 (gint32 * o, const gint32 * a,
+    const gint32 * b, gint len, const gint32 * icoeff, gint oversample)
 {
   gint i = 0;
   __m128i sum, ta, tb;
@@ -277,11 +282,11 @@ audio_resampler_check_x86 (const gchar *option)
     GST_DEBUG ("enable SSE2 optimisations");
     resample_gint16_none_1 = resample_gint16_none_1_sse2;
     resample_gfloat_none_1 = resample_gfloat_none_1_sse;
-    resample_gfloat_linear_1 = resample_gfloat_linear_1_sse;
     resample_gfloat_none_2 = resample_gfloat_none_2_sse;
     resample_gdouble_none_1 = resample_gdouble_none_1_sse2;
     resample_gint16_none_2 = resample_gint16_none_2_sse2;
     resample_gdouble_none_2 = resample_gdouble_none_2_sse2;
+    resample_gfloat_linear_1 = resample_gfloat_linear_1_sse;
 #endif
   } else if (!strcmp (option, "sse41")) {
 #if defined (HAVE_SMMINTRIN_H) && defined(__SSE4_1__)
index c5fde62..4d843e1 100644 (file)
@@ -479,109 +479,77 @@ GET_TAPS_LINEAR_FUNC (gint32);
 GET_TAPS_LINEAR_FUNC (gfloat);
 GET_TAPS_LINEAR_FUNC (gdouble);
 
-static inline void
-inner_product_gint16_none_1_c (gint16 * o, const gint16 * a,
-    const gint16 * b, gint len, gpointer icoeff, gint oversample)
-{
-  gint i;
-  gint32 res = 0;
-
-  for (i = 0; i < len; i++)
-    res += (gint32) a[i] * (gint32) b[i];
-
-  res = (res + (1 << (PRECISION_S16 - 1))) >> PRECISION_S16;
-  *o = CLAMP (res, -(1L << 15), (1L << 15) - 1);
-}
-
-static inline void
-inner_product_gint16_linear_1_c (gint16 * o, const gint16 * a, const gint16 * b,
-    gint len, gpointer icoeff, gint oversample)
-{
-  gint i;
-  gint32 res, res1 = 0, res2 = 0;
-  gint16 *ic = icoeff;
-
-  for (i = 0; i < len; i++) {
-    res1 += (gint32) a[i] * (gint32) b[i * oversample];
-    res2 += (gint32) a[i] * (gint32) b[i * oversample + 1];
-  }
-  res = (res1 >> PRECISION_S16) * ic[0] + (res2 >> PRECISION_S16) * ic[1];
-  res = (res + (1 << (PRECISION_S16 - 1))) >> PRECISION_S16;
-  *o = CLAMP (res, -(1L << 15), (1L << 15) - 1);
-}
-
-static inline void
-inner_product_gint32_none_1_c (gint32 * o, const gint32 * a, const gint32 * b,
-    gint len, gpointer icoeff, gint oversample)
-{
-  gint i;
-  gint64 res = 0;
-
-  for (i = 0; i < len; i++)
-    res += (gint64) a[i] * (gint64) b[i];
-
-  res = (res + (1 << (PRECISION_S32 - 1))) >> PRECISION_S32;
-  *o = CLAMP (res, -(1L << 31), (1L << 31) - 1);
-}
-
-static inline void
-inner_product_gfloat_none_1_c (gfloat * o, const gfloat * a, const gfloat * b,
-    gint len, gpointer icoeff, gint oversample)
-{
-  gint i;
-  gfloat res = 0.0;
-
-  for (i = 0; i < len; i++)
-    res += a[i] * b[i];
-
-  *o = res;
+#define INNER_PRODUCT_INT_NONE_FUNC(type,type2,prec,limit)      \
+static inline void                                              \
+inner_product_##type##_none_1_c (type * o, const type * a,      \
+    const type * b, gint len, const type *ic, gint oversample)  \
+{                                                               \
+  gint i;                                                       \
+  type2 res = 0;                                                \
+                                                                \
+  for (i = 0; i < len; i++)                                     \
+    res += (type2) a[i] * (type2) b[i];                         \
+                                                                \
+  res = (res + (1 << ((prec) - 1))) >> (prec);                  \
+  *o = CLAMP (res, -(limit), (limit) - 1);                      \
 }
 
-static inline void
-inner_product_gfloat_linear_1_c (gfloat * o, const gfloat * a, const gfloat * b,
-    gint len, gpointer icoeff, gint oversample)
-{
-  gint i;
-  gfloat res, res1 = 0.0, res2 = 0.0, *ic = icoeff;
-
-  for (i = 0; i < len; i++) {
-    res1 += a[i] * b[i * oversample];
-    res2 += a[i] * b[i * oversample + 1];
-  }
-  res = res1 * ic[0] + res2 * ic[1];
+INNER_PRODUCT_INT_NONE_FUNC (gint16, gint32, PRECISION_S16, 1L << 15);
+INNER_PRODUCT_INT_NONE_FUNC (gint32, gint64, PRECISION_S32, 1L << 31);
 
-  *o = res;
+#define INNER_PRODUCT_INT_LINEAR_FUNC(type,type2,prec,limit)    \
+static inline void                                              \
+inner_product_##type##_linear_1_c (type * o, const type * a,    \
+    const type * b, gint len, const type *ic, gint oversample)  \
+{                                                               \
+  gint i;                                                       \
+  type2 res, res1 = 0, res2 = 0;                                \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    res1 += (type2) a[i] * (type2) b[i * oversample];           \
+    res2 += (type2) a[i] * (type2) b[i * oversample + 1];       \
+  }                                                             \
+  res = (res1 >> (prec)) * ic[0] + (res2 >> (prec)) * ic[1];    \
+  res = (res + (1 << ((prec) - 1))) >> (prec);                  \
+  *o = CLAMP (res, -(limit), (limit) - 1);                      \
 }
 
-static inline void
-inner_product_gdouble_none_1_c (gdouble * o, const gdouble * a,
-    const gdouble * b, gint len, gpointer icoeff, gint oversample)
-{
-  gint i;
-  gdouble res = 0.0;
-
-  for (i = 0; i < len; i++)
-    res += a[i] * b[i];
+INNER_PRODUCT_INT_LINEAR_FUNC (gint16, gint32, PRECISION_S16, 1L << 15);
+INNER_PRODUCT_INT_LINEAR_FUNC (gint32, gint64, PRECISION_S32, 1L << 31);
 
-  *o = res;
+#define INNER_PRODUCT_FLOAT_NONE_FUNC(type)                     \
+static inline void                                              \
+inner_product_##type##_none_1_c (type * o, const type * a,      \
+    const type * b, gint len, const type *ic, gint oversample)  \
+{                                                               \
+  gint i;                                                       \
+  type res = 0.0;                                               \
+                                                                \
+  for (i = 0; i < len; i++)                                     \
+    res += a[i] * b[i];                                         \
+                                                                \
+  *o = res;                                                     \
 }
 
-static inline void
-inner_product_gdouble_linear_1_c (gdouble * o, const gdouble * a,
-    const gdouble * b, gint len, gpointer icoeff, gint oversample)
-{
-  gint i;
-  gdouble res, res1 = 0.0, res2 = 0.0, *ic = icoeff;
-
-  for (i = 0; i < len; i++) {
-    res1 += a[i] * b[i * oversample];
-    res2 += a[i] * b[i * oversample + 1];
-  }
-  res = res1 * ic[0] + res2 * ic[1];
+INNER_PRODUCT_FLOAT_NONE_FUNC (gfloat);
+INNER_PRODUCT_FLOAT_NONE_FUNC (gdouble);
 
-  *o = res;
+#define INNER_PRODUCT_FLOAT_LINEAR_FUNC(type)                   \
+static inline void                                              \
+inner_product_##type##_linear_1_c (type * o, const type * a,    \
+    const type * b, gint len, const type *ic, gint oversample)  \
+{                                                               \
+  gint i;                                                       \
+  type res1 = 0.0, res2 = 0.0;                                  \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    res1 += a[i] * b[i * oversample];                           \
+    res2 += a[i] * b[i * oversample + 1];                       \
+  }                                                             \
+  *o = res1 * ic[0] + res2 * ic[1];                             \
 }
-
+INNER_PRODUCT_FLOAT_LINEAR_FUNC (gfloat);
+INNER_PRODUCT_FLOAT_LINEAR_FUNC (gdouble);
 
 #define MAKE_RESAMPLE_FUNC(type,inter,channels,arch)                            \
 static void                                                                     \
@@ -611,7 +579,7 @@ resample_ ##type## _ ##inter## _ ##channels## _ ##arch (GstAudioResampler * resa
                                                                                 \
       taps = get_taps_ ##type##_##inter (resampler, &samp_index, &samp_phase, icoeff);                   \
                                                                                 \
-      inner_product_ ##type##_##inter##_##channels##_##arch (op, ipp, taps, n_taps, &icoeff,oversample);     \
+      inner_product_ ##type##_##inter##_##channels##_##arch (op, ipp, taps, n_taps, icoeff, oversample);     \
       op += ostride;                                                            \
     }                                                                           \
     memmove (ip, &ip[samp_index * channels],                                    \
@@ -629,7 +597,9 @@ MAKE_RESAMPLE_FUNC (gfloat, none, 1, c);
 MAKE_RESAMPLE_FUNC (gdouble, none, 1, c);
 
 MAKE_RESAMPLE_FUNC (gint16, linear, 1, c);
+MAKE_RESAMPLE_FUNC (gint32, linear, 1, c);
 MAKE_RESAMPLE_FUNC (gfloat, linear, 1, c);
+MAKE_RESAMPLE_FUNC (gdouble, linear, 1, c);
 
 static ResampleFunc resample_funcs[] = {
   resample_gint16_none_1_c,
@@ -642,9 +612,9 @@ static ResampleFunc resample_funcs[] = {
   NULL,
 
   resample_gint16_linear_1_c,
-  NULL,
+  resample_gint32_linear_1_c,
   resample_gfloat_linear_1_c,
-  NULL,
+  resample_gdouble_linear_1_c,
   NULL,
   NULL,
   NULL,
index 1fa3dd2..839ceae 100644 (file)
@@ -154,6 +154,7 @@ EXPORTS
        gst_audio_quantize_reset
        gst_audio_quantize_samples
        gst_audio_reorder_channels
+       gst_audio_resampler_filter_interpolation_get_type
        gst_audio_resampler_filter_mode_get_type
        gst_audio_resampler_flags_get_type
        gst_audio_resampler_free