various: fix pad template leaks
[platform/upstream/gst-plugins-good.git] / gst / audiofx / audiofxbasefirfilter.c
1 /* -*- c-basic-offset: 2 -*-
2  * 
3  * GStreamer
4  * Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
5  *               2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
6  *               2007-2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  * 
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <string.h>
30 #include <math.h>
31 #include <gst/gst.h>
32 #include <gst/audio/gstaudiofilter.h>
33 #include <gst/controller/gstcontroller.h>
34
35 /* FIXME: Remove this once we depend on gst-plugins-base 0.10.26 */
36 #ifndef GST_AUDIO_FILTER_CAST
37 #define GST_AUDIO_FILTER_CAST(obj) ((GstAudioFilter *) (obj))
38 #endif
39
40 #include "audiofxbasefirfilter.h"
41
42 #define GST_CAT_DEFAULT gst_audio_fx_base_fir_filter_debug
43 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
44
45 #define ALLOWED_CAPS \
46     "audio/x-raw-float, "                                             \
47     " width = (int) { 32, 64 }, "                                     \
48     " endianness = (int) BYTE_ORDER, "                                \
49     " rate = (int) [ 1, MAX ], "                                      \
50     " channels = (int) [ 1, MAX ]"
51
52 #define DEBUG_INIT(bla) \
53   GST_DEBUG_CATEGORY_INIT (gst_audio_fx_base_fir_filter_debug, "audiofxbasefirfilter", 0, \
54       "FIR filter base class");
55
56 /* Switch from time-domain to FFT convolution for kernels >= this */
57 #define FFT_THRESHOLD 32
58
59 enum
60 {
61   PROP_0 = 0,
62   PROP_LOW_LATENCY,
63   PROP_DRAIN_ON_CHANGES
64 };
65
66 #define DEFAULT_LOW_LATENCY FALSE
67 #define DEFAULT_DRAIN_ON_CHANGES TRUE
68
69 GST_BOILERPLATE_FULL (GstAudioFXBaseFIRFilter, gst_audio_fx_base_fir_filter,
70     GstAudioFilter, GST_TYPE_AUDIO_FILTER, DEBUG_INIT);
71
72 static GstFlowReturn gst_audio_fx_base_fir_filter_transform (GstBaseTransform *
73     base, GstBuffer * inbuf, GstBuffer * outbuf);
74 static gboolean gst_audio_fx_base_fir_filter_start (GstBaseTransform * base);
75 static gboolean gst_audio_fx_base_fir_filter_stop (GstBaseTransform * base);
76 static gboolean gst_audio_fx_base_fir_filter_event (GstBaseTransform * base,
77     GstEvent * event);
78 static gboolean gst_audio_fx_base_fir_filter_transform_size (GstBaseTransform *
79     base, GstPadDirection direction, GstCaps * caps, guint size,
80     GstCaps * othercaps, guint * othersize);
81 static gboolean gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
82     GstRingBufferSpec * format);
83
84 static gboolean gst_audio_fx_base_fir_filter_query (GstPad * pad,
85     GstQuery * query);
86 static const GstQueryType *gst_audio_fx_base_fir_filter_query_type (GstPad *
87     pad);
88
89 /* 
90  * The code below calculates the linear convolution:
91  *
92  * y[t] = \sum_{u=0}^{M-1} x[t - u] * h[u]
93  *
94  * where y is the output, x is the input, M is the length
95  * of the filter kernel and h is the filter kernel. For x
96  * holds: x[t] == 0 \forall t < 0.
97  *
98  * The runtime complexity of this is O (M) per sample.
99  *
100  */
101 #define DEFINE_PROCESS_FUNC(width,ctype) \
102 static guint \
103 process_##width (GstAudioFXBaseFIRFilter * self, const g##ctype * src, g##ctype * dst, guint input_samples) \
104 { \
105   gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels; \
106   TIME_DOMAIN_CONVOLUTION_BODY (channels); \
107 }
108
109 #define DEFINE_PROCESS_FUNC_FIXED_CHANNELS(width,channels,ctype) \
110 static guint \
111 process_##channels##_##width (GstAudioFXBaseFIRFilter * self, const g##ctype * src, g##ctype * dst, guint input_samples) \
112 { \
113   TIME_DOMAIN_CONVOLUTION_BODY (channels); \
114 }
115
116 #define TIME_DOMAIN_CONVOLUTION_BODY(channels) G_STMT_START { \
117   gint kernel_length = self->kernel_length; \
118   gint i, j, k, l; \
119   gint res_start; \
120   gint from_input; \
121   gint off; \
122   gdouble *buffer = self->buffer; \
123   gdouble *kernel = self->kernel; \
124   guint buffer_length = self->buffer_length; \
125   \
126   if (!buffer) { \
127     self->buffer_length = buffer_length = kernel_length * channels; \
128     self->buffer = buffer = g_new0 (gdouble, self->buffer_length); \
129   } \
130   \
131   /* convolution */ \
132   for (i = 0; i < input_samples; i++) { \
133     dst[i] = 0.0; \
134     k = i % channels; \
135     l = i / channels; \
136     from_input = MIN (l, kernel_length-1); \
137     off = l * channels + k; \
138     for (j = 0; j <= from_input; j++) { \
139       dst[i] += src[off] * kernel[j]; \
140       off -= channels; \
141     } \
142     /* j == from_input && off == (l - j) * channels + k */ \
143     off += kernel_length * channels; \
144     for (; j < kernel_length; j++) { \
145       dst[i] += buffer[off] * kernel[j]; \
146       off -= channels; \
147     } \
148   } \
149   \
150   /* copy the tail of the current input buffer to the residue, while \
151    * keeping parts of the residue if the input buffer is smaller than \
152    * the kernel length */ \
153   /* from now on take kernel length as length over all channels */ \
154   kernel_length *= channels; \
155   if (input_samples < kernel_length) \
156     res_start = kernel_length - input_samples; \
157   else \
158     res_start = 0; \
159   \
160   for (i = 0; i < res_start; i++) \
161     buffer[i] = buffer[i + input_samples]; \
162   /* i == res_start */ \
163   for (; i < kernel_length; i++) \
164     buffer[i] = src[input_samples - kernel_length + i]; \
165   \
166   self->buffer_fill += kernel_length - res_start; \
167   if (self->buffer_fill > kernel_length) \
168     self->buffer_fill = kernel_length; \
169   \
170   return input_samples / channels; \
171 } G_STMT_END
172
173 DEFINE_PROCESS_FUNC (32, float);
174 DEFINE_PROCESS_FUNC (64, double);
175
176 DEFINE_PROCESS_FUNC_FIXED_CHANNELS (32, 1, float);
177 DEFINE_PROCESS_FUNC_FIXED_CHANNELS (64, 1, double);
178
179 DEFINE_PROCESS_FUNC_FIXED_CHANNELS (32, 2, float);
180 DEFINE_PROCESS_FUNC_FIXED_CHANNELS (64, 2, double);
181
182 #undef TIME_DOMAIN_CONVOLUTION_BODY
183 #undef DEFINE_PROCESS_FUNC
184 #undef DEFINE_PROCESS_FUNC_FIXED_CHANNELS
185
186 /* This implements FFT convolution and uses the overlap-save algorithm.
187  * See http://cnx.org/content/m12022/latest/ or your favorite
188  * digital signal processing book for details.
189  *
190  * In every pass the following is calculated:
191  *
192  * y = IFFT (FFT(x) * FFT(h))
193  *
194  * where y is the output in the time domain, x the
195  * input and h the filter kernel. * is the multiplication
196  * of complex numbers.
197  *
198  * Due to the circular convolution theorem this
199  * gives in the time domain:
200  *
201  * y[t] = \sum_{u=0}^{M-1} x[t - u] * h[u]
202  *
203  * where y is the output, M is the kernel length,
204  * x the periodically extended[0] input and h the
205  * filter kernel.
206  *
207  * ([0] Periodically extended means:    )
208  * (    x[t] = x[t+kN] \forall k \in Z  )
209  * (    where N is the length of x      )
210  *
211  * This means:
212  * - Obviously x and h need to be of the same size for the FFT
213  * - The first M-1 output values are useless because they're
214  *   built from 1 up to M-1 values from the end of the input
215  *   (circular convolusion!).
216  * - The last M-1 input values are only used for 1 up to M-1
217  *   output values, i.e. they need to be used again in the
218  *   next pass for the first M-1 input values.
219  *
220  * => The first pass needs M-1 zeroes at the beginning of the
221  * input and the last M-1 input values of every pass need to
222  * be used as the first M-1 input values of the next pass.
223  *
224  * => x must be larger than h to give a useful number of output
225  * samples and h needs to be padded by zeroes at the end to give
226  * it virtually the same size as x (by M we denote the number of
227  * non-padding samples of h). If len(x)==len(h)==M only 1 output
228  * sample would be calculated per pass, len(x)==2*len(h) would
229  * give M+1 output samples, etc. Usually a factor between 4 and 8
230  * gives a low number of operations per output samples (see website
231  * given above).
232  *
233  * Overall this gives a runtime complexity per sample of
234  *
235  *   (  N log N  )
236  * O ( --------- ) compared to O (M) for the direct calculation.
237  *   ( N - M + 1 )
238  */
239 #define DEFINE_FFT_PROCESS_FUNC(width,ctype) \
240 static guint \
241 process_fft_##width (GstAudioFXBaseFIRFilter * self, const g##ctype * src, \
242     g##ctype * dst, guint input_samples) \
243 { \
244   gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels; \
245   FFT_CONVOLUTION_BODY (channels); \
246 }
247
248 #define DEFINE_FFT_PROCESS_FUNC_FIXED_CHANNELS(width,channels,ctype) \
249 static guint \
250 process_fft_##channels##_##width (GstAudioFXBaseFIRFilter * self, const g##ctype * src, \
251     g##ctype * dst, guint input_samples) \
252 { \
253   FFT_CONVOLUTION_BODY (channels); \
254 }
255
256 #define FFT_CONVOLUTION_BODY(channels) G_STMT_START { \
257   gint i, j; \
258   guint pass; \
259   guint kernel_length = self->kernel_length; \
260   guint block_length = self->block_length; \
261   guint buffer_length = self->buffer_length; \
262   guint real_buffer_length = buffer_length + kernel_length - 1; \
263   guint buffer_fill = self->buffer_fill; \
264   GstFFTF64 *fft = self->fft; \
265   GstFFTF64 *ifft = self->ifft; \
266   GstFFTF64Complex *frequency_response = self->frequency_response; \
267   GstFFTF64Complex *fft_buffer = self->fft_buffer; \
268   guint frequency_response_length = self->frequency_response_length; \
269   gdouble *buffer = self->buffer; \
270   guint generated = 0; \
271   gdouble re, im; \
272   \
273   if (!fft_buffer) \
274     self->fft_buffer = fft_buffer = \
275         g_new (GstFFTF64Complex, frequency_response_length); \
276   \
277   /* Buffer contains the time domain samples of input data for one chunk \
278    * plus some more space for the inverse FFT below. \
279    * \
280    * The samples are put at offset kernel_length, the inverse FFT \
281    * overwrites everthing from offset 0 to length-kernel_length+1, keeping \
282    * the last kernel_length-1 samples for copying to the next processing \
283    * step. \
284    */ \
285   if (!buffer) { \
286     self->buffer_length = buffer_length = block_length; \
287     real_buffer_length = buffer_length + kernel_length - 1; \
288     \
289     self->buffer = buffer = g_new0 (gdouble, real_buffer_length * channels); \
290     \
291     /* Beginning has kernel_length-1 zeroes at the beginning */ \
292     self->buffer_fill = buffer_fill = kernel_length - 1; \
293   } \
294   \
295   g_assert (self->buffer_length == block_length); \
296   \
297   while (input_samples) { \
298     pass = MIN (buffer_length - buffer_fill, input_samples); \
299     \
300     /* Deinterleave channels */ \
301     for (i = 0; i < pass; i++) { \
302       for (j = 0; j < channels; j++) { \
303         buffer[real_buffer_length * j + buffer_fill + kernel_length - 1 + i] = \
304             src[i * channels + j]; \
305       } \
306     } \
307     buffer_fill += pass; \
308     src += channels * pass; \
309     input_samples -= pass; \
310     \
311     /* If we don't have a complete buffer go out */ \
312     if (buffer_fill < buffer_length) \
313       break; \
314     \
315     for (j = 0; j < channels; j++) { \
316       /* Calculate FFT of input block */ \
317       gst_fft_f64_fft (fft, \
318           buffer + real_buffer_length * j + kernel_length - 1, fft_buffer); \
319       \
320       /* Complex multiplication of input and filter spectrum */ \
321       for (i = 0; i < frequency_response_length; i++) { \
322         re = fft_buffer[i].r; \
323         im = fft_buffer[i].i; \
324         \
325         fft_buffer[i].r = \
326             re * frequency_response[i].r - \
327             im * frequency_response[i].i; \
328         fft_buffer[i].i = \
329             re * frequency_response[i].i + \
330             im * frequency_response[i].r; \
331       } \
332       \
333       /* Calculate inverse FFT of the result */ \
334       gst_fft_f64_inverse_fft (ifft, fft_buffer, \
335           buffer + real_buffer_length * j); \
336       \
337       /* Copy all except the first kernel_length-1 samples to the output */ \
338       for (i = 0; i < buffer_length - kernel_length + 1; i++) { \
339         dst[i * channels + j] = \
340             buffer[real_buffer_length * j + kernel_length - 1 + i]; \
341       } \
342       \
343       /* Copy the last kernel_length-1 samples to the beginning for the next block */ \
344       for (i = 0; i < kernel_length - 1; i++) { \
345         buffer[real_buffer_length * j + kernel_length - 1 + i] = \
346             buffer[real_buffer_length * j + buffer_length + i]; \
347       } \
348     } \
349     \
350     generated += buffer_length - kernel_length + 1; \
351     dst += channels * (buffer_length - kernel_length + 1); \
352     \
353     /* The the first kernel_length-1 samples are there already */ \
354     buffer_fill = kernel_length - 1; \
355   } \
356   \
357   /* Write back cached buffer_fill value */ \
358   self->buffer_fill = buffer_fill; \
359   \
360   return generated; \
361 } G_STMT_END
362
363 DEFINE_FFT_PROCESS_FUNC (32, float);
364 DEFINE_FFT_PROCESS_FUNC (64, double);
365
366 DEFINE_FFT_PROCESS_FUNC_FIXED_CHANNELS (32, 1, float);
367 DEFINE_FFT_PROCESS_FUNC_FIXED_CHANNELS (64, 1, double);
368
369 DEFINE_FFT_PROCESS_FUNC_FIXED_CHANNELS (32, 2, float);
370 DEFINE_FFT_PROCESS_FUNC_FIXED_CHANNELS (64, 2, double);
371
372 #undef FFT_CONVOLUTION_BODY
373 #undef DEFINE_FFT_PROCESS_FUNC
374 #undef DEFINE_FFT_PROCESS_FUNC_FIXED_CHANNELS
375
376 /* Element class */
377 static void
378     gst_audio_fx_base_fir_filter_calculate_frequency_response
379     (GstAudioFXBaseFIRFilter * self)
380 {
381   gst_fft_f64_free (self->fft);
382   self->fft = NULL;
383   gst_fft_f64_free (self->ifft);
384   self->ifft = NULL;
385   g_free (self->frequency_response);
386   self->frequency_response_length = 0;
387   g_free (self->fft_buffer);
388   self->fft_buffer = NULL;
389
390   if (self->kernel && self->kernel_length >= FFT_THRESHOLD
391       && !self->low_latency) {
392     guint block_length, i;
393     gdouble *kernel_tmp, *kernel = self->kernel;
394
395     /* We process 4 * kernel_length samples per pass in FFT mode */
396     block_length = 4 * self->kernel_length;
397     block_length = gst_fft_next_fast_length (block_length);
398     self->block_length = block_length;
399
400     kernel_tmp = g_new0 (gdouble, block_length);
401     memcpy (kernel_tmp, kernel, self->kernel_length * sizeof (gdouble));
402
403     self->fft = gst_fft_f64_new (block_length, FALSE);
404     self->ifft = gst_fft_f64_new (block_length, TRUE);
405     self->frequency_response_length = block_length / 2 + 1;
406     self->frequency_response =
407         g_new (GstFFTF64Complex, self->frequency_response_length);
408     gst_fft_f64_fft (self->fft, kernel_tmp, self->frequency_response);
409     g_free (kernel_tmp);
410
411     /* Normalize to make sure IFFT(FFT(x)) == x */
412     for (i = 0; i < self->frequency_response_length; i++) {
413       self->frequency_response[i].r /= block_length;
414       self->frequency_response[i].i /= block_length;
415     }
416   }
417 }
418
419 /* Must be called with base transform lock! */
420 static void
421 gst_audio_fx_base_fir_filter_select_process_function (GstAudioFXBaseFIRFilter *
422     self, gint width, gint channels)
423 {
424   if (width == 32 && self->fft && !self->low_latency) {
425     if (channels == 1)
426       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_1_32;
427     else if (channels == 2)
428       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_2_32;
429     else
430       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_32;
431   } else if (width == 64 && self->fft && !self->low_latency) {
432     if (channels == 1)
433       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_1_64;
434     else if (channels == 2)
435       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_2_64;
436     else
437       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_64;
438   } else if (width == 32) {
439     if (channels == 1)
440       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_1_32;
441     else if (channels == 2)
442       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_2_32;
443     else
444       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_32;
445   } else if (width == 64) {
446     if (channels == 1)
447       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_1_64;
448     else if (channels == 2)
449       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_2_64;
450     else
451       self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_64;
452   } else {
453     self->process = NULL;
454   }
455 }
456
457 static void
458 gst_audio_fx_base_fir_filter_dispose (GObject * object)
459 {
460   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (object);
461
462   g_free (self->buffer);
463   self->buffer = NULL;
464   self->buffer_length = 0;
465
466   g_free (self->kernel);
467   self->kernel = NULL;
468
469   gst_fft_f64_free (self->fft);
470   self->fft = NULL;
471   gst_fft_f64_free (self->ifft);
472   self->ifft = NULL;
473
474   g_free (self->frequency_response);
475   self->frequency_response = NULL;
476
477   g_free (self->fft_buffer);
478   self->fft_buffer = NULL;
479
480   G_OBJECT_CLASS (parent_class)->dispose (object);
481 }
482
483 static void
484 gst_audio_fx_base_fir_filter_set_property (GObject * object, guint prop_id,
485     const GValue * value, GParamSpec * pspec)
486 {
487   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (object);
488
489   switch (prop_id) {
490     case PROP_LOW_LATENCY:{
491       gboolean low_latency;
492
493       if (GST_STATE (self) >= GST_STATE_PAUSED) {
494         g_warning ("Changing the \"low-latency\" property "
495             "is only allowed in states < PAUSED");
496         return;
497       }
498
499       GST_BASE_TRANSFORM_LOCK (self);
500       low_latency = g_value_get_boolean (value);
501
502       if (self->low_latency != low_latency) {
503         self->low_latency = low_latency;
504         gst_audio_fx_base_fir_filter_calculate_frequency_response (self);
505         gst_audio_fx_base_fir_filter_select_process_function (self,
506             GST_AUDIO_FILTER_CAST (self)->format.width,
507             GST_AUDIO_FILTER_CAST (self)->format.channels);
508       }
509       GST_BASE_TRANSFORM_UNLOCK (self);
510       break;
511     }
512     case PROP_DRAIN_ON_CHANGES:{
513       GST_BASE_TRANSFORM_LOCK (self);
514       self->drain_on_changes = g_value_get_boolean (value);
515       GST_BASE_TRANSFORM_UNLOCK (self);
516       break;
517     }
518     default:
519       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
520       break;
521   }
522 }
523
524 static void
525 gst_audio_fx_base_fir_filter_get_property (GObject * object, guint prop_id,
526     GValue * value, GParamSpec * pspec)
527 {
528   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (object);
529
530   switch (prop_id) {
531     case PROP_LOW_LATENCY:
532       g_value_set_boolean (value, self->low_latency);
533       break;
534     case PROP_DRAIN_ON_CHANGES:
535       g_value_set_boolean (value, self->drain_on_changes);
536       break;
537     default:
538       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
539       break;
540   }
541 }
542
543 static void
544 gst_audio_fx_base_fir_filter_base_init (gpointer g_class)
545 {
546   GstCaps *caps;
547
548   caps = gst_caps_from_string (ALLOWED_CAPS);
549   gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (g_class),
550       caps);
551   gst_caps_unref (caps);
552 }
553
554 static void
555 gst_audio_fx_base_fir_filter_class_init (GstAudioFXBaseFIRFilterClass * klass)
556 {
557   GObjectClass *gobject_class = (GObjectClass *) klass;
558   GstBaseTransformClass *trans_class = (GstBaseTransformClass *) klass;
559   GstAudioFilterClass *filter_class = (GstAudioFilterClass *) klass;
560
561   gobject_class->dispose = gst_audio_fx_base_fir_filter_dispose;
562   gobject_class->set_property = gst_audio_fx_base_fir_filter_set_property;
563   gobject_class->get_property = gst_audio_fx_base_fir_filter_get_property;
564
565   /**
566    * GstAudioFXBaseFIRFilter::low-latency:
567    *
568    * Work in low-latency mode. This mode is much slower for large filter sizes
569    * but the latency is always only the pre-latency of the filter.
570    *
571    * Since: 0.10.18
572    */
573   g_object_class_install_property (gobject_class, PROP_LOW_LATENCY,
574       g_param_spec_boolean ("low-latency", "Low latency",
575           "Operate in low latency mode. This mode is slower but the "
576           "latency will only be the filter pre-latency. "
577           "Can only be changed in states < PAUSED!", DEFAULT_LOW_LATENCY,
578           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
579
580   /**
581    * GstAudioFXBaseFIRFilter::drain-on-changes:
582    *
583    * Whether the filter should be drained when its coeficients change
584    *
585    * Note: Currently this only works if the kernel size is not changed!
586    * Support for drainless kernel size changes will be added in the future.
587    *
588    * Since: 0.10.18
589    */
590   g_object_class_install_property (gobject_class, PROP_DRAIN_ON_CHANGES,
591       g_param_spec_boolean ("drain-on-changes", "Drain on changes",
592           "Drains the filter when its coeficients change",
593           DEFAULT_DRAIN_ON_CHANGES,
594           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
595
596   trans_class->transform =
597       GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_transform);
598   trans_class->start = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_start);
599   trans_class->stop = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_stop);
600   trans_class->event = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_event);
601   trans_class->transform_size =
602       GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_transform_size);
603   filter_class->setup = GST_DEBUG_FUNCPTR (gst_audio_fx_base_fir_filter_setup);
604 }
605
606 static void
607 gst_audio_fx_base_fir_filter_init (GstAudioFXBaseFIRFilter * self,
608     GstAudioFXBaseFIRFilterClass * g_class)
609 {
610   self->kernel = NULL;
611   self->buffer = NULL;
612   self->buffer_length = 0;
613
614   self->start_ts = GST_CLOCK_TIME_NONE;
615   self->start_off = GST_BUFFER_OFFSET_NONE;
616   self->nsamples_out = 0;
617   self->nsamples_in = 0;
618
619   self->low_latency = DEFAULT_LOW_LATENCY;
620   self->drain_on_changes = DEFAULT_DRAIN_ON_CHANGES;
621
622   gst_pad_set_query_function (GST_BASE_TRANSFORM (self)->srcpad,
623       gst_audio_fx_base_fir_filter_query);
624   gst_pad_set_query_type_function (GST_BASE_TRANSFORM (self)->srcpad,
625       gst_audio_fx_base_fir_filter_query_type);
626 }
627
628 void
629 gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter * self)
630 {
631   GstBuffer *outbuf;
632   GstFlowReturn res;
633   gint rate = GST_AUDIO_FILTER_CAST (self)->format.rate;
634   gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels;
635   gint width = GST_AUDIO_FILTER_CAST (self)->format.width / 8;
636   gint outsize, outsamples;
637   guint8 *in, *out;
638
639   if (channels == 0 || rate == 0 || self->nsamples_in == 0) {
640     self->buffer_fill = 0;
641     g_free (self->buffer);
642     self->buffer = NULL;
643     return;
644   }
645
646   /* Calculate the number of samples and their memory size that
647    * should be pushed from the residue */
648   outsamples = self->nsamples_in - (self->nsamples_out - self->latency);
649   if (outsamples <= 0) {
650     self->buffer_fill = 0;
651     g_free (self->buffer);
652     self->buffer = NULL;
653     return;
654   }
655   outsize = outsamples * channels * width;
656
657   if (!self->fft || self->low_latency) {
658     gint64 diffsize, diffsamples;
659
660     /* Process the difference between latency and residue length samples
661      * to start at the actual data instead of starting at the zeros before
662      * when we only got one buffer smaller than latency */
663     diffsamples =
664         ((gint64) self->latency) - ((gint64) self->buffer_fill) / channels;
665     if (diffsamples > 0) {
666       diffsize = diffsamples * channels * width;
667       in = g_new0 (guint8, diffsize);
668       out = g_new0 (guint8, diffsize);
669       self->nsamples_out += self->process (self, in, out, diffsamples);
670       g_free (in);
671       g_free (out);
672     }
673
674     res = gst_pad_alloc_buffer (GST_BASE_TRANSFORM_CAST (self)->srcpad,
675         GST_BUFFER_OFFSET_NONE, outsize,
676         GST_PAD_CAPS (GST_BASE_TRANSFORM_CAST (self)->srcpad), &outbuf);
677
678     if (G_UNLIKELY (res != GST_FLOW_OK)) {
679       GST_WARNING_OBJECT (self, "failed allocating buffer of %d bytes",
680           outsize);
681       self->buffer_fill = 0;
682       return;
683     }
684
685     /* Convolve the residue with zeros to get the actual remaining data */
686     in = g_new0 (guint8, outsize);
687     self->nsamples_out +=
688         self->process (self, in, GST_BUFFER_DATA (outbuf), outsamples);
689     g_free (in);
690   } else {
691     guint gensamples = 0;
692     guint8 *data;
693
694     outbuf = gst_buffer_new_and_alloc (outsize);
695     data = GST_BUFFER_DATA (outbuf);
696
697     while (gensamples < outsamples) {
698       guint step_insamples = self->block_length - self->buffer_fill;
699       guint8 *zeroes = g_new0 (guint8, step_insamples * channels * width);
700       guint8 *out = g_new (guint8, self->block_length * channels * width);
701       guint step_gensamples;
702
703       step_gensamples = self->process (self, zeroes, out, step_insamples);
704       g_free (zeroes);
705
706       memcpy (data + gensamples * width, out, MIN (step_gensamples,
707               outsamples - gensamples) * width);
708       gensamples += MIN (step_gensamples, outsamples - gensamples);
709
710       g_free (out);
711     }
712     self->nsamples_out += gensamples;
713   }
714
715   /* Set timestamp, offset, etc from the values we
716    * saved when processing the regular buffers */
717   if (GST_CLOCK_TIME_IS_VALID (self->start_ts))
718     GST_BUFFER_TIMESTAMP (outbuf) = self->start_ts;
719   else
720     GST_BUFFER_TIMESTAMP (outbuf) = 0;
721   GST_BUFFER_TIMESTAMP (outbuf) +=
722       gst_util_uint64_scale_int (self->nsamples_out - outsamples -
723       self->latency, GST_SECOND, rate);
724
725   GST_BUFFER_DURATION (outbuf) =
726       gst_util_uint64_scale_int (outsamples, GST_SECOND, rate);
727
728   if (self->start_off != GST_BUFFER_OFFSET_NONE) {
729     GST_BUFFER_OFFSET (outbuf) =
730         self->start_off + self->nsamples_out - outsamples - self->latency;
731     GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + outsamples;
732   }
733
734   GST_DEBUG_OBJECT (self, "Pushing residue buffer of size %d with timestamp: %"
735       GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %"
736       G_GUINT64_FORMAT ", offset_end: %" G_GUINT64_FORMAT ", nsamples_out: %d",
737       GST_BUFFER_SIZE (outbuf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
738       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf),
739       GST_BUFFER_OFFSET_END (outbuf), outsamples);
740
741   res = gst_pad_push (GST_BASE_TRANSFORM_CAST (self)->srcpad, outbuf);
742
743   if (G_UNLIKELY (res != GST_FLOW_OK)) {
744     GST_WARNING_OBJECT (self, "failed to push residue");
745   }
746
747   self->buffer_fill = 0;
748 }
749
750 /* GstAudioFilter vmethod implementations */
751
752 /* get notified of caps and plug in the correct process function */
753 static gboolean
754 gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
755     GstRingBufferSpec * format)
756 {
757   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
758
759   if (self->buffer) {
760     gst_audio_fx_base_fir_filter_push_residue (self);
761     g_free (self->buffer);
762     self->buffer = NULL;
763     self->buffer_fill = 0;
764     self->buffer_length = 0;
765     self->start_ts = GST_CLOCK_TIME_NONE;
766     self->start_off = GST_BUFFER_OFFSET_NONE;
767     self->nsamples_out = 0;
768     self->nsamples_in = 0;
769   }
770
771   gst_audio_fx_base_fir_filter_select_process_function (self, format->width,
772       format->channels);
773
774   return (self->process != NULL);
775 }
776
777 /* GstBaseTransform vmethod implementations */
778
779 static gboolean
780 gst_audio_fx_base_fir_filter_transform_size (GstBaseTransform * base,
781     GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
782     guint * othersize)
783 {
784   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
785   guint blocklen;
786   GstStructure *s;
787   gint width, channels;
788
789   if (!self->fft || self->low_latency || direction == GST_PAD_SRC) {
790     *othersize = size;
791     return TRUE;
792   }
793
794   s = gst_caps_get_structure (caps, 0);
795   if (!gst_structure_get_int (s, "width", &width) ||
796       !gst_structure_get_int (s, "channels", &channels))
797     return FALSE;
798
799   width /= 8;
800
801   size /= width * channels;
802
803   blocklen = self->block_length - self->kernel_length + 1;
804   *othersize = ((size + blocklen - 1) / blocklen) * blocklen;
805
806   *othersize *= width * channels;
807
808   return TRUE;
809 }
810
811 static GstFlowReturn
812 gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base,
813     GstBuffer * inbuf, GstBuffer * outbuf)
814 {
815   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
816   GstClockTime timestamp, expected_timestamp;
817   gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels;
818   gint rate = GST_AUDIO_FILTER_CAST (self)->format.rate;
819   gint width = GST_AUDIO_FILTER_CAST (self)->format.width / 8;
820   guint input_samples = (GST_BUFFER_SIZE (inbuf) / width) / channels;
821   guint output_samples = (GST_BUFFER_SIZE (outbuf) / width) / channels;
822   guint generated_samples;
823   guint64 output_offset;
824   gint64 diff = 0;
825   GstClockTime stream_time;
826
827   timestamp = GST_BUFFER_TIMESTAMP (outbuf);
828
829   if (!GST_CLOCK_TIME_IS_VALID (timestamp)
830       && !GST_CLOCK_TIME_IS_VALID (self->start_ts)) {
831     GST_ERROR_OBJECT (self, "Invalid timestamp");
832     return GST_FLOW_ERROR;
833   }
834
835   stream_time =
836       gst_segment_to_stream_time (&base->segment, GST_FORMAT_TIME, timestamp);
837
838   GST_DEBUG_OBJECT (self, "sync to %" GST_TIME_FORMAT,
839       GST_TIME_ARGS (timestamp));
840
841   if (GST_CLOCK_TIME_IS_VALID (stream_time))
842     gst_object_sync_values (G_OBJECT (self), stream_time);
843
844   g_return_val_if_fail (self->kernel != NULL, GST_FLOW_ERROR);
845   g_return_val_if_fail (channels != 0, GST_FLOW_ERROR);
846
847   if (GST_CLOCK_TIME_IS_VALID (self->start_ts))
848     expected_timestamp =
849         self->start_ts + gst_util_uint64_scale_int (self->nsamples_in,
850         GST_SECOND, rate);
851   else
852     expected_timestamp = GST_CLOCK_TIME_NONE;
853
854   /* Reset the residue if already existing on discont buffers */
855   if (GST_BUFFER_IS_DISCONT (inbuf)
856       || (GST_CLOCK_TIME_IS_VALID (expected_timestamp)
857           && (ABS (GST_CLOCK_DIFF (timestamp,
858                       expected_timestamp) > 5 * GST_MSECOND)))) {
859     GST_DEBUG_OBJECT (self, "Discontinuity detected - flushing");
860     if (GST_CLOCK_TIME_IS_VALID (expected_timestamp))
861       gst_audio_fx_base_fir_filter_push_residue (self);
862     self->buffer_fill = 0;
863     g_free (self->buffer);
864     self->buffer = NULL;
865     self->start_ts = timestamp;
866     self->start_off = GST_BUFFER_OFFSET (inbuf);
867     self->nsamples_out = 0;
868     self->nsamples_in = 0;
869   } else if (!GST_CLOCK_TIME_IS_VALID (self->start_ts)) {
870     self->start_ts = timestamp;
871     self->start_off = GST_BUFFER_OFFSET (inbuf);
872   }
873
874   self->nsamples_in += input_samples;
875
876   generated_samples =
877       self->process (self, GST_BUFFER_DATA (inbuf), GST_BUFFER_DATA (outbuf),
878       input_samples);
879
880   g_assert (generated_samples <= output_samples);
881   self->nsamples_out += generated_samples;
882   if (generated_samples == 0)
883     return GST_BASE_TRANSFORM_FLOW_DROPPED;
884
885   /* Calculate the number of samples we can push out now without outputting
886    * latency zeros in the beginning */
887   diff = ((gint64) self->nsamples_out) - ((gint64) self->latency);
888   if (diff < 0) {
889     return GST_BASE_TRANSFORM_FLOW_DROPPED;
890   } else if (diff < generated_samples) {
891     gint64 tmp = diff;
892     diff = generated_samples - diff;
893     generated_samples = tmp;
894     GST_BUFFER_DATA (outbuf) += diff * width * channels;
895   }
896   GST_BUFFER_SIZE (outbuf) = generated_samples * width * channels;
897
898   output_offset = self->nsamples_out - self->latency - generated_samples;
899   GST_BUFFER_TIMESTAMP (outbuf) =
900       self->start_ts + gst_util_uint64_scale_int (output_offset, GST_SECOND,
901       rate);
902   GST_BUFFER_DURATION (outbuf) =
903       gst_util_uint64_scale_int (output_samples, GST_SECOND, rate);
904   if (self->start_off != GST_BUFFER_OFFSET_NONE) {
905     GST_BUFFER_OFFSET (outbuf) = self->start_off + output_offset;
906     GST_BUFFER_OFFSET_END (outbuf) =
907         GST_BUFFER_OFFSET (outbuf) + generated_samples;
908   } else {
909     GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
910     GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
911   }
912
913   GST_DEBUG_OBJECT (self, "Pushing buffer of size %d with timestamp: %"
914       GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %"
915       G_GUINT64_FORMAT ", offset_end: %" G_GUINT64_FORMAT ", nsamples_out: %d",
916       GST_BUFFER_SIZE (outbuf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
917       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf),
918       GST_BUFFER_OFFSET_END (outbuf), generated_samples);
919
920   return GST_FLOW_OK;
921 }
922
923 static gboolean
924 gst_audio_fx_base_fir_filter_start (GstBaseTransform * base)
925 {
926   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
927
928   self->buffer_fill = 0;
929   g_free (self->buffer);
930   self->buffer = NULL;
931   self->start_ts = GST_CLOCK_TIME_NONE;
932   self->start_off = GST_BUFFER_OFFSET_NONE;
933   self->nsamples_out = 0;
934   self->nsamples_in = 0;
935
936   return TRUE;
937 }
938
939 static gboolean
940 gst_audio_fx_base_fir_filter_stop (GstBaseTransform * base)
941 {
942   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
943
944   g_free (self->buffer);
945   self->buffer = NULL;
946   self->buffer_length = 0;
947
948   return TRUE;
949 }
950
951 static gboolean
952 gst_audio_fx_base_fir_filter_query (GstPad * pad, GstQuery * query)
953 {
954   GstAudioFXBaseFIRFilter *self =
955       GST_AUDIO_FX_BASE_FIR_FILTER (gst_pad_get_parent (pad));
956   gboolean res = TRUE;
957
958   switch (GST_QUERY_TYPE (query)) {
959     case GST_QUERY_LATENCY:
960     {
961       GstClockTime min, max;
962       gboolean live;
963       guint64 latency;
964       GstPad *peer;
965       gint rate = GST_AUDIO_FILTER (self)->format.rate;
966
967       if (rate == 0) {
968         res = FALSE;
969       } else if ((peer = gst_pad_get_peer (GST_BASE_TRANSFORM (self)->sinkpad))) {
970         if ((res = gst_pad_query (peer, query))) {
971           gst_query_parse_latency (query, &live, &min, &max);
972
973           GST_DEBUG_OBJECT (self, "Peer latency: min %"
974               GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
975               GST_TIME_ARGS (min), GST_TIME_ARGS (max));
976
977           if (self->fft && !self->low_latency)
978             latency = self->block_length - self->kernel_length + 1;
979           else
980             latency = self->latency;
981
982           /* add our own latency */
983           latency = gst_util_uint64_scale_round (latency, GST_SECOND, rate);
984
985           GST_DEBUG_OBJECT (self, "Our latency: %"
986               GST_TIME_FORMAT, GST_TIME_ARGS (latency));
987
988           min += latency;
989           if (max != GST_CLOCK_TIME_NONE)
990             max += latency;
991
992           GST_DEBUG_OBJECT (self, "Calculated total latency : min %"
993               GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
994               GST_TIME_ARGS (min), GST_TIME_ARGS (max));
995
996           gst_query_set_latency (query, live, min, max);
997         }
998         gst_object_unref (peer);
999       }
1000       break;
1001     }
1002     default:
1003       res = gst_pad_query_default (pad, query);
1004       break;
1005   }
1006   gst_object_unref (self);
1007   return res;
1008 }
1009
1010 static const GstQueryType *
1011 gst_audio_fx_base_fir_filter_query_type (GstPad * pad)
1012 {
1013   static const GstQueryType types[] = {
1014     GST_QUERY_LATENCY,
1015     0
1016   };
1017
1018   return types;
1019 }
1020
1021 static gboolean
1022 gst_audio_fx_base_fir_filter_event (GstBaseTransform * base, GstEvent * event)
1023 {
1024   GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
1025
1026   switch (GST_EVENT_TYPE (event)) {
1027     case GST_EVENT_EOS:
1028       gst_audio_fx_base_fir_filter_push_residue (self);
1029       self->start_ts = GST_CLOCK_TIME_NONE;
1030       self->start_off = GST_BUFFER_OFFSET_NONE;
1031       self->nsamples_out = 0;
1032       self->nsamples_in = 0;
1033       break;
1034     default:
1035       break;
1036   }
1037
1038   return GST_BASE_TRANSFORM_CLASS (parent_class)->event (base, event);
1039 }
1040
1041 void
1042 gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self,
1043     gdouble * kernel, guint kernel_length, guint64 latency)
1044 {
1045   gboolean latency_changed;
1046
1047   g_return_if_fail (kernel != NULL);
1048   g_return_if_fail (self != NULL);
1049
1050   GST_BASE_TRANSFORM_LOCK (self);
1051
1052   latency_changed = (self->latency != latency
1053       || (!self->low_latency && self->kernel_length < FFT_THRESHOLD
1054           && kernel_length >= FFT_THRESHOLD)
1055       || (!self->low_latency && self->kernel_length >= FFT_THRESHOLD
1056           && kernel_length < FFT_THRESHOLD));
1057
1058   /* FIXME: If the latency changes, the buffer size changes too and we
1059    * have to drain in any case until this is fixed in the future */
1060   if (self->buffer && (!self->drain_on_changes || latency_changed)) {
1061     gst_audio_fx_base_fir_filter_push_residue (self);
1062     self->start_ts = GST_CLOCK_TIME_NONE;
1063     self->start_off = GST_BUFFER_OFFSET_NONE;
1064     self->nsamples_out = 0;
1065     self->nsamples_in = 0;
1066     self->buffer_fill = 0;
1067   }
1068
1069   g_free (self->kernel);
1070   if (!self->drain_on_changes || latency_changed) {
1071     g_free (self->buffer);
1072     self->buffer = NULL;
1073     self->buffer_fill = 0;
1074     self->buffer_length = 0;
1075   }
1076
1077   self->kernel = kernel;
1078   self->kernel_length = kernel_length;
1079
1080   gst_audio_fx_base_fir_filter_calculate_frequency_response (self);
1081   gst_audio_fx_base_fir_filter_select_process_function (self,
1082       GST_AUDIO_FILTER_CAST (self)->format.width,
1083       GST_AUDIO_FILTER_CAST (self)->format.channels);
1084
1085   if (latency_changed) {
1086     self->latency = latency;
1087     gst_element_post_message (GST_ELEMENT (self),
1088         gst_message_new_latency (GST_OBJECT (self)));
1089   }
1090
1091   GST_BASE_TRANSFORM_UNLOCK (self);
1092 }