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