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