summaryrefslogtreecommitdiffstats
path: root/gst/filter
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2007-08-10 04:21:39 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2007-08-10 04:21:39 +0000
commit882fd5c387f9f6fa51038e9517c7b0ad665e0b0e (patch)
tree68355a391ba06d32cb58b0b44c10729224c79845 /gst/filter
parent3dffa0f9e68d6401cd38937ca562f84ab33b93b1 (diff)
downloadgst-plugins-bad-882fd5c387f9f6fa51038e9517c7b0ad665e0b0e.tar.gz
gst-plugins-bad-882fd5c387f9f6fa51038e9517c7b0ad665e0b0e.tar.bz2
gst-plugins-bad-882fd5c387f9f6fa51038e9517c7b0ad665e0b0e.zip
gst/filter/gstlpwsinc.*: Add a highpass mode.
Original commit message from CVS: * gst/filter/gstlpwsinc.c: (gst_lpwsinc_mode_get_type), (gst_lpwsinc_class_init), (process_32), (process_64), (lpwsinc_build_kernel), (lpwsinc_set_property), (lpwsinc_get_property): * gst/filter/gstlpwsinc.h: Add a highpass mode.
Diffstat (limited to 'gst/filter')
-rw-r--r--gst/filter/gstlpwsinc.c67
-rw-r--r--gst/filter/gstlpwsinc.h1
2 files changed, 58 insertions, 10 deletions
diff --git a/gst/filter/gstlpwsinc.c b/gst/filter/gstlpwsinc.c
index 1ba193a9..8f4ec530 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.
- * - Implement a highpass mode (spectral inversion)
* - 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.
@@ -50,10 +49,9 @@
#define GST_CAT_DEFAULT gst_lpwsinc_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-static const GstElementDetails lpwsinc_details =
-GST_ELEMENT_DETAILS ("Low-pass Windowed sinc filter",
+static const GstElementDetails lpwsinc_details = GST_ELEMENT_DETAILS ("LPWSinc",
"Filter/Effect/Audio",
- "Low-pass Windowed sinc filter",
+ "Low-pass and High-pass Windowed sinc filter",
"Thomas <thomas@apestaart.org>, "
"Steven W. Smith, "
"Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>, "
@@ -70,9 +68,36 @@ enum
{
PROP_0,
PROP_LENGTH,
- PROP_FREQUENCY
+ PROP_FREQUENCY,
+ PROP_MODE
};
+enum
+{
+ MODE_LOW_PASS = 0,
+ MODE_HIGH_PASS
+};
+
+#define GST_TYPE_LPWSINC_MODE (gst_lpwsinc_mode_get_type ())
+static GType
+gst_lpwsinc_mode_get_type (void)
+{
+ static GType gtype = 0;
+
+ if (gtype == 0) {
+ static const GEnumValue values[] = {
+ {MODE_LOW_PASS, "Low pass (default)",
+ "low-pass"},
+ {MODE_HIGH_PASS, "High pass",
+ "high-pass"},
+ {0, NULL, NULL}
+ };
+
+ gtype = g_enum_register_static ("GstLPWSincMode", values);
+ }
+ return gtype;
+}
+
#define ALLOWED_CAPS \
"audio/x-raw-float," \
" width = (int) { 32, 64 }, " \
@@ -81,7 +106,7 @@ enum
" channels = (int) [ 1, MAX ]"
#define DEBUG_INIT(bla) \
- GST_DEBUG_CATEGORY_INIT (gst_lpwsinc_debug, "lpwsinc", 0, "Low-pass Windowed sinc filter plugin");
+ GST_DEBUG_CATEGORY_INIT (gst_lpwsinc_debug, "lpwsinc", 0, "Low-pass and High-pass Windowed sinc filter plugin");
GST_BOILERPLATE_FULL (GstLPWSinc, gst_lpwsinc, GstAudioFilter,
GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
@@ -147,12 +172,18 @@ gst_lpwsinc_class_init (GstLPWSincClass * klass)
g_object_class_install_property (gobject_class, PROP_FREQUENCY,
g_param_spec_double ("frequency", "Frequency",
- "Cut-off Frequency", 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE));
+ "Cut-off Frequency", 0.0, G_MAXDOUBLE, 0.0,
+ G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
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));
+ 1, G_MAXINT, 1, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, PROP_MODE,
+ g_param_spec_enum ("mode", "Mode",
+ "Low pass or high pass mode", GST_TYPE_LPWSINC_MODE,
+ MODE_LOW_PASS, 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);
@@ -173,7 +204,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->wing_size * 2 + 1;
gint i, j, k, l;
gint channels = GST_AUDIO_FILTER (self)->format.channels;
@@ -200,7 +231,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->wing_size * 2 + 1;
gint i, j, k, l;
gint channels = GST_AUDIO_FILTER (self)->format.channels;
@@ -270,6 +301,13 @@ lpwsinc_build_kernel (GstLPWSinc * self)
for (i = 0; i <= len * 2; ++i)
self->kernel[i] /= sum;
+ /* convert to highpass if specified */
+ if (self->mode == MODE_HIGH_PASS) {
+ for (i = 0; i <= len * 2; ++i)
+ self->kernel[i] = -self->kernel[i];
+ self->kernel[len] += 1.0;
+ }
+
/* set up the residue memory space */
if (self->residue)
g_free (self->residue);
@@ -370,6 +408,12 @@ lpwsinc_set_property (GObject * object, guint prop_id, const GValue * value,
lpwsinc_build_kernel (self);
GST_BASE_TRANSFORM_UNLOCK (self);
break;
+ case PROP_MODE:
+ GST_BASE_TRANSFORM_LOCK (self);
+ self->mode = 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;
@@ -389,6 +433,9 @@ lpwsinc_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_FREQUENCY:
g_value_set_double (value, self->frequency);
break;
+ case PROP_MODE:
+ g_value_set_enum (value, self->mode);
+ 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 afb7e9c7..bc9377f6 100644
--- a/gst/filter/gstlpwsinc.h
+++ b/gst/filter/gstlpwsinc.h
@@ -66,6 +66,7 @@ struct _GstLPWSinc {
GstLPWSincProcessFunc process;
+ gint mode;
gdouble frequency;
gint wing_size; /* length of a "wing" of the filter;
actual length is 2 * wing_size + 1 */