2 * Copyright (C) <2004> Benjamin Otte <otte@gnome.org>
3 * <2007> Stefan Kost <ensonic@users.sf.net>
4 * <2007> Sebastian Dröge <slomo@circular-chaos.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
29 #include "gstiirequalizer.h"
30 #include "gstiirequalizernbands.h"
31 #include "gstiirequalizer3bands.h"
32 #include "gstiirequalizer10bands.h"
34 #include "gst/glib-compat-private.h"
36 GST_DEBUG_CATEGORY (equalizer_debug);
37 #define GST_CAT_DEFAULT equalizer_debug
39 #define BANDS_LOCK(equ) g_mutex_lock(equ->bands_lock)
40 #define BANDS_UNLOCK(equ) g_mutex_unlock(equ->bands_lock)
42 static void gst_iir_equalizer_child_proxy_interface_init (gpointer g_iface,
45 static void gst_iir_equalizer_finalize (GObject * object);
47 static gboolean gst_iir_equalizer_setup (GstAudioFilter * filter,
48 GstRingBufferSpec * fmt);
49 static GstFlowReturn gst_iir_equalizer_transform_ip (GstBaseTransform * btrans,
52 #define ALLOWED_CAPS \
56 " endianness=(int)BYTE_ORDER," \
57 " signed=(bool)TRUE," \
58 " rate=(int)[1000,MAX]," \
59 " channels=(int)[1,MAX]; " \
60 "audio/x-raw-float," \
61 " width=(int) { 32, 64 } ," \
62 " endianness=(int)BYTE_ORDER," \
63 " rate=(int)[1000,MAX]," \
64 " channels=(int)[1,MAX]"
67 _do_init (GType object_type)
69 const GInterfaceInfo child_proxy_interface_info = {
70 (GInterfaceInitFunc) gst_iir_equalizer_child_proxy_interface_init,
71 NULL, /* interface_finalize */
72 NULL /* interface_data */
75 g_type_add_interface_static (object_type, GST_TYPE_CHILD_PROXY,
76 &child_proxy_interface_info);
79 GST_BOILERPLATE_FULL (GstIirEqualizer, gst_iir_equalizer,
80 GstAudioFilter, GST_TYPE_AUDIO_FILTER, _do_init);
97 } GstIirEqualizerBandType;
99 #define GST_TYPE_IIR_EQUALIZER_BAND_TYPE (gst_iir_equalizer_band_type_get_type ())
101 gst_iir_equalizer_band_type_get_type (void)
103 static GType gtype = 0;
106 static const GEnumValue values[] = {
107 {BAND_TYPE_PEAK, "Peak filter (default for inner bands)", "peak"},
108 {BAND_TYPE_LOW_SHELF, "Low shelf filter (default for first band)",
110 {BAND_TYPE_HIGH_SHELF, "High shelf filter (default for last band)",
115 gtype = g_enum_register_static ("GstIirEqualizerBandType", values);
121 typedef struct _GstIirEqualizerBandClass GstIirEqualizerBandClass;
123 #define GST_TYPE_IIR_EQUALIZER_BAND \
124 (gst_iir_equalizer_band_get_type())
125 #define GST_IIR_EQUALIZER_BAND(obj) \
126 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_IIR_EQUALIZER_BAND,GstIirEqualizerBand))
127 #define GST_IIR_EQUALIZER_BAND_CLASS(klass) \
128 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_IIR_EQUALIZER_BAND,GstIirEqualizerBandClass))
129 #define GST_IS_IIR_EQUALIZER_BAND(obj) \
130 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_IIR_EQUALIZER_BAND))
131 #define GST_IS_IIR_EQUALIZER_BAND_CLASS(klass) \
132 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_IIR_EQUALIZER_BAND))
134 struct _GstIirEqualizerBand
139 /* center frequency and gain */
143 GstIirEqualizerBandType type;
145 /* second order iir filter */
146 gdouble b1, b2; /* IIR coefficients for outputs */
147 gdouble a0, a1, a2; /* IIR coefficients for inputs */
150 struct _GstIirEqualizerBandClass
152 GstObjectClass parent_class;
155 static GType gst_iir_equalizer_band_get_type (void);
158 gst_iir_equalizer_band_set_property (GObject * object, guint prop_id,
159 const GValue * value, GParamSpec * pspec)
161 GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object);
162 GstIirEqualizer *equ =
163 GST_IIR_EQUALIZER (gst_object_get_parent (GST_OBJECT (band)));
169 gain = g_value_get_double (value);
170 GST_DEBUG_OBJECT (band, "gain = %lf -> %lf", band->gain, gain);
171 if (gain != band->gain) {
173 equ->need_new_coefficients = TRUE;
176 GST_DEBUG_OBJECT (band, "changed gain = %lf ", band->gain);
183 freq = g_value_get_double (value);
184 GST_DEBUG_OBJECT (band, "freq = %lf -> %lf", band->freq, freq);
185 if (freq != band->freq) {
187 equ->need_new_coefficients = TRUE;
190 GST_DEBUG_OBJECT (band, "changed freq = %lf ", band->freq);
194 case PROP_BANDWIDTH:{
197 width = g_value_get_double (value);
198 GST_DEBUG_OBJECT (band, "width = %lf -> %lf", band->width, width);
199 if (width != band->width) {
201 equ->need_new_coefficients = TRUE;
204 GST_DEBUG_OBJECT (band, "changed width = %lf ", band->width);
209 GstIirEqualizerBandType type;
211 type = g_value_get_enum (value);
212 GST_DEBUG_OBJECT (band, "type = %d -> %d", band->type, type);
213 if (type != band->type) {
215 equ->need_new_coefficients = TRUE;
218 GST_DEBUG_OBJECT (band, "changed type = %d ", band->type);
223 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
227 gst_object_unref (equ);
231 gst_iir_equalizer_band_get_property (GObject * object, guint prop_id,
232 GValue * value, GParamSpec * pspec)
234 GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object);
238 g_value_set_double (value, band->gain);
241 g_value_set_double (value, band->freq);
244 g_value_set_double (value, band->width);
247 g_value_set_enum (value, band->type);
250 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
256 gst_iir_equalizer_band_class_init (GstIirEqualizerBandClass * klass)
258 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
260 gobject_class->set_property = gst_iir_equalizer_band_set_property;
261 gobject_class->get_property = gst_iir_equalizer_band_get_property;
263 g_object_class_install_property (gobject_class, PROP_GAIN,
264 g_param_spec_double ("gain", "gain",
265 "gain for the frequency band ranging from -24.0 dB to +12.0 dB",
267 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
269 g_object_class_install_property (gobject_class, PROP_FREQ,
270 g_param_spec_double ("freq", "freq",
271 "center frequency of the band",
273 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
275 g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
276 g_param_spec_double ("bandwidth", "bandwidth",
277 "difference between bandedges in Hz",
279 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
281 g_object_class_install_property (gobject_class, PROP_TYPE,
282 g_param_spec_enum ("type", "Type",
283 "Filter type", GST_TYPE_IIR_EQUALIZER_BAND_TYPE,
285 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
289 gst_iir_equalizer_band_init (GstIirEqualizerBand * band,
290 GstIirEqualizerBandClass * klass)
295 band->type = BAND_TYPE_PEAK;
299 gst_iir_equalizer_band_get_type (void)
301 static GType type = 0;
303 if (G_UNLIKELY (!type)) {
304 const GTypeInfo type_info = {
305 sizeof (GstIirEqualizerBandClass),
308 (GClassInitFunc) gst_iir_equalizer_band_class_init,
311 sizeof (GstIirEqualizerBand),
313 (GInstanceInitFunc) gst_iir_equalizer_band_init,
316 g_type_register_static (GST_TYPE_OBJECT, "GstIirEqualizerBand",
323 /* child proxy iface */
325 gst_iir_equalizer_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
328 GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);
332 if (G_UNLIKELY (index >= equ->freq_band_count)) {
334 g_return_val_if_fail (index < equ->freq_band_count, NULL);
337 ret = gst_object_ref (equ->bands[index]);
340 GST_LOG_OBJECT (equ, "return child[%d] %" GST_PTR_FORMAT, index, ret);
345 gst_iir_equalizer_child_proxy_get_children_count (GstChildProxy * child_proxy)
347 GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);
349 GST_LOG ("we have %d children", equ->freq_band_count);
350 return equ->freq_band_count;
354 gst_iir_equalizer_child_proxy_interface_init (gpointer g_iface,
357 GstChildProxyInterface *iface = g_iface;
359 GST_DEBUG ("initializing iface");
361 iface->get_child_by_index = gst_iir_equalizer_child_proxy_get_child_by_index;
362 iface->get_children_count = gst_iir_equalizer_child_proxy_get_children_count;
366 /* equalizer implementation */
369 gst_iir_equalizer_base_init (gpointer g_class)
371 GstAudioFilterClass *audiofilter_class = GST_AUDIO_FILTER_CLASS (g_class);
374 caps = gst_caps_from_string (ALLOWED_CAPS);
375 gst_audio_filter_class_add_pad_templates (audiofilter_class, caps);
376 gst_caps_unref (caps);
380 gst_iir_equalizer_class_init (GstIirEqualizerClass * klass)
382 GstAudioFilterClass *audio_filter_class = (GstAudioFilterClass *) klass;
383 GstBaseTransformClass *btrans_class = (GstBaseTransformClass *) klass;
384 GObjectClass *gobject_class = (GObjectClass *) klass;
386 gobject_class->finalize = gst_iir_equalizer_finalize;
387 audio_filter_class->setup = gst_iir_equalizer_setup;
388 btrans_class->transform_ip = gst_iir_equalizer_transform_ip;
392 gst_iir_equalizer_init (GstIirEqualizer * eq, GstIirEqualizerClass * g_class)
394 eq->bands_lock = g_mutex_new ();
395 eq->need_new_coefficients = TRUE;
399 gst_iir_equalizer_finalize (GObject * object)
401 GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);
404 for (i = 0; i < equ->freq_band_count; i++) {
406 gst_object_unparent (GST_OBJECT (equ->bands[i]));
407 equ->bands[i] = NULL;
409 equ->freq_band_count = 0;
412 g_free (equ->history);
414 g_mutex_free (equ->bands_lock);
416 G_OBJECT_CLASS (parent_class)->finalize (object);
421 * The Equivalence of Various Methods of Computing
422 * Biquad Coefficients for Audio Parametric Equalizers
424 * by Robert Bristow-Johnson
426 * http://www.aes.org/e-lib/browse.cfm?elib=6326
427 * http://www.musicdsp.org/files/EQ-Coefficients.pdf
428 * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
430 * The bandwidth method that we use here is the preferred
431 * one from this article transformed from octaves to frequency
434 static inline gdouble
435 arg_to_scale (gdouble arg)
437 return (pow (10.0, arg / 40.0));
441 calculate_omega (gdouble freq, gint rate)
445 if (freq / rate >= 0.5)
447 else if (freq <= 0.0)
450 omega = 2.0 * G_PI * (freq / rate);
456 calculate_bw (GstIirEqualizerBand * band, gint rate)
460 if (band->width / rate >= 0.5) {
461 /* If bandwidth == 0.5 the calculation below fails as tan(G_PI/2)
462 * is undefined. So set the bandwidth to a slightly smaller value.
464 bw = G_PI - 0.00000001;
465 } else if (band->width <= 0.0) {
466 /* If bandwidth == 0 this band won't change anything so set
467 * the coefficients accordingly. The coefficient calculation
468 * below would create coefficients that for some reason amplify
477 bw = 2.0 * G_PI * (band->width / rate);
483 setup_peak_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
485 g_return_if_fail (GST_AUDIO_FILTER (equ)->format.rate);
488 gdouble gain, omega, bw;
489 gdouble alpha, alpha1, alpha2, b0;
491 gain = arg_to_scale (band->gain);
492 omega = calculate_omega (band->freq, GST_AUDIO_FILTER (equ)->format.rate);
493 bw = calculate_bw (band, GST_AUDIO_FILTER (equ)->format.rate);
497 alpha = tan (bw / 2.0);
499 alpha1 = alpha * gain;
500 alpha2 = alpha / gain;
504 band->a0 = (1.0 + alpha1) / b0;
505 band->a1 = (-2.0 * cos (omega)) / b0;
506 band->a2 = (1.0 - alpha1) / b0;
507 band->b1 = (2.0 * cos (omega)) / b0;
508 band->b2 = -(1.0 - alpha2) / b0;
512 ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g",
513 band->gain, band->width, band->freq, band->a0, band->a1, band->a2,
519 setup_low_shelf_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
521 g_return_if_fail (GST_AUDIO_FILTER (equ)->format.rate);
524 gdouble gain, omega, bw;
525 gdouble alpha, delta, b0;
528 gain = arg_to_scale (band->gain);
529 omega = calculate_omega (band->freq, GST_AUDIO_FILTER (equ)->format.rate);
530 bw = calculate_bw (band, GST_AUDIO_FILTER (equ)->format.rate);
536 alpha = tan (bw / 2.0);
538 delta = 2.0 * sqrt (gain) * alpha;
539 b0 = egp + egm * cos (omega) + delta;
541 band->a0 = ((egp - egm * cos (omega) + delta) * gain) / b0;
542 band->a1 = ((egm - egp * cos (omega)) * 2.0 * gain) / b0;
543 band->a2 = ((egp - egm * cos (omega) - delta) * gain) / b0;
544 band->b1 = ((egm + egp * cos (omega)) * 2.0) / b0;
545 band->b2 = -((egp + egm * cos (omega) - delta)) / b0;
550 ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g",
551 band->gain, band->width, band->freq, band->a0, band->a1, band->a2,
557 setup_high_shelf_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
559 g_return_if_fail (GST_AUDIO_FILTER (equ)->format.rate);
562 gdouble gain, omega, bw;
563 gdouble alpha, delta, b0;
566 gain = arg_to_scale (band->gain);
567 omega = calculate_omega (band->freq, GST_AUDIO_FILTER (equ)->format.rate);
568 bw = calculate_bw (band, GST_AUDIO_FILTER (equ)->format.rate);
574 alpha = tan (bw / 2.0);
576 delta = 2.0 * sqrt (gain) * alpha;
577 b0 = egp - egm * cos (omega) + delta;
579 band->a0 = ((egp + egm * cos (omega) + delta) * gain) / b0;
580 band->a1 = ((egm + egp * cos (omega)) * -2.0 * gain) / b0;
581 band->a2 = ((egp + egm * cos (omega) - delta) * gain) / b0;
582 band->b1 = ((egm - egp * cos (omega)) * -2.0) / b0;
583 band->b2 = -((egp - egm * cos (omega) - delta)) / b0;
588 ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g",
589 band->gain, band->width, band->freq, band->a0, band->a1, band->a2,
594 /* Must be called with bands_lock and transform lock! */
596 set_passthrough (GstIirEqualizer * equ)
599 gboolean passthrough = TRUE;
601 for (i = 0; i < equ->freq_band_count; i++) {
602 passthrough = passthrough && (equ->bands[i]->gain == 0.0);
605 gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (equ), passthrough);
606 GST_DEBUG ("Passthrough mode: %d\n", passthrough);
609 /* Must be called with bands_lock and transform lock! */
611 update_coefficients (GstIirEqualizer * equ)
613 gint i, n = equ->freq_band_count;
615 for (i = 0; i < n; i++) {
616 if (equ->bands[i]->type == BAND_TYPE_PEAK)
617 setup_peak_filter (equ, equ->bands[i]);
618 else if (equ->bands[i]->type == BAND_TYPE_LOW_SHELF)
619 setup_low_shelf_filter (equ, equ->bands[i]);
621 setup_high_shelf_filter (equ, equ->bands[i]);
624 equ->need_new_coefficients = FALSE;
627 /* Must be called with transform lock! */
629 alloc_history (GstIirEqualizer * equ)
631 /* free + alloc = no memcpy */
632 g_free (equ->history);
634 g_malloc0 (equ->history_size * GST_AUDIO_FILTER (equ)->format.channels *
635 equ->freq_band_count);
639 gst_iir_equalizer_compute_frequencies (GstIirEqualizer * equ, guint new_count)
642 gdouble freq0, freq1, step;
645 if (equ->freq_band_count == new_count)
650 if (G_UNLIKELY (equ->freq_band_count == new_count)) {
655 old_count = equ->freq_band_count;
656 equ->freq_band_count = new_count;
657 GST_DEBUG ("bands %u -> %u", old_count, new_count);
659 if (old_count < new_count) {
661 equ->bands = g_realloc (equ->bands, sizeof (GstObject *) * new_count);
662 for (i = old_count; i < new_count; i++) {
663 /* otherwise they get names like 'iirequalizerband5' */
664 sprintf (name, "band%u", i);
665 equ->bands[i] = g_object_new (GST_TYPE_IIR_EQUALIZER_BAND,
667 GST_DEBUG ("adding band[%d]=%p", i, equ->bands[i]);
669 gst_object_set_parent (GST_OBJECT (equ->bands[i]), GST_OBJECT (equ));
670 gst_child_proxy_child_added (GST_OBJECT (equ),
671 GST_OBJECT (equ->bands[i]));
674 /* free unused bands */
675 for (i = new_count; i < old_count; i++) {
676 GST_DEBUG ("removing band[%d]=%p", i, equ->bands[i]);
677 gst_child_proxy_child_removed (GST_OBJECT (equ),
678 GST_OBJECT (equ->bands[i]));
679 gst_object_unparent (GST_OBJECT (equ->bands[i]));
680 equ->bands[i] = NULL;
686 /* set center frequencies and name band objects
687 * FIXME: arg! we can't change the name of parented objects :(
688 * application should read band->freq to get the name
691 step = pow (HIGHEST_FREQ / LOWEST_FREQ, 1.0 / new_count);
693 for (i = 0; i < new_count; i++) {
694 freq1 = freq0 * step;
697 equ->bands[i]->type = BAND_TYPE_LOW_SHELF;
698 else if (i == new_count - 1)
699 equ->bands[i]->type = BAND_TYPE_HIGH_SHELF;
701 equ->bands[i]->type = BAND_TYPE_PEAK;
703 equ->bands[i]->freq = freq0 + ((freq1 - freq0) / 2.0);
704 equ->bands[i]->width = freq1 - freq0;
705 GST_DEBUG ("band[%2d] = '%lf'", i, equ->bands[i]->freq);
707 g_object_notify (G_OBJECT (equ->bands[i]), "bandwidth");
708 g_object_notify (G_OBJECT (equ->bands[i]), "freq");
709 g_object_notify (G_OBJECT (equ->bands[i]), "type");
712 if(equ->bands[i]->freq<10000.0)
713 sprintf (name,"%dHz",(gint)equ->bands[i]->freq);
715 sprintf (name,"%dkHz",(gint)(equ->bands[i]->freq/1000.0));
716 gst_object_set_name( GST_OBJECT (equ->bands[i]), name);
717 GST_DEBUG ("band[%2d] = '%s'",i,name);
722 equ->need_new_coefficients = TRUE;
726 /* start of code that is type specific */
728 #define CREATE_OPTIMIZED_FUNCTIONS_INT(TYPE,BIG_TYPE,MIN_VAL,MAX_VAL) \
730 BIG_TYPE x1, x2; /* history of input values for a filter */ \
731 BIG_TYPE y1, y2; /* history of output values for a filter */ \
732 } SecondOrderHistory ## TYPE; \
734 static inline BIG_TYPE \
735 one_step_ ## TYPE (GstIirEqualizerBand *filter, \
736 SecondOrderHistory ## TYPE *history, BIG_TYPE input) \
738 /* calculate output */ \
739 BIG_TYPE output = filter->a0 * input + \
740 filter->a1 * history->x1 + filter->a2 * history->x2 + \
741 filter->b1 * history->y1 + filter->b2 * history->y2; \
742 /* update history */ \
743 history->y2 = history->y1; \
744 history->y1 = output; \
745 history->x2 = history->x1; \
746 history->x1 = input; \
752 history_size_ ## TYPE = sizeof (SecondOrderHistory ## TYPE); \
755 gst_iir_equ_process_ ## TYPE (GstIirEqualizer *equ, guint8 *data, \
756 guint size, guint channels) \
758 guint frames = size / channels / sizeof (TYPE); \
759 guint i, c, f, nf = equ->freq_band_count; \
761 GstIirEqualizerBand **filters = equ->bands; \
763 for (i = 0; i < frames; i++) { \
764 SecondOrderHistory ## TYPE *history = equ->history; \
765 for (c = 0; c < channels; c++) { \
766 cur = *((TYPE *) data); \
767 for (f = 0; f < nf; f++) { \
768 cur = one_step_ ## TYPE (filters[f], history, cur); \
771 cur = CLAMP (cur, MIN_VAL, MAX_VAL); \
772 *((TYPE *) data) = (TYPE) floor (cur); \
773 data += sizeof (TYPE); \
778 #define CREATE_OPTIMIZED_FUNCTIONS(TYPE) \
780 TYPE x1, x2; /* history of input values for a filter */ \
781 TYPE y1, y2; /* history of output values for a filter */ \
782 } SecondOrderHistory ## TYPE; \
785 one_step_ ## TYPE (GstIirEqualizerBand *filter, \
786 SecondOrderHistory ## TYPE *history, TYPE input) \
788 /* calculate output */ \
789 TYPE output = filter->a0 * input + filter->a1 * history->x1 + \
790 filter->a2 * history->x2 + filter->b1 * history->y1 + \
791 filter->b2 * history->y2; \
792 /* update history */ \
793 history->y2 = history->y1; \
794 history->y1 = output; \
795 history->x2 = history->x1; \
796 history->x1 = input; \
802 history_size_ ## TYPE = sizeof (SecondOrderHistory ## TYPE); \
805 gst_iir_equ_process_ ## TYPE (GstIirEqualizer *equ, guint8 *data, \
806 guint size, guint channels) \
808 guint frames = size / channels / sizeof (TYPE); \
809 guint i, c, f, nf = equ->freq_band_count; \
811 GstIirEqualizerBand **filters = equ->bands; \
813 for (i = 0; i < frames; i++) { \
814 SecondOrderHistory ## TYPE *history = equ->history; \
815 for (c = 0; c < channels; c++) { \
816 cur = *((TYPE *) data); \
817 for (f = 0; f < nf; f++) { \
818 cur = one_step_ ## TYPE (filters[f], history, cur); \
821 *((TYPE *) data) = (TYPE) cur; \
822 data += sizeof (TYPE); \
827 CREATE_OPTIMIZED_FUNCTIONS_INT (gint16, gfloat, -32768.0, 32767.0);
828 CREATE_OPTIMIZED_FUNCTIONS (gfloat);
829 CREATE_OPTIMIZED_FUNCTIONS (gdouble);
832 gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
834 GstAudioFilter *filter = GST_AUDIO_FILTER (btrans);
835 GstIirEqualizer *equ = GST_IIR_EQUALIZER (btrans);
836 GstClockTime timestamp;
837 gboolean need_new_coefficients;
839 if (G_UNLIKELY (filter->format.channels < 1 || equ->process == NULL))
840 return GST_FLOW_NOT_NEGOTIATED;
843 need_new_coefficients = equ->need_new_coefficients;
846 if (!need_new_coefficients && gst_base_transform_is_passthrough (btrans))
849 timestamp = GST_BUFFER_TIMESTAMP (buf);
851 gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp);
853 if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
854 GstIirEqualizerBand **filters = equ->bands;
855 guint f, nf = equ->freq_band_count;
857 gst_object_sync_values (G_OBJECT (equ), timestamp);
859 /* sync values for bands too */
860 /* FIXME: iterating equ->bands is not thread-safe here */
861 for (f = 0; f < nf; f++) {
862 gst_object_sync_values (G_OBJECT (filters[f]), timestamp);
867 if (need_new_coefficients) {
868 update_coefficients (equ);
869 set_passthrough (equ);
873 equ->process (equ, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf),
874 filter->format.channels);
880 gst_iir_equalizer_setup (GstAudioFilter * audio, GstRingBufferSpec * fmt)
882 GstIirEqualizer *equ = GST_IIR_EQUALIZER (audio);
885 case GST_BUFTYPE_LINEAR:
886 switch (fmt->width) {
888 equ->history_size = history_size_gint16;
889 equ->process = gst_iir_equ_process_gint16;
895 case GST_BUFTYPE_FLOAT:
896 switch (fmt->width) {
898 equ->history_size = history_size_gfloat;
899 equ->process = gst_iir_equ_process_gfloat;
902 equ->history_size = history_size_gdouble;
903 equ->process = gst_iir_equ_process_gdouble;
919 plugin_init (GstPlugin * plugin)
921 GST_DEBUG_CATEGORY_INIT (equalizer_debug, "equalizer", 0, "equalizer");
923 if (!(gst_element_register (plugin, "equalizer-nbands", GST_RANK_NONE,
924 GST_TYPE_IIR_EQUALIZER_NBANDS)))
927 if (!(gst_element_register (plugin, "equalizer-3bands", GST_RANK_NONE,
928 GST_TYPE_IIR_EQUALIZER_3BANDS)))
931 if (!(gst_element_register (plugin, "equalizer-10bands", GST_RANK_NONE,
932 GST_TYPE_IIR_EQUALIZER_10BANDS)))
938 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
941 "GStreamer audio equalizers",
942 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)