* 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.
*/
PROP_0,
PROP_LENGTH,
PROP_FREQUENCY,
- PROP_MODE
+ PROP_MODE,
+ PROP_WINDOW
};
enum
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 }, " \
"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);
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;
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 */
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;
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;