From 6b97253764969146b7b88df4d635777a36abd369 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 10 Aug 2007 04:44:43 +0000 Subject: [PATCH] gst/filter/gstlpwsinc.*: Specify the actual filter length instead of a weird 2N+1. Setting the property will round to... Original commit message from CVS: * gst/filter/gstlpwsinc.c: (gst_lpwsinc_class_init), (gst_lpwsinc_init), (process_32), (process_64), (lpwsinc_build_kernel), (lpwsinc_set_property), (lpwsinc_get_property): * gst/filter/gstlpwsinc.h: Specify the actual filter length instead of a weird 2N+1. Setting the property will round to the next odd number. Also remove now obsolete FIXMEs. --- gst/audiofx/audiowsinclimit.c | 50 ++++++++++++++++++++++++------------------- gst/audiofx/audiowsinclimit.h | 7 +----- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/gst/audiofx/audiowsinclimit.c b/gst/audiofx/audiowsinclimit.c index fce2b00..24906d1 100644 --- a/gst/audiofx/audiowsinclimit.c +++ b/gst/audiofx/audiowsinclimit.c @@ -204,8 +204,8 @@ gst_lpwsinc_class_init (GstLPWSincClass * klass) g_object_class_install_property (gobject_class, PROP_LENGTH, g_param_spec_int ("length", "Length", - "N such that the filter length = 2N + 1", - 1, G_MAXINT, 1, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); + "Filter kernel length, will be rounded to the next odd number", + 3, G_MAXINT, 101, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); g_object_class_install_property (gobject_class, PROP_MODE, g_param_spec_enum ("mode", "Mode", @@ -227,7 +227,7 @@ gst_lpwsinc_init (GstLPWSinc * self, GstLPWSincClass * g_class) { self->mode = MODE_LOW_PASS; self->window = WINDOW_HAMMING; - self->wing_size = 50; + self->kernel_length = 101; self->frequency = 0.0; self->kernel = NULL; self->residue = NULL; @@ -238,7 +238,7 @@ gst_lpwsinc_init (GstLPWSinc * self, GstLPWSincClass * g_class) static void process_32 (GstLPWSinc * self, gfloat * src, gfloat * dst, guint input_samples) { - gint kernel_length = self->wing_size * 2 + 1; + gint kernel_length = self->kernel_length; gint i, j, k, l; gint channels = GST_AUDIO_FILTER (self)->format.channels; @@ -265,7 +265,7 @@ static void process_64 (GstLPWSinc * self, gdouble * src, gdouble * dst, guint input_samples) { - gint kernel_length = self->wing_size * 2 + 1; + gint kernel_length = self->kernel_length; gint i, j, k, l; gint channels = GST_AUDIO_FILTER (self)->format.channels; @@ -297,8 +297,8 @@ lpwsinc_build_kernel (GstLPWSinc * self) gdouble w; /* fill the kernel */ - len = self->wing_size; - GST_DEBUG ("lpwsinc: initializing filter kernel of length %d", len * 2 + 1); + len = self->kernel_length; + GST_DEBUG ("lpwsinc: initializing filter kernel of length %d", len); if (GST_AUDIO_FILTER (self)->format.rate == 0) { GST_DEBUG ("rate not set yet"); @@ -318,40 +318,40 @@ lpwsinc_build_kernel (GstLPWSinc * self) if (self->kernel) g_free (self->kernel); - self->kernel = g_new (gdouble, 2 * len + 1); + self->kernel = g_new (gdouble, len); - for (i = 0; i <= len * 2; ++i) { - if (i == len) + for (i = 0; i < len; ++i) { + if (i == len / 2) self->kernel[i] = w; else - self->kernel[i] = sin (w * (i - len)) / (i - len); + self->kernel[i] = sin (w * (i - len / 2)) / (i - len / 2); /* windowing */ if (self->window == WINDOW_HAMMING) - self->kernel[i] *= (0.54 - 0.46 * cos (M_PI * i / len)); + self->kernel[i] *= (0.54 - 0.46 * cos (2 * 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)); + (0.42 - 0.5 * cos (2 * M_PI * i / len) + + 0.08 * cos (4 * M_PI * i / len)); } /* normalize for unity gain at DC */ - for (i = 0; i <= len * 2; ++i) + for (i = 0; i < len; ++i) sum += self->kernel[i]; - for (i = 0; i <= len * 2; ++i) + for (i = 0; i < len; ++i) self->kernel[i] /= sum; /* convert to highpass if specified */ if (self->mode == MODE_HIGH_PASS) { - for (i = 0; i <= len * 2; ++i) + for (i = 0; i < len; ++i) self->kernel[i] = -self->kernel[i]; - self->kernel[len] += 1.0; + self->kernel[len / 2] += 1.0; } /* set up the residue memory space */ if (self->residue) g_free (self->residue); self->residue = - g_new0 (gdouble, - (len * 2 + 1) * GST_AUDIO_FILTER (self)->format.channels); + g_new0 (gdouble, len * GST_AUDIO_FILTER (self)->format.channels); self->have_kernel = TRUE; } @@ -434,12 +434,18 @@ lpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, g_return_if_fail (GST_IS_LPWSINC (self)); switch (prop_id) { - case PROP_LENGTH: + case PROP_LENGTH:{ + gint val; + GST_BASE_TRANSFORM_LOCK (self); - self->wing_size = g_value_get_int (value); + val = g_value_get_int (value); + if (val % 2 == 0) + val++; + self->kernel_length = val; lpwsinc_build_kernel (self); GST_BASE_TRANSFORM_UNLOCK (self); break; + } case PROP_FREQUENCY: GST_BASE_TRANSFORM_LOCK (self); self->frequency = g_value_get_double (value); @@ -472,7 +478,7 @@ lpwsinc_get_property (GObject * object, guint prop_id, GValue * value, switch (prop_id) { case PROP_LENGTH: - g_value_set_int (value, self->wing_size); + g_value_set_int (value, self->kernel_length); break; case PROP_FREQUENCY: g_value_set_double (value, self->frequency); diff --git a/gst/audiofx/audiowsinclimit.h b/gst/audiofx/audiowsinclimit.h index d9838bd..599bef8 100644 --- a/gst/audiofx/audiowsinclimit.h +++ b/gst/audiofx/audiowsinclimit.h @@ -25,10 +25,6 @@ * chapter 16 * available at http://www.dspguide.com/ * - * FIXME: - * - this filter is totally unoptimized ! - * - we do not destroy the allocated memory for filters and residue - * - this might be improved upon with bytestream */ #ifndef __GST_LPWSINC_H__ @@ -69,8 +65,7 @@ struct _GstLPWSinc { gint mode; gint window; gdouble frequency; - gint wing_size; /* length of a "wing" of the filter; - actual length is 2 * wing_size + 1 */ + gint kernel_length; /* length of the filter kernel */ gdouble *residue; /* buffer for left-over samples from previous buffer */ gdouble *kernel; /* filter kernel */ -- 2.7.4