mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 00:58:12 +00:00
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.
This commit is contained in:
parent
0e4fc6653a
commit
85e572a4cc
2 changed files with 58 additions and 10 deletions
|
@ -29,7 +29,6 @@
|
||||||
* TODO: - Implement the convolution in place, probably only makes sense
|
* TODO: - Implement the convolution in place, probably only makes sense
|
||||||
* when using FFT convolution as currently the convolution itself
|
* when using FFT convolution as currently the convolution itself
|
||||||
* is probably the bottleneck.
|
* is probably the bottleneck.
|
||||||
* - Implement a highpass mode (spectral inversion)
|
|
||||||
* - Allow choosing between different windows (blackman, hanning, ...)
|
* - Allow choosing between different windows (blackman, hanning, ...)
|
||||||
* - Maybe allow cascading the filter to get a better stopband attenuation.
|
* - Maybe allow cascading the filter to get a better stopband attenuation.
|
||||||
* Can be done by convolving a filter kernel with itself.
|
* Can be done by convolving a filter kernel with itself.
|
||||||
|
@ -50,10 +49,9 @@
|
||||||
#define GST_CAT_DEFAULT gst_lpwsinc_debug
|
#define GST_CAT_DEFAULT gst_lpwsinc_debug
|
||||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||||
|
|
||||||
static const GstElementDetails lpwsinc_details =
|
static const GstElementDetails lpwsinc_details = GST_ELEMENT_DETAILS ("LPWSinc",
|
||||||
GST_ELEMENT_DETAILS ("Low-pass Windowed sinc filter",
|
|
||||||
"Filter/Effect/Audio",
|
"Filter/Effect/Audio",
|
||||||
"Low-pass Windowed sinc filter",
|
"Low-pass and High-pass Windowed sinc filter",
|
||||||
"Thomas <thomas@apestaart.org>, "
|
"Thomas <thomas@apestaart.org>, "
|
||||||
"Steven W. Smith, "
|
"Steven W. Smith, "
|
||||||
"Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>, "
|
"Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>, "
|
||||||
|
@ -70,9 +68,36 @@ enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_LENGTH,
|
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 \
|
#define ALLOWED_CAPS \
|
||||||
"audio/x-raw-float," \
|
"audio/x-raw-float," \
|
||||||
" width = (int) { 32, 64 }, " \
|
" width = (int) { 32, 64 }, " \
|
||||||
|
@ -81,7 +106,7 @@ enum
|
||||||
" channels = (int) [ 1, MAX ]"
|
" channels = (int) [ 1, MAX ]"
|
||||||
|
|
||||||
#define DEBUG_INIT(bla) \
|
#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_BOILERPLATE_FULL (GstLPWSinc, gst_lpwsinc, GstAudioFilter,
|
||||||
GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
|
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_object_class_install_property (gobject_class, PROP_FREQUENCY,
|
||||||
g_param_spec_double ("frequency", "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_object_class_install_property (gobject_class, PROP_LENGTH,
|
||||||
g_param_spec_int ("length", "Length",
|
g_param_spec_int ("length", "Length",
|
||||||
"N such that the filter length = 2N + 1",
|
"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->transform = GST_DEBUG_FUNCPTR (lpwsinc_transform);
|
||||||
trans_class->get_unit_size = GST_DEBUG_FUNCPTR (lpwsinc_get_unit_size);
|
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
|
static void
|
||||||
process_32 (GstLPWSinc * self, gfloat * src, gfloat * dst, guint input_samples)
|
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 i, j, k, l;
|
||||||
gint channels = GST_AUDIO_FILTER (self)->format.channels;
|
gint channels = GST_AUDIO_FILTER (self)->format.channels;
|
||||||
|
|
||||||
|
@ -200,7 +231,7 @@ static void
|
||||||
process_64 (GstLPWSinc * self, gdouble * src, gdouble * dst,
|
process_64 (GstLPWSinc * self, gdouble * src, gdouble * dst,
|
||||||
guint input_samples)
|
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 i, j, k, l;
|
||||||
gint channels = GST_AUDIO_FILTER (self)->format.channels;
|
gint channels = GST_AUDIO_FILTER (self)->format.channels;
|
||||||
|
|
||||||
|
@ -270,6 +301,13 @@ lpwsinc_build_kernel (GstLPWSinc * self)
|
||||||
for (i = 0; i <= len * 2; ++i)
|
for (i = 0; i <= len * 2; ++i)
|
||||||
self->kernel[i] /= sum;
|
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 */
|
/* set up the residue memory space */
|
||||||
if (self->residue)
|
if (self->residue)
|
||||||
g_free (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);
|
lpwsinc_build_kernel (self);
|
||||||
GST_BASE_TRANSFORM_UNLOCK (self);
|
GST_BASE_TRANSFORM_UNLOCK (self);
|
||||||
break;
|
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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -389,6 +433,9 @@ lpwsinc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
case PROP_FREQUENCY:
|
case PROP_FREQUENCY:
|
||||||
g_value_set_double (value, self->frequency);
|
g_value_set_double (value, self->frequency);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MODE:
|
||||||
|
g_value_set_enum (value, self->mode);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct _GstLPWSinc {
|
||||||
|
|
||||||
GstLPWSincProcessFunc process;
|
GstLPWSincProcessFunc process;
|
||||||
|
|
||||||
|
gint mode;
|
||||||
gdouble frequency;
|
gdouble frequency;
|
||||||
gint wing_size; /* length of a "wing" of the filter;
|
gint wing_size; /* length of a "wing" of the filter;
|
||||||
actual length is 2 * wing_size + 1 */
|
actual length is 2 * wing_size + 1 */
|
||||||
|
|
Loading…
Reference in a new issue