summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2010-01-07 17:25:05 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2010-01-07 17:28:43 +0100
commita9a5e0c7e1a3731c3ead52b6336d815a1603ac9c (patch)
tree1c8ba32597d93a8655ab7ffd3cdcef20328da68a
parented22a974787058928457f2cf734a2732791fcbed (diff)
audiofxbasefirfilter: Add property for not draining the history on kernel changes
Currently this only works if the kernel size doesn't change, in the future it will be possible to change the kernel size too without draining the complete history and without loosing anything. Partially based on a patch by Thiago Santos <thiago.sousa.santos@collabora.co.uk>
-rw-r--r--gst/audiofx/audiofirfilter.c7
-rw-r--r--gst/audiofx/audiofxbasefirfilter.c59
-rw-r--r--gst/audiofx/audiofxbasefirfilter.h3
3 files changed, 51 insertions, 18 deletions
diff --git a/gst/audiofx/audiofirfilter.c b/gst/audiofx/audiofirfilter.c
index df4e2dcb5..b6102ae78 100644
--- a/gst/audiofx/audiofirfilter.c
+++ b/gst/audiofx/audiofirfilter.c
@@ -148,9 +148,6 @@ gst_audio_fir_filter_update_kernel (GstAudioFIRFilter * self, GValueArray * va)
gdouble *kernel;
guint i;
- gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
- (self));
-
if (va) {
if (self->kernel)
g_value_array_free (self->kernel);
@@ -231,9 +228,7 @@ gst_audio_fir_filter_set_property (GObject * object, guint prop_id,
switch (prop_id) {
case PROP_KERNEL:
g_mutex_lock (self->lock);
- gst_audio_fx_base_fir_filter_push_residue (GST_AUDIO_FX_BASE_FIR_FILTER
- (self));
-
+ /* update kernel already pushes residues */
gst_audio_fir_filter_update_kernel (self, g_value_dup_boxed (value));
g_mutex_unlock (self->lock);
break;
diff --git a/gst/audiofx/audiofxbasefirfilter.c b/gst/audiofx/audiofxbasefirfilter.c
index fde7fb445..37fa639cf 100644
--- a/gst/audiofx/audiofxbasefirfilter.c
+++ b/gst/audiofx/audiofxbasefirfilter.c
@@ -59,10 +59,12 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
enum
{
PROP_0 = 0,
- PROP_LOW_LATENCY
+ PROP_LOW_LATENCY,
+ PROP_DRAIN_ON_CHANGES
};
#define DEFAULT_LOW_LATENCY FALSE
+#define DEFAULT_DRAIN_ON_CHANGES TRUE
GST_BOILERPLATE_FULL (GstAudioFXBaseFIRFilter, gst_audio_fx_base_fir_filter,
GstAudioFilter, GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
@@ -290,6 +292,8 @@ process_fft_##channels##_##width (GstAudioFXBaseFIRFilter * self, const g##ctype
self->buffer_fill = buffer_fill = kernel_length - 1; \
} \
\
+ g_assert (self->buffer_length == block_length); \
+ \
while (input_samples) { \
pass = MIN (buffer_length - buffer_fill, input_samples); \
\
@@ -505,6 +509,12 @@ gst_audio_fx_base_fir_filter_set_property (GObject * object, guint prop_id,
GST_BASE_TRANSFORM_UNLOCK (self);
break;
}
+ case PROP_DRAIN_ON_CHANGES:{
+ GST_BASE_TRANSFORM_LOCK (self);
+ self->drain_on_changes = g_value_get_boolean (value);
+ GST_BASE_TRANSFORM_UNLOCK (self);
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -521,6 +531,9 @@ gst_audio_fx_base_fir_filter_get_property (GObject * object, guint prop_id,
case PROP_LOW_LATENCY:
g_value_set_boolean (value, self->low_latency);
break;
+ case PROP_DRAIN_ON_CHANGES:
+ g_value_set_boolean (value, self->drain_on_changes);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -564,6 +577,22 @@ gst_audio_fx_base_fir_filter_class_init (GstAudioFXBaseFIRFilterClass * klass)
"Can only be changed in states < PAUSED!", DEFAULT_LOW_LATENCY,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstAudioFXBaseFIRFilter::drain-on-changes:
+ *
+ * Whether the filter should be drained when its coeficients change
+ *
+ * Note: Currently this only works if the kernel size is not changed!
+ * Support for drainless kernel size changes will be added in the future.
+ *
+ * Since: 0.10.18
+ */
+ g_object_class_install_property (gobject_class, PROP_DRAIN_ON_CHANGES,
+ g_param_spec_boolean ("drain-on-changes", "Drain on changes",
+ "Drains the filter when its coeficients change",
+ DEFAULT_DRAIN_ON_CHANGES,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
trans_class->transform =
GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_transform);
trans_class->start = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_start);
@@ -588,6 +617,7 @@ gst_audio_fx_base_fir_filter_init (GstAudioFXBaseFIRFilter * self,
self->nsamples_in = 0;
self->low_latency = DEFAULT_LOW_LATENCY;
+ self->drain_on_changes = DEFAULT_DRAIN_ON_CHANGES;
gst_pad_set_query_function (GST_BASE_TRANSFORM (self)->srcpad,
gst_audio_fx_base_fir_filter_query);
@@ -1009,7 +1039,16 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self,
g_return_if_fail (self != NULL);
GST_BASE_TRANSFORM_LOCK (self);
- if (self->buffer) {
+
+ latency_changed = (self->latency != latency
+ || (!self->low_latency && self->kernel_length < FFT_THRESHOLD
+ && kernel_length >= FFT_THRESHOLD)
+ || (!self->low_latency && self->kernel_length >= FFT_THRESHOLD
+ && kernel_length < FFT_THRESHOLD));
+
+ /* FIXME: If the latency changes, the buffer size changes too and we
+ * have to drain in any case until this is fixed in the future */
+ if (self->buffer && (!self->drain_on_changes || latency_changed)) {
gst_audio_fx_base_fir_filter_push_residue (self);
self->start_ts = GST_CLOCK_TIME_NONE;
self->start_off = GST_BUFFER_OFFSET_NONE;
@@ -1018,17 +1057,13 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self,
self->buffer_fill = 0;
}
- latency_changed = (self->latency != latency
- || (!self->low_latency && self->kernel_length < FFT_THRESHOLD
- && kernel_length >= FFT_THRESHOLD)
- || (!self->low_latency && self->kernel_length >= FFT_THRESHOLD
- && kernel_length < FFT_THRESHOLD));
-
g_free (self->kernel);
- g_free (self->buffer);
- self->buffer = NULL;
- self->buffer_fill = 0;
- self->buffer_length = 0;
+ if (!self->drain_on_changes || latency_changed) {
+ g_free (self->buffer);
+ self->buffer = NULL;
+ self->buffer_fill = 0;
+ self->buffer_length = 0;
+ }
self->kernel = kernel;
self->kernel_length = kernel_length;
diff --git a/gst/audiofx/audiofxbasefirfilter.h b/gst/audiofx/audiofxbasefirfilter.h
index ed0ec7540..c9eeb1bc2 100644
--- a/gst/audiofx/audiofxbasefirfilter.h
+++ b/gst/audiofx/audiofxbasefirfilter.h
@@ -62,6 +62,9 @@ struct _GstAudioFXBaseFIRFilter {
guint64 latency; /* pre-latency of the filter kernel */
gboolean low_latency; /* work in slower low latency mode */
+ gboolean drain_on_changes; /* If the filter should be drained when
+ * coeficients change */
+
/* < private > */
GstAudioFXBaseFIRFilterProcessFunc process;