audiowsincband: Add new windowing functions: gaussian, cos and hann
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 13 Apr 2011 15:49:22 +0000 (17:49 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 13 Apr 2011 15:52:30 +0000 (17:52 +0200)
gst/audiofx/audiowsincband.c

index c6e2a0d..05db339 100644 (file)
@@ -26,6 +26,8 @@
  * chapter 16
  * available at http://www.dspguide.com/
  *
+ * For the window functions see
+ * http://en.wikipedia.org/wiki/Window_function
  */
 
 /**
@@ -104,7 +106,10 @@ gst_gst_audio_wsincband_mode_get_type (void)
 enum
 {
   WINDOW_HAMMING = 0,
-  WINDOW_BLACKMAN
+  WINDOW_BLACKMAN,
+  WINDOW_GAUSSIAN,
+  WINDOW_COSINE,
+  WINDOW_HANN
 };
 
 #define GST_TYPE_AUDIO_WSINC_BAND_WINDOW (gst_gst_audio_wsincband_window_get_type ())
@@ -119,6 +124,12 @@ gst_gst_audio_wsincband_window_get_type (void)
           "hamming"},
       {WINDOW_BLACKMAN, "Blackman window",
           "blackman"},
+      {WINDOW_GAUSSIAN, "Gaussian window",
+          "gaussian"},
+      {WINDOW_COSINE, "Cosine window",
+          "cosine"},
+      {WINDOW_HANN, "Hann window",
+          "hann"},
       {0, NULL, NULL}
     };
 
@@ -143,6 +154,9 @@ static void gst_audio_wsincband_finalize (GObject * object);
 static gboolean gst_audio_wsincband_setup (GstAudioFilter * base,
     GstRingBufferSpec * format);
 
+
+#define POW2(x)  (x)*(x)
+
 /* Element class */
 static void
 gst_audio_wsincband_base_init (gpointer g_class)
@@ -263,13 +277,26 @@ gst_audio_wsincband_build_kernel (GstAudioWSincBand * self)
     else
       kernel_lp[i] = sin (w * (i - len / 2))
           / (i - len / 2);
-    /* Windowing */
-    if (self->window == WINDOW_HAMMING)
-      kernel_lp[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / len));
-    else
-      kernel_lp[i] *=
-          (0.42 - 0.5 * cos (2 * G_PI * i / len) +
-          0.08 * cos (4 * G_PI * i / len));
+
+    /* windowing */
+    switch (self->window) {
+      case WINDOW_HAMMING:
+        kernel_lp[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / (len - 1)));
+        break;
+      case WINDOW_BLACKMAN:
+        kernel_lp[i] *= (0.42 - 0.5 * cos (2 * G_PI * i / (len - 1)) +
+            0.08 * cos (4 * G_PI * i / (len - 1)));
+        break;
+      case WINDOW_GAUSSIAN:
+        kernel_lp[i] *= exp (-0.5 * POW2 (3.0 / len * (2 * i - (len - 1))));
+        break;
+      case WINDOW_COSINE:
+        kernel_lp[i] *= cos (G_PI * i / (len - 1) - G_PI / 2);
+        break;
+      case WINDOW_HANN:
+        kernel_lp[i] *= 0.5 * (1 - cos (2 * G_PI * i / (len - 1)));
+        break;
+    }
   }
 
   /* normalize for unity gain at DC */
@@ -289,12 +316,24 @@ gst_audio_wsincband_build_kernel (GstAudioWSincBand * self)
       kernel_hp[i] = sin (w * (i - len / 2))
           / (i - len / 2);
     /* Windowing */
-    if (self->window == WINDOW_HAMMING)
-      kernel_hp[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / len));
-    else
-      kernel_hp[i] *=
-          (0.42 - 0.5 * cos (2 * G_PI * i / len) +
-          0.08 * cos (4 * G_PI * i / len));
+    switch (self->window) {
+      case WINDOW_HAMMING:
+        kernel_hp[i] *= (0.54 - 0.46 * cos (2 * G_PI * i / (len - 1)));
+        break;
+      case WINDOW_BLACKMAN:
+        kernel_hp[i] *= (0.42 - 0.5 * cos (2 * G_PI * i / (len - 1)) +
+            0.08 * cos (4 * G_PI * i / (len - 1)));
+        break;
+      case WINDOW_GAUSSIAN:
+        kernel_hp[i] *= exp (-0.5 * POW2 (3.0 / len * (2 * i - (len - 1))));
+        break;
+      case WINDOW_COSINE:
+        kernel_hp[i] *= cos (G_PI * i / (len - 1) - G_PI / 2);
+        break;
+      case WINDOW_HANN:
+        kernel_hp[i] *= 0.5 * (1 - cos (2 * G_PI * i / (len - 1)));
+        break;
+    }
   }
 
   /* normalize for unity gain at DC */