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., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
30 #include "gstiirequalizer.h"
31 #include "gstiirequalizernbands.h"
32 #include "gstiirequalizer3bands.h"
33 #include "gstiirequalizer10bands.h"
35 #include "gst/glib-compat-private.h"
37 GST_DEBUG_CATEGORY (equalizer_debug);
38 #define GST_CAT_DEFAULT equalizer_debug
40 #define BANDS_LOCK(equ) g_mutex_lock(&equ->bands_lock)
41 #define BANDS_UNLOCK(equ) g_mutex_unlock(&equ->bands_lock)
43 static void gst_iir_equalizer_child_proxy_interface_init (gpointer g_iface,
46 static void gst_iir_equalizer_finalize (GObject * object);
48 static gboolean gst_iir_equalizer_setup (GstAudioFilter * filter,
49 const GstAudioInfo * info);
50 static GstFlowReturn gst_iir_equalizer_transform_ip (GstBaseTransform * btrans,
53 #define ALLOWED_CAPS \
55 " format=(string) {"GST_AUDIO_NE(S16)","GST_AUDIO_NE(F32)"," \
56 GST_AUDIO_NE(F64)" }, " \
57 " rate=(int)[1000,MAX]," \
58 " channels=(int)[1,MAX]," \
59 " layout=(string)interleaved"
61 #define gst_iir_equalizer_parent_class parent_class
62 G_DEFINE_TYPE_WITH_CODE (GstIirEqualizer, gst_iir_equalizer,
63 GST_TYPE_AUDIO_FILTER,
64 G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
65 gst_iir_equalizer_child_proxy_interface_init)
66 G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
84 } GstIirEqualizerBandType;
86 #define GST_TYPE_IIR_EQUALIZER_BAND_TYPE (gst_iir_equalizer_band_type_get_type ())
88 gst_iir_equalizer_band_type_get_type (void)
90 static GType gtype = 0;
93 static const GEnumValue values[] = {
94 {BAND_TYPE_PEAK, "Peak filter (default for inner bands)", "peak"},
95 {BAND_TYPE_LOW_SHELF, "Low shelf filter (default for first band)",
97 {BAND_TYPE_HIGH_SHELF, "High shelf filter (default for last band)",
102 gtype = g_enum_register_static ("GstIirEqualizerBandType", values);
108 typedef struct _GstIirEqualizerBandClass GstIirEqualizerBandClass;
110 #define GST_TYPE_IIR_EQUALIZER_BAND \
111 (gst_iir_equalizer_band_get_type())
112 #define GST_IIR_EQUALIZER_BAND(obj) \
113 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_IIR_EQUALIZER_BAND,GstIirEqualizerBand))
114 #define GST_IIR_EQUALIZER_BAND_CLASS(klass) \
115 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_IIR_EQUALIZER_BAND,GstIirEqualizerBandClass))
116 #define GST_IS_IIR_EQUALIZER_BAND(obj) \
117 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_IIR_EQUALIZER_BAND))
118 #define GST_IS_IIR_EQUALIZER_BAND_CLASS(klass) \
119 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_IIR_EQUALIZER_BAND))
121 struct _GstIirEqualizerBand
126 /* center frequency and gain */
130 GstIirEqualizerBandType type;
132 /* second order iir filter */
133 gdouble b1, b2; /* IIR coefficients for outputs */
134 gdouble a0, a1, a2; /* IIR coefficients for inputs */
137 struct _GstIirEqualizerBandClass
139 GstObjectClass parent_class;
142 static GType gst_iir_equalizer_band_get_type (void);
145 gst_iir_equalizer_band_set_property (GObject * object, guint prop_id,
146 const GValue * value, GParamSpec * pspec)
148 GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object);
149 GstIirEqualizer *equ =
150 GST_IIR_EQUALIZER (gst_object_get_parent (GST_OBJECT (band)));
156 gain = g_value_get_double (value);
157 GST_DEBUG_OBJECT (band, "gain = %lf -> %lf", band->gain, gain);
158 if (gain != band->gain) {
160 equ->need_new_coefficients = TRUE;
163 GST_DEBUG_OBJECT (band, "changed gain = %lf ", band->gain);
170 freq = g_value_get_double (value);
171 GST_DEBUG_OBJECT (band, "freq = %lf -> %lf", band->freq, freq);
172 if (freq != band->freq) {
174 equ->need_new_coefficients = TRUE;
177 GST_DEBUG_OBJECT (band, "changed freq = %lf ", band->freq);
181 case PROP_BANDWIDTH:{
184 width = g_value_get_double (value);
185 GST_DEBUG_OBJECT (band, "width = %lf -> %lf", band->width, width);
186 if (width != band->width) {
188 equ->need_new_coefficients = TRUE;
191 GST_DEBUG_OBJECT (band, "changed width = %lf ", band->width);
196 GstIirEqualizerBandType type;
198 type = g_value_get_enum (value);
199 GST_DEBUG_OBJECT (band, "type = %d -> %d", band->type, type);
200 if (type != band->type) {
202 equ->need_new_coefficients = TRUE;
205 GST_DEBUG_OBJECT (band, "changed type = %d ", band->type);
210 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
214 gst_object_unref (equ);
218 gst_iir_equalizer_band_get_property (GObject * object, guint prop_id,
219 GValue * value, GParamSpec * pspec)
221 GstIirEqualizerBand *band = GST_IIR_EQUALIZER_BAND (object);
225 g_value_set_double (value, band->gain);
228 g_value_set_double (value, band->freq);
231 g_value_set_double (value, band->width);
234 g_value_set_enum (value, band->type);
237 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
243 gst_iir_equalizer_band_class_init (GstIirEqualizerBandClass * klass)
245 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
247 gobject_class->set_property = gst_iir_equalizer_band_set_property;
248 gobject_class->get_property = gst_iir_equalizer_band_get_property;
250 g_object_class_install_property (gobject_class, PROP_GAIN,
251 g_param_spec_double ("gain", "gain",
252 "gain for the frequency band ranging from -24.0 dB to +12.0 dB",
254 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
256 g_object_class_install_property (gobject_class, PROP_FREQ,
257 g_param_spec_double ("freq", "freq",
258 "center frequency of the band",
260 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
262 g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
263 g_param_spec_double ("bandwidth", "bandwidth",
264 "difference between bandedges in Hz",
266 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
268 g_object_class_install_property (gobject_class, PROP_TYPE,
269 g_param_spec_enum ("type", "Type",
270 "Filter type", GST_TYPE_IIR_EQUALIZER_BAND_TYPE,
272 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
276 gst_iir_equalizer_band_init (GstIirEqualizerBand * band,
277 GstIirEqualizerBandClass * klass)
282 band->type = BAND_TYPE_PEAK;
286 gst_iir_equalizer_band_get_type (void)
288 static GType type = 0;
290 if (G_UNLIKELY (!type)) {
291 const GTypeInfo type_info = {
292 sizeof (GstIirEqualizerBandClass),
295 (GClassInitFunc) gst_iir_equalizer_band_class_init,
298 sizeof (GstIirEqualizerBand),
300 (GInstanceInitFunc) gst_iir_equalizer_band_init,
303 g_type_register_static (GST_TYPE_OBJECT, "GstIirEqualizerBand",
310 /* child proxy iface */
312 gst_iir_equalizer_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
315 GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);
319 if (G_UNLIKELY (index >= equ->freq_band_count)) {
321 g_return_val_if_fail (index < equ->freq_band_count, NULL);
324 ret = g_object_ref (equ->bands[index]);
327 GST_LOG_OBJECT (equ, "return child[%d] %" GST_PTR_FORMAT, index, ret);
332 gst_iir_equalizer_child_proxy_get_children_count (GstChildProxy * child_proxy)
334 GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);
336 GST_LOG ("we have %d children", equ->freq_band_count);
337 return equ->freq_band_count;
341 gst_iir_equalizer_child_proxy_interface_init (gpointer g_iface,
344 GstChildProxyInterface *iface = g_iface;
346 GST_DEBUG ("initializing iface");
348 iface->get_child_by_index = gst_iir_equalizer_child_proxy_get_child_by_index;
349 iface->get_children_count = gst_iir_equalizer_child_proxy_get_children_count;
352 /* equalizer implementation */
355 gst_iir_equalizer_class_init (GstIirEqualizerClass * klass)
357 GstAudioFilterClass *audio_filter_class = (GstAudioFilterClass *) klass;
358 GstBaseTransformClass *btrans_class = (GstBaseTransformClass *) klass;
359 GObjectClass *gobject_class = (GObjectClass *) klass;
362 gobject_class->finalize = gst_iir_equalizer_finalize;
363 audio_filter_class->setup = gst_iir_equalizer_setup;
364 btrans_class->transform_ip = gst_iir_equalizer_transform_ip;
366 caps = gst_caps_from_string (ALLOWED_CAPS);
367 gst_audio_filter_class_add_pad_templates (audio_filter_class, caps);
368 gst_caps_unref (caps);
372 gst_iir_equalizer_init (GstIirEqualizer * eq)
374 g_mutex_init (&eq->bands_lock);
375 eq->need_new_coefficients = TRUE;
379 gst_iir_equalizer_finalize (GObject * object)
381 GstIirEqualizer *equ = GST_IIR_EQUALIZER (object);
384 for (i = 0; i < equ->freq_band_count; i++) {
386 gst_object_unparent (GST_OBJECT (equ->bands[i]));
387 equ->bands[i] = NULL;
389 equ->freq_band_count = 0;
392 g_free (equ->history);
394 g_mutex_clear (&equ->bands_lock);
396 G_OBJECT_CLASS (parent_class)->finalize (object);
401 * The Equivalence of Various Methods of Computing
402 * Biquad Coefficients for Audio Parametric Equalizers
404 * by Robert Bristow-Johnson
406 * http://www.aes.org/e-lib/browse.cfm?elib=6326
407 * http://www.musicdsp.org/files/EQ-Coefficients.pdf
408 * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
410 * The bandwidth method that we use here is the preferred
411 * one from this article transformed from octaves to frequency
414 static inline gdouble
415 arg_to_scale (gdouble arg)
417 return (pow (10.0, arg / 40.0));
421 calculate_omega (gdouble freq, gint rate)
425 if (freq / rate >= 0.5)
427 else if (freq <= 0.0)
430 omega = 2.0 * G_PI * (freq / rate);
436 calculate_bw (GstIirEqualizerBand * band, gint rate)
440 if (band->width / rate >= 0.5) {
441 /* If bandwidth == 0.5 the calculation below fails as tan(G_PI/2)
442 * is undefined. So set the bandwidth to a slightly smaller value.
444 bw = G_PI - 0.00000001;
445 } else if (band->width <= 0.0) {
446 /* If bandwidth == 0 this band won't change anything so set
447 * the coefficients accordingly. The coefficient calculation
448 * below would create coefficients that for some reason amplify
457 bw = 2.0 * G_PI * (band->width / rate);
463 setup_peak_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
465 gint rate = GST_AUDIO_FILTER_RATE (equ);
467 g_return_if_fail (rate);
470 gdouble gain, omega, bw;
471 gdouble alpha, alpha1, alpha2, b0;
473 gain = arg_to_scale (band->gain);
474 omega = calculate_omega (band->freq, rate);
475 bw = calculate_bw (band, rate);
479 alpha = tan (bw / 2.0);
481 alpha1 = alpha * gain;
482 alpha2 = alpha / gain;
486 band->a0 = (1.0 + alpha1) / b0;
487 band->a1 = (-2.0 * cos (omega)) / b0;
488 band->a2 = (1.0 - alpha1) / b0;
489 band->b1 = (2.0 * cos (omega)) / b0;
490 band->b2 = -(1.0 - alpha2) / b0;
494 ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g",
495 band->gain, band->width, band->freq, band->a0, band->a1, band->a2,
501 setup_low_shelf_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
503 gint rate = GST_AUDIO_FILTER_RATE (equ);
505 g_return_if_fail (rate);
508 gdouble gain, omega, bw;
509 gdouble alpha, delta, b0;
512 gain = arg_to_scale (band->gain);
513 omega = calculate_omega (band->freq, rate);
514 bw = calculate_bw (band, rate);
520 alpha = tan (bw / 2.0);
522 delta = 2.0 * sqrt (gain) * alpha;
523 b0 = egp + egm * cos (omega) + delta;
525 band->a0 = ((egp - egm * cos (omega) + delta) * gain) / b0;
526 band->a1 = ((egm - egp * cos (omega)) * 2.0 * gain) / b0;
527 band->a2 = ((egp - egm * cos (omega) - delta) * gain) / b0;
528 band->b1 = ((egm + egp * cos (omega)) * 2.0) / b0;
529 band->b2 = -((egp + egm * cos (omega) - delta)) / b0;
534 ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g",
535 band->gain, band->width, band->freq, band->a0, band->a1, band->a2,
541 setup_high_shelf_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
543 gint rate = GST_AUDIO_FILTER_RATE (equ);
545 g_return_if_fail (rate);
548 gdouble gain, omega, bw;
549 gdouble alpha, delta, b0;
552 gain = arg_to_scale (band->gain);
553 omega = calculate_omega (band->freq, rate);
554 bw = calculate_bw (band, rate);
560 alpha = tan (bw / 2.0);
562 delta = 2.0 * sqrt (gain) * alpha;
563 b0 = egp - egm * cos (omega) + delta;
565 band->a0 = ((egp + egm * cos (omega) + delta) * gain) / b0;
566 band->a1 = ((egm + egp * cos (omega)) * -2.0 * gain) / b0;
567 band->a2 = ((egp + egm * cos (omega) - delta) * gain) / b0;
568 band->b1 = ((egm - egp * cos (omega)) * -2.0) / b0;
569 band->b2 = -((egp - egm * cos (omega) - delta)) / b0;
574 ("gain = %5.1f, width= %7.2f, freq = %7.2f, a0 = %7.5g, a1 = %7.5g, a2=%7.5g b1 = %7.5g, b2 = %7.5g",
575 band->gain, band->width, band->freq, band->a0, band->a1, band->a2,
580 /* Must be called with bands_lock and transform lock! */
582 set_passthrough (GstIirEqualizer * equ)
585 gboolean passthrough = TRUE;
587 for (i = 0; i < equ->freq_band_count; i++) {
588 passthrough = passthrough && (equ->bands[i]->gain == 0.0);
591 gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (equ), passthrough);
592 GST_DEBUG ("Passthrough mode: %d\n", passthrough);
595 /* Must be called with bands_lock and transform lock! */
597 update_coefficients (GstIirEqualizer * equ)
599 gint i, n = equ->freq_band_count;
601 for (i = 0; i < n; i++) {
602 if (equ->bands[i]->type == BAND_TYPE_PEAK)
603 setup_peak_filter (equ, equ->bands[i]);
604 else if (equ->bands[i]->type == BAND_TYPE_LOW_SHELF)
605 setup_low_shelf_filter (equ, equ->bands[i]);
607 setup_high_shelf_filter (equ, equ->bands[i]);
610 equ->need_new_coefficients = FALSE;
613 /* Must be called with transform lock! */
615 alloc_history (GstIirEqualizer * equ, const GstAudioInfo * info)
617 /* free + alloc = no memcpy */
618 g_free (equ->history);
620 g_malloc0 (equ->history_size * GST_AUDIO_INFO_CHANNELS (info) *
621 equ->freq_band_count);
625 gst_iir_equalizer_compute_frequencies (GstIirEqualizer * equ, guint new_count)
628 gdouble freq0, freq1, step;
631 if (equ->freq_band_count == new_count)
636 if (G_UNLIKELY (equ->freq_band_count == new_count)) {
641 old_count = equ->freq_band_count;
642 equ->freq_band_count = new_count;
643 GST_DEBUG ("bands %u -> %u", old_count, new_count);
645 if (old_count < new_count) {
647 equ->bands = g_realloc (equ->bands, sizeof (GstObject *) * new_count);
648 for (i = old_count; i < new_count; i++) {
649 /* otherwise they get names like 'iirequalizerband5' */
650 sprintf (name, "band%u", i);
651 equ->bands[i] = g_object_new (GST_TYPE_IIR_EQUALIZER_BAND,
653 GST_DEBUG ("adding band[%d]=%p", i, equ->bands[i]);
655 gst_object_set_parent (GST_OBJECT (equ->bands[i]), GST_OBJECT (equ));
656 gst_child_proxy_child_added (GST_CHILD_PROXY (equ),
657 G_OBJECT (equ->bands[i]), name);
660 /* free unused bands */
661 for (i = new_count; i < old_count; i++) {
662 GST_DEBUG ("removing band[%d]=%p", i, equ->bands[i]);
663 gst_child_proxy_child_removed (GST_CHILD_PROXY (equ),
664 G_OBJECT (equ->bands[i]), GST_OBJECT_NAME (equ->bands[i]));
665 gst_object_unparent (GST_OBJECT (equ->bands[i]));
666 equ->bands[i] = NULL;
670 alloc_history (equ, GST_AUDIO_FILTER_INFO (equ));
672 /* set center frequencies and name band objects
673 * FIXME: arg! we can't change the name of parented objects :(
674 * application should read band->freq to get the name
677 step = pow (HIGHEST_FREQ / LOWEST_FREQ, 1.0 / new_count);
679 for (i = 0; i < new_count; i++) {
680 freq1 = freq0 * step;
683 equ->bands[i]->type = BAND_TYPE_LOW_SHELF;
684 else if (i == new_count - 1)
685 equ->bands[i]->type = BAND_TYPE_HIGH_SHELF;
687 equ->bands[i]->type = BAND_TYPE_PEAK;
689 equ->bands[i]->freq = freq0 + ((freq1 - freq0) / 2.0);
690 equ->bands[i]->width = freq1 - freq0;
691 GST_DEBUG ("band[%2d] = '%lf'", i, equ->bands[i]->freq);
693 g_object_notify (G_OBJECT (equ->bands[i]), "bandwidth");
694 g_object_notify (G_OBJECT (equ->bands[i]), "freq");
695 g_object_notify (G_OBJECT (equ->bands[i]), "type");
698 if(equ->bands[i]->freq<10000.0)
699 sprintf (name,"%dHz",(gint)equ->bands[i]->freq);
701 sprintf (name,"%dkHz",(gint)(equ->bands[i]->freq/1000.0));
702 gst_object_set_name( GST_OBJECT (equ->bands[i]), name);
703 GST_DEBUG ("band[%2d] = '%s'",i,name);
708 equ->need_new_coefficients = TRUE;
712 /* start of code that is type specific */
714 #define CREATE_OPTIMIZED_FUNCTIONS_INT(TYPE,BIG_TYPE,MIN_VAL,MAX_VAL) \
716 BIG_TYPE x1, x2; /* history of input values for a filter */ \
717 BIG_TYPE y1, y2; /* history of output values for a filter */ \
718 } SecondOrderHistory ## TYPE; \
720 static inline BIG_TYPE \
721 one_step_ ## TYPE (GstIirEqualizerBand *filter, \
722 SecondOrderHistory ## TYPE *history, BIG_TYPE input) \
724 /* calculate output */ \
725 BIG_TYPE output = filter->a0 * input + \
726 filter->a1 * history->x1 + filter->a2 * history->x2 + \
727 filter->b1 * history->y1 + filter->b2 * history->y2; \
728 /* update history */ \
729 history->y2 = history->y1; \
730 history->y1 = output; \
731 history->x2 = history->x1; \
732 history->x1 = input; \
738 history_size_ ## TYPE = sizeof (SecondOrderHistory ## TYPE); \
741 gst_iir_equ_process_ ## TYPE (GstIirEqualizer *equ, guint8 *data, \
742 guint size, guint channels) \
744 guint frames = size / channels / sizeof (TYPE); \
745 guint i, c, f, nf = equ->freq_band_count; \
747 GstIirEqualizerBand **filters = equ->bands; \
749 for (i = 0; i < frames; i++) { \
750 SecondOrderHistory ## TYPE *history = equ->history; \
751 for (c = 0; c < channels; c++) { \
752 cur = *((TYPE *) data); \
753 for (f = 0; f < nf; f++) { \
754 cur = one_step_ ## TYPE (filters[f], history, cur); \
757 cur = CLAMP (cur, MIN_VAL, MAX_VAL); \
758 *((TYPE *) data) = (TYPE) floor (cur); \
759 data += sizeof (TYPE); \
764 #define CREATE_OPTIMIZED_FUNCTIONS(TYPE) \
766 TYPE x1, x2; /* history of input values for a filter */ \
767 TYPE y1, y2; /* history of output values for a filter */ \
768 } SecondOrderHistory ## TYPE; \
771 one_step_ ## TYPE (GstIirEqualizerBand *filter, \
772 SecondOrderHistory ## TYPE *history, TYPE input) \
774 /* calculate output */ \
775 TYPE output = filter->a0 * input + filter->a1 * history->x1 + \
776 filter->a2 * history->x2 + filter->b1 * history->y1 + \
777 filter->b2 * history->y2; \
778 /* update history */ \
779 history->y2 = history->y1; \
780 history->y1 = output; \
781 history->x2 = history->x1; \
782 history->x1 = input; \
788 history_size_ ## TYPE = sizeof (SecondOrderHistory ## TYPE); \
791 gst_iir_equ_process_ ## TYPE (GstIirEqualizer *equ, guint8 *data, \
792 guint size, guint channels) \
794 guint frames = size / channels / sizeof (TYPE); \
795 guint i, c, f, nf = equ->freq_band_count; \
797 GstIirEqualizerBand **filters = equ->bands; \
799 for (i = 0; i < frames; i++) { \
800 SecondOrderHistory ## TYPE *history = equ->history; \
801 for (c = 0; c < channels; c++) { \
802 cur = *((TYPE *) data); \
803 for (f = 0; f < nf; f++) { \
804 cur = one_step_ ## TYPE (filters[f], history, cur); \
807 *((TYPE *) data) = (TYPE) cur; \
808 data += sizeof (TYPE); \
813 CREATE_OPTIMIZED_FUNCTIONS_INT (gint16, gfloat, -32768.0, 32767.0);
814 CREATE_OPTIMIZED_FUNCTIONS (gfloat);
815 CREATE_OPTIMIZED_FUNCTIONS (gdouble);
818 gst_iir_equalizer_transform_ip (GstBaseTransform * btrans, GstBuffer * buf)
820 GstAudioFilter *filter = GST_AUDIO_FILTER (btrans);
821 GstIirEqualizer *equ = GST_IIR_EQUALIZER (btrans);
822 GstClockTime timestamp;
824 gint channels = GST_AUDIO_FILTER_CHANNELS (filter);
825 gboolean need_new_coefficients;
827 if (G_UNLIKELY (channels < 1 || equ->process == NULL))
828 return GST_FLOW_NOT_NEGOTIATED;
831 need_new_coefficients = equ->need_new_coefficients;
834 if (!need_new_coefficients && gst_base_transform_is_passthrough (btrans))
837 timestamp = GST_BUFFER_TIMESTAMP (buf);
839 gst_segment_to_stream_time (&btrans->segment, GST_FORMAT_TIME, timestamp);
841 if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
842 GstIirEqualizerBand **filters = equ->bands;
843 guint f, nf = equ->freq_band_count;
845 gst_object_sync_values (GST_OBJECT (equ), timestamp);
847 /* sync values for bands too */
848 /* FIXME: iterating equ->bands is not thread-safe here */
849 for (f = 0; f < nf; f++) {
850 gst_object_sync_values (GST_OBJECT (filters[f]), timestamp);
855 if (need_new_coefficients) {
856 update_coefficients (equ);
857 set_passthrough (equ);
861 gst_buffer_map (buf, &map, GST_MAP_READWRITE);
862 equ->process (equ, map.data, map.size, channels);
863 gst_buffer_unmap (buf, &map);
869 gst_iir_equalizer_setup (GstAudioFilter * audio, const GstAudioInfo * info)
871 GstIirEqualizer *equ = GST_IIR_EQUALIZER (audio);
873 switch (GST_AUDIO_INFO_FORMAT (info)) {
874 case GST_AUDIO_FORMAT_S16:
875 equ->history_size = history_size_gint16;
876 equ->process = gst_iir_equ_process_gint16;
878 case GST_AUDIO_FORMAT_F32:
879 equ->history_size = history_size_gfloat;
880 equ->process = gst_iir_equ_process_gfloat;
882 case GST_AUDIO_FORMAT_F64:
883 equ->history_size = history_size_gdouble;
884 equ->process = gst_iir_equ_process_gdouble;
890 alloc_history (equ, info);
896 plugin_init (GstPlugin * plugin)
898 GST_DEBUG_CATEGORY_INIT (equalizer_debug, "equalizer", 0, "equalizer");
900 if (!(gst_element_register (plugin, "equalizer-nbands", GST_RANK_NONE,
901 GST_TYPE_IIR_EQUALIZER_NBANDS)))
904 if (!(gst_element_register (plugin, "equalizer-3bands", GST_RANK_NONE,
905 GST_TYPE_IIR_EQUALIZER_3BANDS)))
908 if (!(gst_element_register (plugin, "equalizer-10bands", GST_RANK_NONE,
909 GST_TYPE_IIR_EQUALIZER_10BANDS)))
915 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
918 "GStreamer audio equalizers",
919 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)