diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-01-07 17:25:05 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-01-07 17:28:43 +0100 |
commit | a9a5e0c7e1a3731c3ead52b6336d815a1603ac9c (patch) | |
tree | 1c8ba32597d93a8655ab7ffd3cdcef20328da68a | |
parent | ed22a974787058928457f2cf734a2732791fcbed (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.c | 7 | ||||
-rw-r--r-- | gst/audiofx/audiofxbasefirfilter.c | 59 | ||||
-rw-r--r-- | gst/audiofx/audiofxbasefirfilter.h | 3 |
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; |