gst/equalizer/: Better algorith for the center frequencies. Subtract band filters from input for negative gains. Rewo...

Original commit message from CVS:
* gst/equalizer/gstiirequalizer.c:
(gst_iir_equalizer_band_set_property),
(gst_iir_equalizer_child_proxy_get_child_by_index),
(gst_iir_equalizer_child_proxy_get_children_count),
(gst_iir_equalizer_child_proxy_interface_init),
(gst_iir_equalizer_class_init), (arg_to_scale), (setup_filter),
(gst_iir_equalizer_compute_frequencies):
* gst/equalizer/gstiirequalizer10bands.c:
(gst_iir_equalizer_10bands_class_init):
* gst/equalizer/gstiirequalizer3bands.c:
(gst_iir_equalizer_3bands_class_init):
* gst/equalizer/gstiirequalizernbands.c:
Better algorith for the center frequencies. Subtract band filters from
input for negative gains. Rework the gain mapping.
This commit is contained in:
Stefan Kost 2007-07-20 11:37:37 +00:00
parent 64b49df80b
commit 2f43b8738c
5 changed files with 83 additions and 78 deletions

View file

@ -1,3 +1,20 @@
2007-07-20 Stefan Kost <ensonic@users.sf.net>
* gst/equalizer/gstiirequalizer.c:
(gst_iir_equalizer_band_set_property),
(gst_iir_equalizer_child_proxy_get_child_by_index),
(gst_iir_equalizer_child_proxy_get_children_count),
(gst_iir_equalizer_child_proxy_interface_init),
(gst_iir_equalizer_class_init), (arg_to_scale), (setup_filter),
(gst_iir_equalizer_compute_frequencies):
* gst/equalizer/gstiirequalizer10bands.c:
(gst_iir_equalizer_10bands_class_init):
* gst/equalizer/gstiirequalizer3bands.c:
(gst_iir_equalizer_3bands_class_init):
* gst/equalizer/gstiirequalizernbands.c:
Better algorith for the center frequencies. Subtract band filters from
input for negative gains. Rework the gain mapping.
2007-07-20 Stefan Kost <ensonic@users.sf.net> 2007-07-20 Stefan Kost <ensonic@users.sf.net>
* ext/dirac/Makefile.am: * ext/dirac/Makefile.am:

View file

@ -141,7 +141,7 @@ gst_iir_equalizer_band_set_property (GObject * object, guint prop_id,
gdouble gain; gdouble gain;
gain = g_value_get_double (value); gain = g_value_get_double (value);
GST_INFO_OBJECT (band, "gain = %lf -> %lf", band->gain, gain); GST_DEBUG_OBJECT (band, "gain = %lf -> %lf", band->gain, gain);
if (gain != band->gain) { if (gain != band->gain) {
GstIirEqualizer *equ = GstIirEqualizer *equ =
GST_IIR_EQUALIZER (gst_object_get_parent (GST_OBJECT (band))); GST_IIR_EQUALIZER (gst_object_get_parent (GST_OBJECT (band)));
@ -151,7 +151,7 @@ gst_iir_equalizer_band_set_property (GObject * object, guint prop_id,
setup_filter (equ, band); setup_filter (equ, band);
} }
gst_object_unref (equ); gst_object_unref (equ);
GST_INFO_OBJECT (band, "changed gain = %lf ", band->gain); GST_DEBUG_OBJECT (band, "changed gain = %lf ", band->gain);
} }
break; break;
} }
@ -233,8 +233,7 @@ gst_iir_equalizer_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
g_return_val_if_fail (index < equ->freq_band_count, NULL); g_return_val_if_fail (index < equ->freq_band_count, NULL);
GST_INFO ("return child[%d] '%s'", index, GST_LOG ("return child[%d] '%s'", index, GST_OBJECT_NAME (equ->bands[index]));
GST_OBJECT_NAME (equ->bands[index]));
return (gst_object_ref (equ->bands[index])); return (gst_object_ref (equ->bands[index]));
} }
@ -243,7 +242,7 @@ gst_iir_equalizer_child_proxy_get_children_count (GstChildProxy * child_proxy)
{ {
GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy); GstIirEqualizer *equ = GST_IIR_EQUALIZER (child_proxy);
GST_INFO ("we have %d children", equ->freq_band_count); GST_LOG ("we have %d children", equ->freq_band_count);
return (equ->freq_band_count); return (equ->freq_band_count);
} }
@ -253,7 +252,7 @@ gst_iir_equalizer_child_proxy_interface_init (gpointer g_iface,
{ {
GstChildProxyInterface *iface = g_iface; GstChildProxyInterface *iface = g_iface;
GST_INFO ("initializing iface"); GST_DEBUG ("initializing iface");
iface->get_child_by_index = gst_iir_equalizer_child_proxy_get_child_by_index; iface->get_child_by_index = gst_iir_equalizer_child_proxy_get_child_by_index;
iface->get_children_count = gst_iir_equalizer_child_proxy_get_children_count; iface->get_children_count = gst_iir_equalizer_child_proxy_get_children_count;
@ -288,7 +287,7 @@ gst_iir_equalizer_class_init (GstIirEqualizerClass * klass)
g_object_class_install_property (gobject_class, ARG_BAND_WIDTH, g_object_class_install_property (gobject_class, ARG_BAND_WIDTH,
g_param_spec_double ("band-width", "band-width", g_param_spec_double ("band-width", "band-width",
"band width calculated as distance between bands * this value", 0.1, "band width calculated as distance between bands * this value", 0.1,
5.0, 1.0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); 10.0, 1.0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
audio_filter_class->setup = gst_iir_equalizer_setup; audio_filter_class->setup = gst_iir_equalizer_setup;
btrans_class->transform_ip = gst_iir_equalizer_transform_ip; btrans_class->transform_ip = gst_iir_equalizer_transform_ip;
@ -314,19 +313,20 @@ gst_iir_equalizer_finalize (GObject * object)
/* /*
* converts gain values to scale factors. * converts gain values to scale factors.
* *
* arguments are in the range [-1 ... 1] with 0 meaning "no action" * we map -1 ... 1 to a db range.
* results are in the range [-0.2 ... 1] with 0 meaning "no action" * A suitable range would be -12db ... 0 ... + 6db which expressed as
* via the function * a factor is about 0.06 ... 1 ... 4.0
* f(x) = 0.25 * 5 ^ x - 0.25 *
* We need to subtract one so that gain is centered around zero
* *
* visualize via gnuplot: * visualize via gnuplot:
* set xrange [-1:1] * set xrange [-1:1]
* plot 0.25 * exp (log (5) * x) - 0.25 * plot 10.0 ** (12*x/10.0)
*/ */
static gdouble static gdouble
arg_to_scale (gdouble arg) arg_to_scale (gdouble arg)
{ {
return 0.25 * exp (log (5) * arg) - 0.25; return (pow (10.0, (6.0 * fabs (arg)) / 10.0) - 1.0);
} }
static void static void
@ -334,6 +334,10 @@ setup_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
{ {
g_return_if_fail (GST_AUDIO_FILTER (equ)->format.rate); g_return_if_fail (GST_AUDIO_FILTER (equ)->format.rate);
/* FIXME: we need better filters
* - the band-width control is not good
* - we need shelf-filter for 1st and last band
*/
{ {
gdouble gain = arg_to_scale (band->gain); gdouble gain = arg_to_scale (band->gain);
gdouble frequency = band->freq / GST_AUDIO_FILTER (equ)->format.rate; gdouble frequency = band->freq / GST_AUDIO_FILTER (equ)->format.rate;
@ -348,7 +352,9 @@ setup_filter (GstIirEqualizer * equ, GstIirEqualizerBand * band)
band->beta *= 2.0; band->beta *= 2.0;
band->alpha *= 2.0 * gain; band->alpha *= 2.0 * gain;
band->gamma *= 2.0; band->gamma *= 2.0;
GST_INFO ("gain = %g, frequency = %g, alpha = %g, beta = %g, gamma=%g",
GST_INFO
("gain = %7.5g, frequency = %7.5g, alpha = %7.5g, beta = %7.5g, gamma=%7.5g",
gain, frequency, band->alpha, band->beta, band->gamma); gain, frequency, band->alpha, band->beta, band->gamma);
} }
} }
@ -357,7 +363,7 @@ void
gst_iir_equalizer_compute_frequencies (GstIirEqualizer * equ, guint new_count) gst_iir_equalizer_compute_frequencies (GstIirEqualizer * equ, guint new_count)
{ {
guint old_count, i; guint old_count, i;
gdouble step = pow (HIGHEST_FREQ / LOWEST_FREQ, 1.0 / (new_count - 1)); gdouble freq0, freq1, step;
gchar name[20]; gchar name[20];
old_count = equ->freq_band_count; old_count = equ->freq_band_count;
@ -396,36 +402,23 @@ gst_iir_equalizer_compute_frequencies (GstIirEqualizer * equ, guint new_count)
/* set center frequencies and name band objects /* set center frequencies and name band objects
* FIXME: arg! we can't change the name of parented objects :( * FIXME: arg! we can't change the name of parented objects :(
* application should read band->freq * application should read band->freq to get the name
* FIXME: the code that calculates the center-frequencies for the bands should
* take the number of bands into account, when chooding the lowest frequency
*/ */
equ->bands[0]->freq = LOWEST_FREQ; step = pow (HIGHEST_FREQ / LOWEST_FREQ, 1.0 / new_count);
GST_DEBUG ("band[ 0] = '%lf'", equ->bands[0]->freq); freq0 = LOWEST_FREQ;
/* for (i = 0; i < new_count; i++) {
if(equ->bands[0]->freq<10000.0) { freq1 = freq0 * step;
sprintf (name,"%dHz",(gint)equ->bands[0]->freq); equ->bands[i]->freq = freq0 + ((freq1 - freq0) / 2.0);
}
else {
sprintf (name,"%dkHz",(gint)(equ->bands[0]->freq/1000.0));
}
gst_object_set_name( GST_OBJECT (equ->bands[0]), name);
GST_DEBUG ("band[ 0] = '%s'",name);
*/
for (i = 1; i < new_count; i++) {
equ->bands[i]->freq = equ->bands[i - 1]->freq * step;
GST_DEBUG ("band[%2d] = '%lf'", i, equ->bands[i]->freq); GST_DEBUG ("band[%2d] = '%lf'", i, equ->bands[i]->freq);
/* /*
if(equ->bands[i]->freq<10000.0) { if(equ->bands[i]->freq<10000.0)
sprintf (name,"%dHz",(gint)equ->bands[i]->freq); sprintf (name,"%dHz",(gint)equ->bands[i]->freq);
} else
else {
sprintf (name,"%dkHz",(gint)(equ->bands[i]->freq/1000.0)); sprintf (name,"%dkHz",(gint)(equ->bands[i]->freq/1000.0));
}
gst_object_set_name( GST_OBJECT (equ->bands[i]), name); gst_object_set_name( GST_OBJECT (equ->bands[i]), name);
GST_DEBUG ("band[%2d] = '%s'",i,name); GST_DEBUG ("band[%2d] = '%s'",i,name);
*/ */
freq0 = freq1;
} }
if (GST_AUDIO_FILTER (equ)->format.rate) { if (GST_AUDIO_FILTER (equ)->format.rate) {
@ -506,7 +499,8 @@ one_step_ ## TYPE (GstIirEqualizerBand *filter, \
history->x2 = history->x1; \ history->x2 = history->x1; \
history->x1 = input; \ history->x1 = input; \
\ \
return output; \ /* for negative gains we subtract */ \
return (filter->gain>0.0) ? output : -output; \
} \ } \
\ \
static const guint \ static const guint \
@ -525,14 +519,13 @@ guint size, guint channels) \
for (c = 0; c < channels; c++) { \ for (c = 0; c < channels; c++) { \
SecondOrderHistory ## TYPE *history = equ->history; \ SecondOrderHistory ## TYPE *history = equ->history; \
val = *((TYPE *) data); \ val = *((TYPE *) data); \
cur = 0; \ cur = 0.25 * val; /* FIXME: should be without factor*/ \
for (f = 0; f < equ->freq_band_count; f++) { \ for (f = 0; f < equ->freq_band_count; f++) { \
GstIirEqualizerBand *filter = equ->bands[f]; \ GstIirEqualizerBand *filter = equ->bands[f]; \
\ \
cur += one_step_ ## TYPE (filter, history, val); \ cur += one_step_ ## TYPE (filter, history, val); \
history++; \ history++; \
} \ } \
cur += val * 0.25; \
cur = CLAMP (cur, MIN_VAL, MAX_VAL); \ cur = CLAMP (cur, MIN_VAL, MAX_VAL); \
*((TYPE *) data) = (TYPE) cur; \ *((TYPE *) data) = (TYPE) cur; \
data += sizeof (TYPE); \ data += sizeof (TYPE); \

View file

@ -27,18 +27,13 @@
* </para> * </para>
* <para> * <para>
* <programlisting> * <programlisting>
* gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-10bands band2=-1.0 ! alsasink * gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-10bands band2=0.5 ! alsasink
* </programlisting> * </programlisting>
* This lowers the volume of the 3rd band which is at 93 Hz by FIXME db. * This raises the volume of the 3rd band which is at 119 Hz by 3 db.
* </para> * </para>
* </refsect2> * </refsect2>
*/ */
/*
*
* gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-10bands band1=-1.0 ! alsasink
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -96,44 +91,44 @@ gst_iir_equalizer_10bands_class_init (GstIirEqualizer10BandsClass * klass)
gobject_class->get_property = gst_iir_equalizer_10bands_get_property; gobject_class->get_property = gst_iir_equalizer_10bands_get_property;
g_object_class_install_property (gobject_class, ARG_BAND0, g_object_class_install_property (gobject_class, ARG_BAND0,
g_param_spec_double ("band0", "20 Hz", g_param_spec_double ("band0", "29 Hz",
"gain for the frequency band 20 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 29 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND1, g_object_class_install_property (gobject_class, ARG_BAND1,
g_param_spec_double ("band1", "43 Hz", g_param_spec_double ("band1", "59 Hz",
"gain for the frequency band 43 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 59 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND2, g_object_class_install_property (gobject_class, ARG_BAND2,
g_param_spec_double ("band2", "93 Hz", g_param_spec_double ("band2", "119 Hz",
"gain for the frequency band 93 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 119 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND3, g_object_class_install_property (gobject_class, ARG_BAND3,
g_param_spec_double ("band3", "200 Hz", g_param_spec_double ("band3", "227 Hz",
"gain for the frequency band 200 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 227 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND4, g_object_class_install_property (gobject_class, ARG_BAND4,
g_param_spec_double ("band4", "430 Hz", g_param_spec_double ("band4", "474 Hz",
"gain for the frequency band 430 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 474 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND5, g_object_class_install_property (gobject_class, ARG_BAND5,
g_param_spec_double ("band5", "928 Hz", g_param_spec_double ("band5", "947 Hz",
"gain for the frequency band 928 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 947 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND6, g_object_class_install_property (gobject_class, ARG_BAND6,
g_param_spec_double ("band6", "2000 Hz", g_param_spec_double ("band6", "1889 Hz",
"gain for the frequency band 2000 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 1889 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND7, g_object_class_install_property (gobject_class, ARG_BAND7,
g_param_spec_double ("band7", "4308 Hz", g_param_spec_double ("band7", "3770 Hz",
"gain for the frequency band 4308 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 3770 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND8, g_object_class_install_property (gobject_class, ARG_BAND8,
g_param_spec_double ("band8", "9283 Hz", g_param_spec_double ("band8", "7523 Hz",
"gain for the frequency band 9283 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 7523 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND9, g_object_class_install_property (gobject_class, ARG_BAND9,
g_param_spec_double ("band9", "20 kHz", g_param_spec_double ("band9", "15011 Hz",
"gain for the frequency band 20 kHz, ranging from -1.0 to +1.0", "gain for the frequency band 15011 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
} }

View file

@ -27,9 +27,9 @@
* </para> * </para>
* <para> * <para>
* <programlisting> * <programlisting>
* gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-3bands band1=-1.0 ! alsasink * gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-3bands band1=1.0 ! alsasink
* </programlisting> * </programlisting>
* This lowers the volume of the 2nd band which is at 632 Hz by FIXME db. * This raises the volume of the 2nd band which is at 1110 Hz by 6 db.
* </para> * </para>
* </refsect2> * </refsect2>
*/ */
@ -84,16 +84,16 @@ gst_iir_equalizer_3bands_class_init (GstIirEqualizer3BandsClass * klass)
gobject_class->get_property = gst_iir_equalizer_3bands_get_property; gobject_class->get_property = gst_iir_equalizer_3bands_get_property;
g_object_class_install_property (gobject_class, ARG_BAND0, g_object_class_install_property (gobject_class, ARG_BAND0,
g_param_spec_double ("band0", "20 Hz", g_param_spec_double ("band0", "110 Hz",
"gain for the frequency band 20 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 110 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND1, g_object_class_install_property (gobject_class, ARG_BAND1,
g_param_spec_double ("band1", "632 Hz", g_param_spec_double ("band1", "1110 Hz",
"gain for the frequency band 632 Hz, ranging from -1.0 to +1.0", "gain for the frequency band 1110 Hz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
g_object_class_install_property (gobject_class, ARG_BAND2, g_object_class_install_property (gobject_class, ARG_BAND2,
g_param_spec_double ("band2", "20 kHz", g_param_spec_double ("band2", "11 kHz",
"gain for the frequency band 20 kHz, ranging from -1.0 to +1.0", "gain for the frequency band 11 kHz, ranging from -1.0 to +1.0",
-1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE)); -1.0, 1.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
} }

View file

@ -28,9 +28,9 @@
* </para> * </para>
* <para> * <para>
* <programlisting> * <programlisting>
* gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-nbands num-bands=15 band5::gain=-1.0 ! alsasink * gst-launch filesrc location=song.ogg ! oggdemux ! vorbisdec ! audioconvert ! equalizer-nbands num-bands=15 band5::gain=1.0 ! alsasink
* </programlisting> * </programlisting>
* This make the equalizer use 15 bands and lowers the volume of the 5th band by FIXME db. * This make the equalizer use 15 bands and raises the volume of the 5th band by 6 db.
* </para> * </para>
* </refsect2> * </refsect2>
*/ */