Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
equalizer.c
Go to the documentation of this file.
1 /*
2  * Equalizer filter, implementation of a 10 band time domain graphic equalizer
3  * using IIR filters. The IIR filters are implemented using a Direct Form II
4  * approach, modified (b1 == 0 always) to save computation.
5  *
6  * This software has been released under the terms of the GNU General Public
7  * license. See http://www.gnu.org/copyleft/gpl.html for details.
8  *
9  * Copyright 2001 Anders Johansson <ajh@atri.curtin.edu.au>
10  *
11  * Adapted for Audacious by John Lindgren, 2010-2011
12  */
13 
14 #include <glib.h>
15 #include <math.h>
16 #include <pthread.h>
17 #include <string.h>
18 
19 #include <libaudcore/audstrings.h>
20 #include <libaudcore/hook.h>
21 
22 #include "equalizer.h"
23 #include "misc.h"
24 #include "types.h"
25 
26 #define EQ_BANDS AUD_EQUALIZER_NBANDS
27 #define MAX_CHANNELS 10
28 
29 /* Q value for band-pass filters 1.2247 = (3/2)^(1/2)
30  * Gives 4 dB suppression at Fc*2 and Fc/2 */
31 #define Q 1.2247449
32 
33 /* Center frequencies for band-pass filters (Hz) */
34 /* These are not the historical WinAmp frequencies, because the IIR filters used
35  * here are designed for each frequency to be twice the previous. Using WinAmp
36  * frequencies leads to too much gain in some bands and too little in others. */
37 static const float CF[EQ_BANDS] = {31.25, 62.5, 125, 250, 500, 1000, 2000,
38  4000, 8000, 16000};
39 
40 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
41 static bool_t active;
42 static int channels, rate;
43 static float a[EQ_BANDS][2]; /* A weights */
44 static float b[EQ_BANDS][2]; /* B weights */
45 static float wqv[MAX_CHANNELS][EQ_BANDS][2]; /* Circular buffer for W data */
46 static float gv[MAX_CHANNELS][EQ_BANDS]; /* Gain factor for each channel and band */
47 static int K; /* Number of used eq bands */
48 
49 /* 2nd order band-pass filter design */
50 static void bp2 (float * a, float * b, float fc, float q)
51 {
52  float th = 2 * M_PI * fc;
53  float C = (1 - tanf (th * q / 2)) / (1 + tanf (th * q / 2));
54 
55  a[0] = (1 + C) * cosf (th);
56  a[1] = -C;
57  b[0] = (1 - C) / 2;
58  b[1] = -1.005;
59 }
60 
61 void eq_set_format (int new_channels, int new_rate)
62 {
63  int k;
64 
65  pthread_mutex_lock (& mutex);
66 
67  channels = new_channels;
68  rate = new_rate;
69 
70  /* Calculate number of active filters */
71  K = EQ_BANDS;
72 
73  while (CF[K - 1] > (float) rate / 2.2)
74  K --;
75 
76  /* Generate filter taps */
77  for (k = 0; k < K; k ++)
78  bp2 (a[k], b[k], CF[k] / (float) rate, Q);
79 
80  /* Reset state */
81  memset (wqv[0][0], 0, sizeof wqv);
82 
83  pthread_mutex_unlock (& mutex);
84 }
85 
86 static void eq_set_bands_real (double preamp, double * values)
87 {
88  float adj[EQ_BANDS];
89  for (int i = 0; i < EQ_BANDS; i ++)
90  adj[i] = preamp + values[i];
91 
92  for (int c = 0; c < MAX_CHANNELS; c ++)
93  for (int i = 0; i < EQ_BANDS; i ++)
94  gv[c][i] = pow (10, adj[i] / 20) - 1;
95 }
96 
97 void eq_filter (float * data, int samples)
98 {
99  int channel;
100 
101  pthread_mutex_lock (& mutex);
102 
103  if (! active)
104  {
105  pthread_mutex_unlock (& mutex);
106  return;
107  }
108 
109  for (channel = 0; channel < channels; channel ++)
110  {
111  float * g = gv[channel]; /* Gain factor */
112  float * end = data + samples;
113  float * f;
114 
115  for (f = data + channel; f < end; f += channels)
116  {
117  int k; /* Frequency band index */
118  float yt = * f; /* Current input sample */
119 
120  for (k = 0; k < K; k ++)
121  {
122  /* Pointer to circular buffer wq */
123  float * wq = wqv[channel][k];
124  /* Calculate output from AR part of current filter */
125  float w = yt * b[k][0] + wq[0] * a[k][0] + wq[1] * a[k][1];
126 
127  /* Calculate output from MA part of current filter */
128  yt += (w + wq[1] * b[k][1]) * g[k];
129 
130  /* Update circular buffer */
131  wq[1] = wq[0];
132  wq[0] = w;
133  }
134 
135  /* Calculate output */
136  * f = yt;
137  }
138  }
139 
140  pthread_mutex_unlock (& mutex);
141 }
142 
143 static void eq_update (void * data, void * user)
144 {
145  pthread_mutex_lock (& mutex);
146 
147  active = get_bool (NULL, "equalizer_active");
148 
149  double values[EQ_BANDS];
150  eq_get_bands (values);
151  eq_set_bands_real (get_double (NULL, "equalizer_preamp"), values);
152 
153  pthread_mutex_unlock (& mutex);
154 }
155 
156 void eq_init (void)
157 {
158  eq_update (NULL, NULL);
159  hook_associate ("set equalizer_active", eq_update, NULL);
160  hook_associate ("set equalizer_preamp", eq_update, NULL);
161  hook_associate ("set equalizer_bands", eq_update, NULL);
162 }
163 
164 void eq_cleanup (void)
165 {
166  hook_dissociate ("set equalizer_active", eq_update);
167  hook_dissociate ("set equalizer_preamp", eq_update);
168  hook_dissociate ("set equalizer_bands", eq_update);
169 }
170 
171 void eq_set_bands (const double * values)
172 {
173  char * string = double_array_to_string (values, EQ_BANDS);
174  g_return_if_fail (string);
175  set_string (NULL, "equalizer_bands", string);
176  g_free (string);
177 }
178 
179 void eq_get_bands (double * values)
180 {
181  memset (values, 0, sizeof (double) * EQ_BANDS);
182  char * string = get_string (NULL, "equalizer_bands");
183  string_to_double_array (string, values, EQ_BANDS);
184  g_free (string);
185 }
186 
187 void eq_set_band (int band, double value)
188 {
189  g_return_if_fail (band >= 0 && band < EQ_BANDS);
190  double values[EQ_BANDS];
191  eq_get_bands (values);
192  values[band] = value;
193  eq_set_bands (values);
194 }
195 
196 double eq_get_band (int band)
197 {
198  g_return_val_if_fail (band >= 0 && band < EQ_BANDS, 0);
199  double values[EQ_BANDS];
200  eq_get_bands (values);
201  return values[band];
202 }