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