summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>2009-12-23 14:01:41 -0300
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2010-01-07 17:33:05 +0100
commitc99c9eee69c1f2d61e73d061349ee5d180b50f91 (patch)
tree011e0fb29069018ff85e066be3f636ba47ac4fdd
parenta9a5e0c7e1a3731c3ead52b6336d815a1603ac9c (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.c66
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;