From 982bf23b353cd825e249d8fc13420f88e9cf4cd4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 10 Aug 2007 04:32:47 +0000 Subject: [PATCH] gst/filter/gstlpwsinc.*: Allow choosing between hamming and blackman window. The blackman window provides a better st... Original commit message from CVS: * gst/filter/gstlpwsinc.c: (gst_lpwsinc_window_get_type), (gst_lpwsinc_class_init), (gst_lpwsinc_init), (lpwsinc_build_kernel), (lpwsinc_set_property), (lpwsinc_get_property): * gst/filter/gstlpwsinc.h: Allow choosing between hamming and blackman window. The blackman window provides a better stopband attenuation but a bit slower rolloff. --- ChangeLog | 11 +++++++++ gst/filter/gstlpwsinc.c | 53 ++++++++++++++++++++++++++++++++++++++--- gst/filter/gstlpwsinc.h | 1 + 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 60a1436cb5..3707cf27bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-08-10 Sebastian Dröge + + * gst/filter/gstlpwsinc.c: (gst_lpwsinc_window_get_type), + (gst_lpwsinc_class_init), (gst_lpwsinc_init), + (lpwsinc_build_kernel), (lpwsinc_set_property), + (lpwsinc_get_property): + * gst/filter/gstlpwsinc.h: + Allow choosing between hamming and blackman window. The blackman + window provides a better stopband attenuation but a bit slower + rolloff. + 2007-08-10 Sebastian Dröge * gst/filter/gstlpwsinc.c: (gst_lpwsinc_mode_get_type), diff --git a/gst/filter/gstlpwsinc.c b/gst/filter/gstlpwsinc.c index 8f4ec530a8..fce2b00dcd 100644 --- a/gst/filter/gstlpwsinc.c +++ b/gst/filter/gstlpwsinc.c @@ -29,7 +29,6 @@ * TODO: - Implement the convolution in place, probably only makes sense * when using FFT convolution as currently the convolution itself * is probably the bottleneck. - * - Allow choosing between different windows (blackman, hanning, ...) * - Maybe allow cascading the filter to get a better stopband attenuation. * Can be done by convolving a filter kernel with itself. */ @@ -69,7 +68,8 @@ enum PROP_0, PROP_LENGTH, PROP_FREQUENCY, - PROP_MODE + PROP_MODE, + PROP_WINDOW }; enum @@ -98,6 +98,33 @@ gst_lpwsinc_mode_get_type (void) return gtype; } +enum +{ + WINDOW_HAMMING = 0, + WINDOW_BLACKMAN +}; + +#define GST_TYPE_LPWSINC_WINDOW (gst_lpwsinc_window_get_type ()) +static GType +gst_lpwsinc_window_get_type (void) +{ + static GType gtype = 0; + + if (gtype == 0) { + static const GEnumValue values[] = { + {WINDOW_HAMMING, "Hamming window (default)", + "hamming"}, + {WINDOW_BLACKMAN, "Blackman window", + "blackman"}, + {0, NULL, NULL} + }; + + gtype = g_enum_register_static ("GstLPWSincWindow", values); + } + return gtype; +} + + #define ALLOWED_CAPS \ "audio/x-raw-float," \ " width = (int) { 32, 64 }, " \ @@ -185,6 +212,11 @@ gst_lpwsinc_class_init (GstLPWSincClass * klass) "Low pass or high pass mode", GST_TYPE_LPWSINC_MODE, MODE_LOW_PASS, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + g_object_class_install_property (gobject_class, PROP_WINDOW, + g_param_spec_enum ("window", "Window", + "Window function to use", GST_TYPE_LPWSINC_WINDOW, + WINDOW_HAMMING, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + trans_class->transform = GST_DEBUG_FUNCPTR (lpwsinc_transform); trans_class->get_unit_size = GST_DEBUG_FUNCPTR (lpwsinc_get_unit_size); GST_AUDIO_FILTER_CLASS (klass)->setup = GST_DEBUG_FUNCPTR (lpwsinc_setup); @@ -193,6 +225,8 @@ gst_lpwsinc_class_init (GstLPWSincClass * klass) static void gst_lpwsinc_init (GstLPWSinc * self, GstLPWSincClass * g_class) { + self->mode = MODE_LOW_PASS; + self->window = WINDOW_HAMMING; self->wing_size = 50; self->frequency = 0.0; self->kernel = NULL; @@ -292,7 +326,11 @@ lpwsinc_build_kernel (GstLPWSinc * self) else self->kernel[i] = sin (w * (i - len)) / (i - len); /* windowing */ - self->kernel[i] *= (0.54 - 0.46 * cos (M_PI * i / len)); + if (self->window == WINDOW_HAMMING) + self->kernel[i] *= (0.54 - 0.46 * cos (M_PI * i / len)); + else + self->kernel[i] *= + (0.42 - 0.5 * cos (M_PI * i / len) + 0.08 * cos (2 * M_PI * i / len)); } /* normalize for unity gain at DC */ @@ -414,6 +452,12 @@ lpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, lpwsinc_build_kernel (self); GST_BASE_TRANSFORM_UNLOCK (self); break; + case PROP_WINDOW: + GST_BASE_TRANSFORM_LOCK (self); + self->window = g_value_get_enum (value); + lpwsinc_build_kernel (self); + GST_BASE_TRANSFORM_UNLOCK (self); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -436,6 +480,9 @@ lpwsinc_get_property (GObject * object, guint prop_id, GValue * value, case PROP_MODE: g_value_set_enum (value, self->mode); break; + case PROP_WINDOW: + g_value_set_enum (value, self->window); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/filter/gstlpwsinc.h b/gst/filter/gstlpwsinc.h index bc9377f60f..d9838bd255 100644 --- a/gst/filter/gstlpwsinc.h +++ b/gst/filter/gstlpwsinc.h @@ -67,6 +67,7 @@ struct _GstLPWSinc { GstLPWSincProcessFunc process; gint mode; + gint window; gdouble frequency; gint wing_size; /* length of a "wing" of the filter; actual length is 2 * wing_size + 1 */ -- 2.34.1