diff options
Diffstat (limited to 'gst/filter')
-rw-r--r-- | gst/filter/gstbpwsinc.c | 185 | ||||
-rw-r--r-- | gst/filter/gstfilter.c | 48 | ||||
-rw-r--r-- | gst/filter/gstiir.c | 125 | ||||
-rw-r--r-- | gst/filter/gstlpwsinc.c | 138 | ||||
-rw-r--r-- | gst/filter/iir.c | 228 | ||||
-rw-r--r-- | gst/filter/iir.h | 11 |
6 files changed, 385 insertions, 350 deletions
diff --git a/gst/filter/gstbpwsinc.c b/gst/filter/gstbpwsinc.c index 77529053..a848cc26 100644 --- a/gst/filter/gstbpwsinc.c +++ b/gst/filter/gstbpwsinc.c @@ -39,20 +39,19 @@ #include <string.h> /* memmove */ /* elementfactory information */ -static GstElementDetails gst_bpwsinc_details = GST_ELEMENT_DETAILS ( - "BPWSinc", - "Filter/Effect/Audio", - "Band-Pass Windowed sinc filter", - "Thomas <thomas@apestaart.org>, " - "Steven W. Smith" -); - -enum { +static GstElementDetails gst_bpwsinc_details = GST_ELEMENT_DETAILS ("BPWSinc", + "Filter/Effect/Audio", + "Band-Pass Windowed sinc filter", + "Thomas <thomas@apestaart.org>, " "Steven W. Smith"); + +enum +{ /* FILL ME */ LAST_SIGNAL }; -enum { +enum +{ ARG_0, ARG_LENGTH, ARG_LOWER_FREQUENCY, @@ -81,51 +80,52 @@ struct _GstBPWSinc double frequency; double lower_frequency, upper_frequency; - int wing_size; /* length of a "wing" of the filter; - actual length is 2 * wing_size + 1 */ + int wing_size; /* length of a "wing" of the filter; + actual length is 2 * wing_size + 1 */ - gfloat *residue; /* buffer for left-over samples from previous buffer */ + gfloat *residue; /* buffer for left-over samples from previous buffer */ double *kernel; }; struct _GstBPWSincClass { - GstElementClass parent_class; + GstElementClass parent_class; }; -static void gst_bpwsinc_base_init (gpointer g_class); -static void gst_bpwsinc_class_init (GstBPWSincClass * klass); -static void gst_bpwsinc_init (GstBPWSinc * filter); +static void gst_bpwsinc_base_init (gpointer g_class); +static void gst_bpwsinc_class_init (GstBPWSincClass * klass); +static void gst_bpwsinc_init (GstBPWSinc * filter); -static void gst_bpwsinc_set_property (GObject * object, guint prop_id, - const GValue * value, - GParamSpec * pspec); -static void gst_bpwsinc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); +static void gst_bpwsinc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_bpwsinc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); -static void gst_bpwsinc_chain (GstPad * pad, GstData *_data); +static void gst_bpwsinc_chain (GstPad * pad, GstData * _data); static GstPadLinkReturn - gst_bpwsinc_sink_connect (GstPad * pad, const GstCaps * caps); +gst_bpwsinc_sink_connect (GstPad * pad, const GstCaps * caps); static GstElementClass *parent_class = NULL; + /*static guint gst_bpwsinc_signals[LAST_SIGNAL] = { 0 }; */ -GType gst_bpwsinc_get_type (void) +GType +gst_bpwsinc_get_type (void) { static GType bpwsinc_type = 0; if (!bpwsinc_type) { static const GTypeInfo bpwsinc_info = { - sizeof (GstBPWSincClass), - gst_bpwsinc_base_init, + sizeof (GstBPWSincClass), + gst_bpwsinc_base_init, NULL, (GClassInitFunc) gst_bpwsinc_class_init, NULL, NULL, sizeof (GstBPWSinc), 0, (GInstanceInitFunc) gst_bpwsinc_init, }; - bpwsinc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBPWSinc", - &bpwsinc_info, 0); + bpwsinc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBPWSinc", + &bpwsinc_info, 0); } return bpwsinc_type; } @@ -139,9 +139,9 @@ gst_bpwsinc_base_init (gpointer g_class) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_filter_src_template)); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_filter_sink_template)); + gst_static_pad_template_get (&gst_filter_sink_template)); - gst_element_class_set_details (element_class, &gst_bpwsinc_details); + gst_element_class_set_details (element_class, &gst_bpwsinc_details); } static void @@ -156,20 +156,17 @@ gst_bpwsinc_class_init (GstBPWSincClass * klass) parent_class = g_type_class_ref (GST_TYPE_ELEMENT); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOWER_FREQUENCY, - g_param_spec_double ("lower-frequency", "Lower Frequency", - "Cut-off lower frequency (relative to sample rate)", - 0.0, 0.5, - 0, G_PARAM_READWRITE)); + g_param_spec_double ("lower-frequency", "Lower Frequency", + "Cut-off lower frequency (relative to sample rate)", + 0.0, 0.5, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_UPPER_FREQUENCY, - g_param_spec_double ("upper-frequency", "Upper Frequency", - "Cut-off upper frequency (relative to sample rate)", - 0.0, 0.5, - 0, G_PARAM_READWRITE)); + g_param_spec_double ("upper-frequency", "Upper Frequency", + "Cut-off upper frequency (relative to sample rate)", + 0.0, 0.5, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LENGTH, - g_param_spec_int ("length", "Length", - "N such that the filter length = 2N + 1", - 1, G_MAXINT, - 1, G_PARAM_READWRITE)); + g_param_spec_int ("length", "Length", + "N such that the filter length = 2N + 1", + 1, G_MAXINT, 1, G_PARAM_READWRITE)); gobject_class->set_property = gst_bpwsinc_set_property; gobject_class->get_property = gst_bpwsinc_get_property; @@ -178,14 +175,16 @@ gst_bpwsinc_class_init (GstBPWSincClass * klass) static void gst_bpwsinc_init (GstBPWSinc * filter) { - filter->sinkpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&gst_filter_sink_template), "sink"); + filter->sinkpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&gst_filter_sink_template), "sink"); gst_pad_set_chain_function (filter->sinkpad, gst_bpwsinc_chain); gst_pad_set_link_function (filter->sinkpad, gst_bpwsinc_sink_connect); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); - filter->srcpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&gst_filter_src_template), "src"); + filter->srcpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&gst_filter_src_template), "src"); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); filter->wing_size = 50; @@ -202,65 +201,65 @@ gst_bpwsinc_sink_connect (GstPad * pad, const GstCaps * caps) int len = 0; double *kernel_lp, *kernel_hp; GstPadLinkReturn set_retval; - + GstBPWSinc *filter = GST_BPWSINC (gst_pad_get_parent (pad)); g_assert (GST_IS_PAD (pad)); g_assert (caps != NULL); set_retval = gst_pad_try_set_caps (filter->srcpad, caps); - - if (set_retval > 0) - { + + if (set_retval > 0) { len = filter->wing_size; /* fill the lp kernel */ - GST_DEBUG ( - "bpwsinc: initializing LP kernel of length %d with cut-off %f", - len * 2 + 1, filter->lower_frequency); + GST_DEBUG ("bpwsinc: initializing LP kernel of length %d with cut-off %f", + len * 2 + 1, filter->lower_frequency); kernel_lp = (double *) g_malloc (sizeof (double) * (2 * len + 1)); - for (i = 0; i <= len * 2; ++i) - { + for (i = 0; i <= len * 2; ++i) { if (i == len) kernel_lp[i] = 2 * M_PI * filter->lower_frequency; else - kernel_lp[i] = sin (2 * M_PI * filter->lower_frequency * (i - len)) - / (i - len); + kernel_lp[i] = sin (2 * M_PI * filter->lower_frequency * (i - len)) + / (i - len); /* Blackman windowing */ - kernel_lp[i] *= (0.42 - 0.5 * cos (M_PI * i / len) - + 0.08 * cos (2 * M_PI * i / len)); + kernel_lp[i] *= (0.42 - 0.5 * cos (M_PI * i / len) + + 0.08 * cos (2 * M_PI * i / len)); } /* normalize for unity gain at DC * FIXME: sure this is not supposed to be quadratic ? */ sum = 0.0; - for (i = 0; i <= len * 2; ++i) sum += kernel_lp[i]; - for (i = 0; i <= len * 2; ++i) kernel_lp[i] /= sum; + for (i = 0; i <= len * 2; ++i) + sum += kernel_lp[i]; + for (i = 0; i <= len * 2; ++i) + kernel_lp[i] /= sum; /* fill the hp kernel */ - GST_DEBUG ( - "bpwsinc: initializing HP kernel of length %d with cut-off %f", - len * 2 + 1, filter->upper_frequency); + GST_DEBUG ("bpwsinc: initializing HP kernel of length %d with cut-off %f", + len * 2 + 1, filter->upper_frequency); kernel_hp = (double *) g_malloc (sizeof (double) * (2 * len + 1)); - for (i = 0; i <= len * 2; ++i) - { + for (i = 0; i <= len * 2; ++i) { if (i == len) kernel_hp[i] = 2 * M_PI * filter->upper_frequency; else - kernel_hp[i] = sin (2 * M_PI * filter->upper_frequency * (i - len)) - / (i - len); + kernel_hp[i] = sin (2 * M_PI * filter->upper_frequency * (i - len)) + / (i - len); /* Blackman windowing */ - kernel_hp[i] *= (0.42 - 0.5 * cos (M_PI * i / len) - + 0.08 * cos (2 * M_PI * i / len)); + kernel_hp[i] *= (0.42 - 0.5 * cos (M_PI * i / len) + + 0.08 * cos (2 * M_PI * i / len)); } /* normalize for unity gain at DC * FIXME: sure this is not supposed to be quadratic ? */ sum = 0.0; - for (i = 0; i <= len * 2; ++i) sum += kernel_hp[i]; - for (i = 0; i <= len * 2; ++i) kernel_hp[i] /= sum; + for (i = 0; i <= len * 2; ++i) + sum += kernel_hp[i]; + for (i = 0; i <= len * 2; ++i) + kernel_hp[i] /= sum; /* do spectral inversion to get a HP filter */ - for (i = 0; i <= len * 2; ++i) kernel_hp[i] = -kernel_hp[i]; + for (i = 0; i <= len * 2; ++i) + kernel_hp[i] = -kernel_hp[i]; kernel_hp[len] += 1; /* combine the two filters */ @@ -271,7 +270,8 @@ gst_bpwsinc_sink_connect (GstPad * pad, const GstCaps * caps) filter->kernel[i] = kernel_lp[i] + kernel_hp[i]; /* do spectral inversion to go from band reject to bandpass */ - for (i = 0; i <= len * 2; ++i) filter->kernel[i] = -filter->kernel[i]; + for (i = 0; i <= len * 2; ++i) + filter->kernel[i] = -filter->kernel[i]; filter->kernel[len] += 1; /* free the helper kernels */ @@ -280,14 +280,15 @@ gst_bpwsinc_sink_connect (GstPad * pad, const GstCaps * caps) /* set up the residue memory space */ filter->residue = (gfloat *) g_malloc (sizeof (gfloat) * (len * 2 + 1)); - for (i = 0; i <= len * 2; ++i) filter->residue[i] = 0.0; + for (i = 0; i <= len * 2; ++i) + filter->residue[i] = 0.0; } return set_retval; } static void -gst_bpwsinc_chain (GstPad *pad, GstData *_data) +gst_bpwsinc_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstBPWSinc *filter; @@ -323,24 +324,24 @@ gst_bpwsinc_chain (GstPad *pad, GstData *_data) memcpy (&input[residue_samples], src, sizeof (gfloat) * input_samples); /* copy the tail of the current input buffer to the residue */ memcpy (filter->residue, &src[input_samples - residue_samples], - sizeof (gfloat) * residue_samples); + sizeof (gfloat) * residue_samples); /* convolution */ /* since we copied the previous set of samples we needed before the actual * input data, we need to add the filter length to our indices for input */ - for (i = 0; i < input_samples; ++i) - { + for (i = 0; i < input_samples; ++i) { src[i] = 0.0; for (j = 0; j < residue_samples; ++j) src[i] += input[i - j + residue_samples] * filter->kernel[j]; } - + g_free (input); gst_pad_push (filter->srcpad, GST_DATA (buf)); } static void -gst_bpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +gst_bpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, + GParamSpec * pspec) { GstBPWSinc *filter; @@ -351,27 +352,28 @@ gst_bpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, switch (prop_id) { case ARG_LENGTH: - filter->wing_size = g_value_get_int (value); - break; + filter->wing_size = g_value_get_int (value); + break; case ARG_LOWER_FREQUENCY: - filter->lower_frequency = g_value_get_double (value); - break; + filter->lower_frequency = g_value_get_double (value); + break; case ARG_UPPER_FREQUENCY: - filter->upper_frequency = g_value_get_double (value); - break; + filter->upper_frequency = g_value_get_double (value); + break; default: break; } } static void -gst_bpwsinc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) +gst_bpwsinc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) { GstBPWSinc *filter; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_BPWSINC (object)); - + filter = GST_BPWSINC (object); switch (prop_id) { @@ -388,5 +390,4 @@ gst_bpwsinc_get_property (GObject * object, guint prop_id, GValue * value, GPara G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } -} - +} diff --git a/gst/filter/gstfilter.c b/gst/filter/gstfilter.c index 7a5d4248..f723ae63 100644 --- a/gst/filter/gstfilter.c +++ b/gst/filter/gstfilter.c @@ -27,33 +27,30 @@ #include <gst/audio/audio.h> -struct _elements_entry { +struct _elements_entry +{ gchar *name; - GType (*type) (void); + GType (*type) (void); }; static struct _elements_entry _elements[] = { - { "iir", gst_iir_get_type }, - { "lpwsinc", gst_lpwsinc_get_type }, - { "bpwsinc", gst_bpwsinc_get_type }, - { NULL, 0 }, + {"iir", gst_iir_get_type}, + {"lpwsinc", gst_lpwsinc_get_type}, + {"bpwsinc", gst_bpwsinc_get_type}, + {NULL, 0}, }; -GstStaticPadTemplate gst_filter_src_template = -GST_STATIC_PAD_TEMPLATE ( - "src", +GstStaticPadTemplate gst_filter_src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ( GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS ) -); + GST_STATIC_CAPS (GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS) + ); -GstStaticPadTemplate gst_filter_sink_template = -GST_STATIC_PAD_TEMPLATE ( - "sink", +GstStaticPadTemplate gst_filter_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ( GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS ) -); + GST_STATIC_CAPS (GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS) + ); static gboolean plugin_init (GstPlugin * plugin) @@ -61,7 +58,8 @@ plugin_init (GstPlugin * plugin) gint i = 0; while (_elements[i].name) { - if (!gst_element_register (plugin, _elements[i].name, GST_RANK_NONE, _elements[i].type())) + if (!gst_element_register (plugin, _elements[i].name, GST_RANK_NONE, + _elements[i].type ())) return FALSE; i++; @@ -70,14 +68,8 @@ plugin_init (GstPlugin * plugin) return TRUE; } -GST_PLUGIN_DEFINE ( - GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "filter", - "IIR, lpwsinc and bpwsinc audio filter elements", - plugin_init, - VERSION, - "LGPL", - GST_PACKAGE, - GST_ORIGIN -); +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "filter", + "IIR, lpwsinc and bpwsinc audio filter elements", + plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN); diff --git a/gst/filter/gstiir.c b/gst/filter/gstiir.c index 4ccf9f09..5e44f3d0 100644 --- a/gst/filter/gstiir.c +++ b/gst/filter/gstiir.c @@ -25,20 +25,19 @@ #include "gstfilter.h" #include "iir.h" -static GstElementDetails gst_iir_details = GST_ELEMENT_DETAILS ( - "IIR", - "Filter/Effect/Audio", - "IIR filter based on vorbis code", - "Monty <monty@xiph.org>, " - "Thomas <thomas@apestaart.org>" -); - -enum { +static GstElementDetails gst_iir_details = GST_ELEMENT_DETAILS ("IIR", + "Filter/Effect/Audio", + "IIR filter based on vorbis code", + "Monty <monty@xiph.org>, " "Thomas <thomas@apestaart.org>"); + +enum +{ /* FILL ME */ LAST_SIGNAL }; -enum { +enum +{ ARG_0, ARG_A, ARG_B, @@ -74,33 +73,34 @@ struct _GstIIR struct _GstIIRClass { - GstElementClass parent_class; + GstElementClass parent_class; }; -static void gst_iir_base_init (gpointer g_class); -static void gst_iir_class_init (GstIIRClass * klass); -static void gst_iir_init (GstIIR * filter); +static void gst_iir_base_init (gpointer g_class); +static void gst_iir_class_init (GstIIRClass * klass); +static void gst_iir_init (GstIIR * filter); -static void gst_iir_set_property (GObject * object, guint prop_id, - const GValue * value, - GParamSpec * pspec); -static void gst_iir_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); +static void gst_iir_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_iir_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); -static void gst_iir_chain (GstPad * pad, GstData *_data); +static void gst_iir_chain (GstPad * pad, GstData * _data); static GstPadLinkReturn - gst_iir_sink_connect (GstPad * pad, const GstCaps * caps); +gst_iir_sink_connect (GstPad * pad, const GstCaps * caps); static GstElementClass *parent_class = NULL; + /*static guint gst_iir_signals[LAST_SIGNAL] = { 0 }; */ -GType gst_iir_get_type (void) +GType +gst_iir_get_type (void) { static GType iir_type = 0; if (!iir_type) { static const GTypeInfo iir_info = { - sizeof (GstIIRClass), + sizeof (GstIIRClass), gst_iir_base_init, NULL, (GClassInitFunc) gst_iir_class_init, NULL, NULL, @@ -108,8 +108,8 @@ GType gst_iir_get_type (void) (GInstanceInitFunc) gst_iir_init, }; - iir_type = g_type_register_static (GST_TYPE_ELEMENT, "GstIIR", - &iir_info, 0); + iir_type = g_type_register_static (GST_TYPE_ELEMENT, "GstIIR", + &iir_info, 0); } return iir_type; } @@ -123,9 +123,9 @@ gst_iir_base_init (gpointer g_class) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_filter_src_template)); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_filter_sink_template)); + gst_static_pad_template_get (&gst_filter_sink_template)); - gst_element_class_set_details (element_class, &gst_iir_details); + gst_element_class_set_details (element_class, &gst_iir_details); } static void @@ -140,21 +140,17 @@ gst_iir_class_init (GstIIRClass * klass) parent_class = g_type_class_ref (GST_TYPE_ELEMENT); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_A, - g_param_spec_double ("A", "A", "A filter coefficient", - -G_MAXDOUBLE, G_MAXDOUBLE, - 0, G_PARAM_READWRITE)); + g_param_spec_double ("A", "A", "A filter coefficient", + -G_MAXDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_B, - g_param_spec_double ("B", "B", "B filter coefficient", - -G_MAXDOUBLE, G_MAXDOUBLE, - 0, G_PARAM_READWRITE)); + g_param_spec_double ("B", "B", "B filter coefficient", + -G_MAXDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GAIN, - g_param_spec_double ("gain", "Gain", "Filter gain", - -G_MAXDOUBLE, G_MAXDOUBLE, - 0, G_PARAM_READWRITE)); + g_param_spec_double ("gain", "Gain", "Filter gain", + -G_MAXDOUBLE, G_MAXDOUBLE, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_STAGES, - g_param_spec_int ("stages", "Stages", "Number of filter stages", - 1, G_MAXINT, - 1, G_PARAM_READWRITE)); + g_param_spec_int ("stages", "Stages", "Number of filter stages", + 1, G_MAXINT, 1, G_PARAM_READWRITE)); gobject_class->set_property = gst_iir_set_property; gobject_class->get_property = gst_iir_get_property; @@ -163,19 +159,21 @@ gst_iir_class_init (GstIIRClass * klass) static void gst_iir_init (GstIIR * filter) { - filter->sinkpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&gst_filter_sink_template), "sink"); + filter->sinkpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&gst_filter_sink_template), "sink"); gst_pad_set_chain_function (filter->sinkpad, gst_iir_chain); gst_pad_set_link_function (filter->sinkpad, gst_iir_sink_connect); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); - filter->srcpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&gst_filter_src_template), "src"); + filter->srcpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&gst_filter_src_template), "src"); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); filter->A = 0.0; filter->B = 0.0; - filter->gain = 1.0; /* unity gain as default */ + filter->gain = 1.0; /* unity gain as default */ filter->stages = 1; filter->state = NULL; } @@ -185,23 +183,23 @@ gst_iir_sink_connect (GstPad * pad, const GstCaps * caps) { GstIIR *filter; GstPadLinkReturn set_retval; - + filter = GST_IIR (gst_pad_get_parent (pad)); - - set_retval = gst_pad_try_set_caps(filter->srcpad, caps); + + set_retval = gst_pad_try_set_caps (filter->srcpad, caps); if (set_retval > 0) { /* connection works, so init the filter */ /* FIXME: remember to free it */ filter->state = (IIR_state *) g_malloc (sizeof (IIR_state)); - IIR_init (filter->state, filter->stages, - filter->gain, &(filter->A), &(filter->B)); + IIR_init (filter->state, filter->stages, + filter->gain, &(filter->A), &(filter->B)); } return set_retval; } static void -gst_iir_chain (GstPad * pad, GstData *_data) +gst_iir_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstIIR *filter; @@ -223,7 +221,8 @@ gst_iir_chain (GstPad * pad, GstData *_data) } static void -gst_iir_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +gst_iir_set_property (GObject * object, guint prop_id, const GValue * value, + GParamSpec * pspec) { GstIIR *filter; @@ -234,30 +233,31 @@ gst_iir_set_property (GObject * object, guint prop_id, const GValue * value, GPa switch (prop_id) { case ARG_A: - filter->A = g_value_get_double (value); - break; + filter->A = g_value_get_double (value); + break; case ARG_B: - filter->B = g_value_get_double (value); - break; + filter->B = g_value_get_double (value); + break; case ARG_GAIN: - filter->gain = g_value_get_double (value); - break; + filter->gain = g_value_get_double (value); + break; case ARG_STAGES: - filter->stages = g_value_get_int (value); - break; + filter->stages = g_value_get_int (value); + break; default: break; } } static void -gst_iir_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) +gst_iir_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) { GstIIR *filter; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_IIR (object)); - + filter = GST_IIR (object); switch (prop_id) { @@ -277,5 +277,4 @@ gst_iir_get_property (GObject * object, guint prop_id, GValue * value, GParamSpe G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } -} - +} diff --git a/gst/filter/gstlpwsinc.c b/gst/filter/gstlpwsinc.c index 603d8775..0ce33b32 100644 --- a/gst/filter/gstlpwsinc.c +++ b/gst/filter/gstlpwsinc.c @@ -38,20 +38,19 @@ #include <math.h> /* M_PI */ #include <string.h> /* memmove */ -static GstElementDetails gst_lpwsinc_details = GST_ELEMENT_DETAILS ( - "LPWSinc", - "Filter/Effect/Audio", - "Low-pass Windowed sinc filter", - "Thomas <thomas@apestaart.org>, " - "Steven W. Smith" -); - -enum { +static GstElementDetails gst_lpwsinc_details = GST_ELEMENT_DETAILS ("LPWSinc", + "Filter/Effect/Audio", + "Low-pass Windowed sinc filter", + "Thomas <thomas@apestaart.org>, " "Steven W. Smith"); + +enum +{ /* FILL ME */ LAST_SIGNAL }; -enum { +enum +{ ARG_0, ARG_LENGTH, ARG_FREQUENCY, @@ -78,42 +77,43 @@ struct _GstLPWSinc GstPad *sinkpad, *srcpad; double frequency; - int wing_size; /* length of a "wing" of the filter; - actual length is 2 * wing_size + 1 */ + int wing_size; /* length of a "wing" of the filter; + actual length is 2 * wing_size + 1 */ - gfloat *residue; /* buffer for left-over samples from previous buffer */ + gfloat *residue; /* buffer for left-over samples from previous buffer */ double *kernel; }; struct _GstLPWSincClass { - GstElementClass parent_class; + GstElementClass parent_class; }; -static void gst_lpwsinc_base_init (gpointer g_class); -static void gst_lpwsinc_class_init (GstLPWSincClass * klass); -static void gst_lpwsinc_init (GstLPWSinc * filter); +static void gst_lpwsinc_base_init (gpointer g_class); +static void gst_lpwsinc_class_init (GstLPWSincClass * klass); +static void gst_lpwsinc_init (GstLPWSinc * filter); -static void gst_lpwsinc_set_property (GObject * object, guint prop_id, - const GValue * value, - GParamSpec * pspec); -static void gst_lpwsinc_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); +static void gst_lpwsinc_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_lpwsinc_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); -static void gst_lpwsinc_chain (GstPad * pad, GstData *_data); +static void gst_lpwsinc_chain (GstPad * pad, GstData * _data); static GstPadLinkReturn - gst_lpwsinc_sink_connect (GstPad * pad, const GstCaps * caps); +gst_lpwsinc_sink_connect (GstPad * pad, const GstCaps * caps); static GstElementClass *parent_class = NULL; + /*static guint gst_lpwsinc_signals[LAST_SIGNAL] = { 0 }; */ -GType gst_lpwsinc_get_type (void) +GType +gst_lpwsinc_get_type (void) { static GType lpwsinc_type = 0; if (!lpwsinc_type) { static const GTypeInfo lpwsinc_info = { - sizeof (GstLPWSincClass), + sizeof (GstLPWSincClass), gst_lpwsinc_base_init, NULL, (GClassInitFunc) gst_lpwsinc_class_init, NULL, NULL, @@ -121,8 +121,8 @@ GType gst_lpwsinc_get_type (void) (GInstanceInitFunc) gst_lpwsinc_init, }; - lpwsinc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstLPWSinc", - &lpwsinc_info, 0); + lpwsinc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstLPWSinc", + &lpwsinc_info, 0); } return lpwsinc_type; } @@ -136,9 +136,9 @@ gst_lpwsinc_base_init (gpointer g_class) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_filter_src_template)); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_filter_sink_template)); + gst_static_pad_template_get (&gst_filter_sink_template)); - gst_element_class_set_details (element_class, &gst_lpwsinc_details); + gst_element_class_set_details (element_class, &gst_lpwsinc_details); } static void @@ -153,15 +153,13 @@ gst_lpwsinc_class_init (GstLPWSincClass * klass) parent_class = g_type_class_ref (GST_TYPE_ELEMENT); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREQUENCY, - g_param_spec_double ("frequency", "Frequency", - "Cut-off Frequency relative to sample rate)", - 0.0, 0.5, - 0, G_PARAM_READWRITE)); + g_param_spec_double ("frequency", "Frequency", + "Cut-off Frequency relative to sample rate)", + 0.0, 0.5, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LENGTH, - g_param_spec_int ("length", "Length", - "N such that the filter length = 2N + 1", - 1, G_MAXINT, - 1, G_PARAM_READWRITE)); + g_param_spec_int ("length", "Length", + "N such that the filter length = 2N + 1", + 1, G_MAXINT, 1, G_PARAM_READWRITE)); gobject_class->set_property = gst_lpwsinc_set_property; gobject_class->get_property = gst_lpwsinc_get_property; @@ -170,14 +168,16 @@ gst_lpwsinc_class_init (GstLPWSincClass * klass) static void gst_lpwsinc_init (GstLPWSinc * filter) { - filter->sinkpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&gst_filter_sink_template), "sink"); + filter->sinkpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&gst_filter_sink_template), "sink"); gst_pad_set_chain_function (filter->sinkpad, gst_lpwsinc_chain); gst_pad_set_link_function (filter->sinkpad, gst_lpwsinc_sink_connect); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); - filter->srcpad = gst_pad_new_from_template ( - gst_static_pad_template_get (&gst_filter_src_template), "src"); + filter->srcpad = + gst_pad_new_from_template (gst_static_pad_template_get + (&gst_filter_src_template), "src"); gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); filter->wing_size = 50; @@ -197,45 +197,45 @@ gst_lpwsinc_sink_connect (GstPad * pad, const GstCaps * caps) g_assert (GST_IS_PAD (pad)); g_assert (caps != NULL); - set_retval = gst_pad_try_set_caps(filter->srcpad, caps); - - if (set_retval > 0) - { + set_retval = gst_pad_try_set_caps (filter->srcpad, caps); + + if (set_retval > 0) { /* connection works, so init the filter */ /* FIXME: remember to free it */ /* fill the kernel */ g_print ("DEBUG: initing filter kernel\n"); len = filter->wing_size; - GST_DEBUG ( - "lpwsinc: initializing filter kernel of length %d", len * 2 + 1); + GST_DEBUG ("lpwsinc: initializing filter kernel of length %d", len * 2 + 1); filter->kernel = (double *) g_malloc (sizeof (double) * (2 * len + 1)); - for (i = 0; i <= len * 2; ++i) - { + for (i = 0; i <= len * 2; ++i) { if (i == len) filter->kernel[i] = 2 * M_PI * filter->frequency; else - filter->kernel[i] = sin (2 * M_PI * filter->frequency * (i - len)) - / (i - len); + filter->kernel[i] = sin (2 * M_PI * filter->frequency * (i - len)) + / (i - len); /* windowing */ filter->kernel[i] *= (0.54 - 0.46 * cos (M_PI * i / len)); } /* normalize for unity gain at DC * FIXME: sure this is not supposed to be quadratic ? */ - for (i = 0; i <= len * 2; ++i) sum += filter->kernel[i]; - for (i = 0; i <= len * 2; ++i) filter->kernel[i] /= sum; + for (i = 0; i <= len * 2; ++i) + sum += filter->kernel[i]; + for (i = 0; i <= len * 2; ++i) + filter->kernel[i] /= sum; /* set up the residue memory space */ filter->residue = (gfloat *) g_malloc (sizeof (gfloat) * (len * 2 + 1)); - for (i = 0; i <= len * 2; ++i) filter->residue[i] = 0.0; + for (i = 0; i <= len * 2; ++i) + filter->residue[i] = 0.0; } return set_retval; } static void -gst_lpwsinc_chain (GstPad * pad, GstData *_data) +gst_lpwsinc_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstLPWSinc *filter; @@ -271,24 +271,24 @@ gst_lpwsinc_chain (GstPad * pad, GstData *_data) memcpy (&input[residue_samples], src, sizeof (gfloat) * input_samples); /* copy the tail of the current input buffer to the residue */ memcpy (filter->residue, &src[input_samples - residue_samples], - sizeof (gfloat) * residue_samples); + sizeof (gfloat) * residue_samples); /* convolution */ /* since we copied the previous set of samples we needed before the actual * input data, we need to add the filter length to our indices for input */ - for (i = 0; i < input_samples; ++i) - { + for (i = 0; i < input_samples; ++i) { src[i] = 0.0; for (j = 0; j < residue_samples; ++j) src[i] += input[i - j + residue_samples] * filter->kernel[j]; } - + g_free (input); gst_pad_push (filter->srcpad, GST_DATA (buf)); } static void -gst_lpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) +gst_lpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, + GParamSpec * pspec) { GstLPWSinc *filter; @@ -299,24 +299,25 @@ gst_lpwsinc_set_property (GObject * object, guint prop_id, const GValue * value, switch (prop_id) { case ARG_LENGTH: - filter->wing_size = g_value_get_int (value); - break; + filter->wing_size = g_value_get_int (value); + break; case ARG_FREQUENCY: - filter->frequency = g_value_get_double (value); - break; + filter->frequency = g_value_get_double (value); + break; default: break; } } static void -gst_lpwsinc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) +gst_lpwsinc_get_property (GObject * object, guint prop_id, GValue * value, + GParamSpec * pspec) { GstLPWSinc *filter; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_LPWSINC (object)); - + filter = GST_LPWSINC (object); switch (prop_id) { @@ -330,5 +331,4 @@ gst_lpwsinc_get_property (GObject * object, guint prop_id, GValue * value, GPara G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } -} - +} diff --git a/gst/filter/iir.c b/gst/filter/iir.c index 13e2e937..8bf629b6 100644 --- a/gst/filter/iir.c +++ b/gst/filter/iir.c @@ -28,91 +28,103 @@ #include <math.h> #include "iir.h" -void IIR_init(IIR_state *s,int stages,double gain, double *A, double *B){ - memset(s,0,sizeof(IIR_state)); - s->stages=stages; - s->gain=gain; - s->coeff_A=malloc(stages*sizeof(double)); - s->coeff_B=malloc((stages+1)*sizeof(double)); - s->z_A=calloc(stages*2,sizeof(double)); - s->z_B=calloc(stages*2,sizeof(double)); - - memcpy(s->coeff_A,A,stages*sizeof(double)); - memcpy(s->coeff_B,B,(stages+1)*sizeof(double)); +void +IIR_init (IIR_state * s, int stages, double gain, double *A, double *B) +{ + memset (s, 0, sizeof (IIR_state)); + s->stages = stages; + s->gain = gain; + s->coeff_A = malloc (stages * sizeof (double)); + s->coeff_B = malloc ((stages + 1) * sizeof (double)); + s->z_A = calloc (stages * 2, sizeof (double)); + s->z_B = calloc (stages * 2, sizeof (double)); + + memcpy (s->coeff_A, A, stages * sizeof (double)); + memcpy (s->coeff_B, B, (stages + 1) * sizeof (double)); } -void IIR_clear(IIR_state *s){ - if(s){ - free(s->coeff_A); - free(s->coeff_B); - free(s->z_A); - free(s->z_B); - memset(s,0,sizeof(IIR_state)); +void +IIR_clear (IIR_state * s) +{ + if (s) { + free (s->coeff_A); + free (s->coeff_B); + free (s->z_A); + free (s->z_B); + memset (s, 0, sizeof (IIR_state)); } } -double IIR_filter(IIR_state *s,double in){ - int stages=s->stages,i; +double +IIR_filter (IIR_state * s, double in) +{ + int stages = s->stages, i; double newA; - double newB=0; - double *zA=s->z_A+s->ring; + double newB = 0; + double *zA = s->z_A + s->ring; - newA=in/=s->gain; - for(i=0;i<stages;i++){ - newA+= s->coeff_A[i] * zA[i]; - newB+= s->coeff_B[i] * zA[i]; + newA = in /= s->gain; + for (i = 0; i < stages; i++) { + newA += s->coeff_A[i] * zA[i]; + newB += s->coeff_B[i] * zA[i]; } - newB+=newA*s->coeff_B[stages]; + newB += newA * s->coeff_B[stages]; - zA[0]=zA[stages]=newA; - if(++s->ring>=stages)s->ring=0; + zA[0] = zA[stages] = newA; + if (++s->ring >= stages) + s->ring = 0; - return(newB); + return (newB); } /* this assumes the symmetrical structure of the feed-forward stage of a Chebyshev bandpass to save multiplies */ -double IIR_filter_ChebBand(IIR_state *s,double in){ - int stages=s->stages,i; +double +IIR_filter_ChebBand (IIR_state * s, double in) +{ + int stages = s->stages, i; double newA; - double newB=0; - double *zA=s->z_A+s->ring; + double newB = 0; + double *zA = s->z_A + s->ring; - newA=in/=s->gain; + newA = in /= s->gain; - newA+= s->coeff_A[0] * zA[0]; - for(i=1;i<(stages>>1);i++){ - newA+= s->coeff_A[i] * zA[i]; - newB+= s->coeff_B[i] * (zA[i]-zA[stages-i]); + newA += s->coeff_A[0] * zA[0]; + for (i = 1; i < (stages >> 1); i++) { + newA += s->coeff_A[i] * zA[i]; + newB += s->coeff_B[i] * (zA[i] - zA[stages - i]); } - newB+= s->coeff_B[i] * zA[i]; - for(;i<stages;i++) - newA+= s->coeff_A[i] * zA[i]; + newB += s->coeff_B[i] * zA[i]; + for (; i < stages; i++) + newA += s->coeff_A[i] * zA[i]; - newB+= newA-zA[0]; + newB += newA - zA[0]; - zA[0]=zA[stages]=newA; - if(++s->ring>=stages)s->ring=0; + zA[0] = zA[stages] = newA; + if (++s->ring >= stages) + s->ring = 0; - return(newB); + return (newB); } #ifdef _V_SELFTEST /* z^-stage, z^-stage+1... */ -static double cheb_bandpass_B[]={-1.,0.,5.,0.,-10.,0.,10.,0.,-5.,0.,1}; -static double cheb_bandpass_A[]={-0.6665900311, - 1.0070146601, - -3.1262875409, - 3.5017171569, - -6.2779211945, - 5.2966481740, - -6.7570216587, - 4.0760335768, - -3.9134284363, - 1.3997338886}; - -static double data[128]={ +static double cheb_bandpass_B[] = + { -1., 0., 5., 0., -10., 0., 10., 0., -5., 0., 1 }; +static double cheb_bandpass_A[] = { -0.6665900311, + 1.0070146601, + -3.1262875409, + 3.5017171569, + -6.2779211945, + 5.2966481740, + -6.7570216587, + 4.0760335768, + -3.9134284363, + 1.3997338886 +}; + +static double data[128] = { 0.0426331, 0.0384521, 0.0345764, @@ -240,7 +252,8 @@ static double data[128]={ -0.0537415, -0.0610046, -0.0609741, - -0.0547791}; + -0.0547791 +}; /* comparison test code from http://www-users.cs.york.ac.uk/~fisher/mkfilter/ (the above page kicks ass, BTW)*/ @@ -249,58 +262,87 @@ static double data[128]={ #define NPOLES 10 #define GAIN 4.599477515e+02 -static float xv[NZEROS+1], yv[NPOLES+1]; - -static double filterloop(double next){ - xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; - xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; xv[8] = xv[9]; xv[9] = xv[10]; +static float xv[NZEROS + 1], yv[NPOLES + 1]; + +static double +filterloop (double next) +{ + xv[0] = xv[1]; + xv[1] = xv[2]; + xv[2] = xv[3]; + xv[3] = xv[4]; + xv[4] = xv[5]; + xv[5] = xv[6]; + xv[6] = xv[7]; + xv[7] = xv[8]; + xv[8] = xv[9]; + xv[9] = xv[10]; xv[10] = next / GAIN; - yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; - yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; yv[8] = yv[9]; yv[9] = yv[10]; - yv[10] = (xv[10] - xv[0]) + 5 * (xv[2] - xv[8]) + 10 * (xv[6] - xv[4]) - + ( -0.6665900311 * yv[0]) + ( 1.0070146601 * yv[1]) - + ( -3.1262875409 * yv[2]) + ( 3.5017171569 * yv[3]) - + ( -6.2779211945 * yv[4]) + ( 5.2966481740 * yv[5]) - + ( -6.7570216587 * yv[6]) + ( 4.0760335768 * yv[7]) - + ( -3.9134284363 * yv[8]) + ( 1.3997338886 * yv[9]); - return(yv[10]); + yv[0] = yv[1]; + yv[1] = yv[2]; + yv[2] = yv[3]; + yv[3] = yv[4]; + yv[4] = yv[5]; + yv[5] = yv[6]; + yv[6] = yv[7]; + yv[7] = yv[8]; + yv[8] = yv[9]; + yv[9] = yv[10]; + yv[10] = (xv[10] - xv[0]) + 5 * (xv[2] - xv[8]) + 10 * (xv[6] - xv[4]) + + (-0.6665900311 * yv[0]) + (1.0070146601 * yv[1]) + + (-3.1262875409 * yv[2]) + (3.5017171569 * yv[3]) + + (-6.2779211945 * yv[4]) + (5.2966481740 * yv[5]) + + (-6.7570216587 * yv[6]) + (4.0760335768 * yv[7]) + + (-3.9134284363 * yv[8]) + (1.3997338886 * yv[9]); + return (yv[10]); } #include <stdio.h> -int main(){ +int +main () +{ /* run the pregenerated Chebyshev filter, then our own distillation through the generic and specialized code */ - double *work=malloc(128*sizeof(double)); + double *work = malloc (128 * sizeof (double)); IIR_state iir; int i; - for(i=0;i<128;i++)work[i]=filterloop(data[i]); + for (i = 0; i < 128; i++) + work[i] = filterloop (data[i]); { - FILE *out=fopen("IIR_ref.m","w"); - for(i=0;i<128;i++)fprintf(out,"%g\n",work[i]); - fclose(out); + FILE *out = fopen ("IIR_ref.m", "w"); + + for (i = 0; i < 128; i++) + fprintf (out, "%g\n", work[i]); + fclose (out); } - IIR_init(&iir,NPOLES,GAIN,cheb_bandpass_A,cheb_bandpass_B); - for(i=0;i<128;i++)work[i]=IIR_filter(&iir,data[i]); + IIR_init (&iir, NPOLES, GAIN, cheb_bandpass_A, cheb_bandpass_B); + for (i = 0; i < 128; i++) + work[i] = IIR_filter (&iir, data[i]); { - FILE *out=fopen("IIR_gen.m","w"); - for(i=0;i<128;i++)fprintf(out,"%g\n",work[i]); - fclose(out); + FILE *out = fopen ("IIR_gen.m", "w"); + + for (i = 0; i < 128; i++) + fprintf (out, "%g\n", work[i]); + fclose (out); } - IIR_clear(&iir); + IIR_clear (&iir); - IIR_init(&iir,NPOLES,GAIN,cheb_bandpass_A,cheb_bandpass_B); - for(i=0;i<128;i++)work[i]=IIR_filter_ChebBand(&iir,data[i]); + IIR_init (&iir, NPOLES, GAIN, cheb_bandpass_A, cheb_bandpass_B); + for (i = 0; i < 128; i++) + work[i] = IIR_filter_ChebBand (&iir, data[i]); { - FILE *out=fopen("IIR_cheb.m","w"); - for(i=0;i<128;i++)fprintf(out,"%g\n",work[i]); - fclose(out); + FILE *out = fopen ("IIR_cheb.m", "w"); + + for (i = 0; i < 128; i++) + fprintf (out, "%g\n", work[i]); + fclose (out); } - IIR_clear(&iir); + IIR_clear (&iir); - return(0); + return (0); } #endif diff --git a/gst/filter/iir.h b/gst/filter/iir.h index 241cc1d2..1cea5663 100644 --- a/gst/filter/iir.h +++ b/gst/filter/iir.h @@ -19,7 +19,8 @@ #ifndef _V_IIR_H_ #define _V_IIR_H_ -typedef struct { +typedef struct +{ int stages; double *coeff_A; double *coeff_B; @@ -29,9 +30,9 @@ typedef struct { double gain; } IIR_state; -void IIR_init(IIR_state *s,int stages,double gain, double *A, double *B); -void IIR_clear(IIR_state *s); -double IIR_filter(IIR_state *s,double in); -double IIR_filter_ChebBand(IIR_state *s,double in); +void IIR_init (IIR_state * s, int stages, double gain, double *A, double *B); +void IIR_clear (IIR_state * s); +double IIR_filter (IIR_state * s, double in); +double IIR_filter_ChebBand (IIR_state * s, double in); #endif |