diff options
author | Thiago Santos <thiago.sousa.santos@collabora.co.uk> | 2009-12-23 14:01:41 -0300 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2010-01-07 17:33:05 +0100 |
commit | c99c9eee69c1f2d61e73d061349ee5d180b50f91 (patch) | |
tree | 011e0fb29069018ff85e066be3f636ba47ac4fdd | |
parent | a9a5e0c7e1a3731c3ead52b6336d815a1603ac9c (diff) |
audiofxbasefirfilter: property for not draining on changes
Adds a new property for not draining the buffers when the
kernel changes
-rw-r--r-- | gst/audiofx/audiofxbasefirfilter.c | 66 |
1 files changed, 59 insertions, 7 deletions
diff --git a/gst/audiofx/audiofxbasefirfilter.c b/gst/audiofx/audiofxbasefirfilter.c index 37fa639cf..61aa8c62e 100644 --- a/gst/audiofx/audiofxbasefirfilter.c +++ b/gst/audiofx/audiofxbasefirfilter.c @@ -582,9 +582,6 @@ gst_audio_fx_base_fir_filter_class_init (GstAudioFXBaseFIRFilterClass * klass) * * 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, @@ -1030,10 +1027,59 @@ gst_audio_fx_base_fir_filter_event (GstBaseTransform * base, GstEvent * event) } void +gst_audio_fx_base_fir_filter_update_buffer_size (GstAudioFXBaseFIRFilter * self, + guint channels, guint old_kernel_length, guint old_real_buffer_length) +{ + gdouble *old_buffer = self->buffer; + guint size = 0; + gint c; + + if (!self->fft) { + size = channels * self->kernel_length; + self->buffer_length = size; + self->buffer = g_new0 (gdouble, self->buffer_length); + if (old_buffer) { + memcpy (self->buffer, old_buffer, + sizeof (gdouble) * MIN (self->buffer_fill, size)); + g_free (old_buffer); + } + } else { + guint real_buffer_length = self->block_length + self->kernel_length - 1; + size = channels * real_buffer_length; + + self->buffer = g_new0 (gdouble, size); + self->buffer_length = self->block_length; + + for (c = 0; c < channels; c++) { + /* copy the kernel */ + memcpy (self->buffer + c * real_buffer_length, + old_buffer + c * (old_real_buffer_length), + sizeof (gdouble) * MIN (old_kernel_length - 1, + self->kernel_length - 1)); + /* copy the channel residue */ + memcpy (self->buffer + c * real_buffer_length + self->kernel_length - 1, + old_buffer + c * old_real_buffer_length + old_kernel_length - 1, + sizeof (gdouble) * + MIN ((old_real_buffer_length - (old_kernel_length - 1)), + real_buffer_length - (self->kernel_length - 1))); + } + self->buffer_length = self->block_length; + if (self->buffer_fill < self->kernel_length - 1) { + self->buffer_fill = self->kernel_length - 1; + } + } + + /* FIXME check what would happen if the new buffer is too short + * and if that is possible at all */ +} + +void gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, gdouble * kernel, guint kernel_length, guint64 latency) { gboolean latency_changed; + guint old_kernel_length; + guint old_buffer_length; g_return_if_fail (kernel != NULL); g_return_if_fail (self != NULL); @@ -1046,9 +1092,7 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, || (!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)) { + if (self->buffer && !self->drain_on_changes) { gst_audio_fx_base_fir_filter_push_residue (self); self->start_ts = GST_CLOCK_TIME_NONE; self->start_off = GST_BUFFER_OFFSET_NONE; @@ -1058,13 +1102,16 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, } g_free (self->kernel); - if (!self->drain_on_changes || latency_changed) { + + if (!self->drain_on_changes) { g_free (self->buffer); self->buffer = NULL; self->buffer_fill = 0; self->buffer_length = 0; } + old_buffer_length = self->buffer_length; + old_kernel_length = self->kernel_length; self->kernel = kernel; self->kernel_length = kernel_length; @@ -1072,6 +1119,11 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self, gst_audio_fx_base_fir_filter_select_process_function (self, GST_AUDIO_FILTER_CAST (self)->format.width, GST_AUDIO_FILTER_CAST (self)->format.channels); + if (!self->drain_on_changes) { + gst_audio_fx_base_fir_filter_update_buffer_size (self, + GST_AUDIO_FILTER_CAST (self)->format.channels, old_kernel_length, + old_buffer_length + old_kernel_length - 1); + } if (latency_changed) { self->latency = latency; |