Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * Equalizer filter, implementation of a 10 band time domain graphic equalizer 00003 * using IIR filters. The IIR filters are implemented using a Direct Form II 00004 * approach, modified (b1 == 0 always) to save computation. 00005 * 00006 * This software has been released under the terms of the GNU General Public 00007 * license. See http://www.gnu.org/copyleft/gpl.html for details. 00008 * 00009 * Copyright 2001 Anders Johansson <ajh@atri.curtin.edu.au> 00010 * 00011 * Adapted for Audacious by John Lindgren, 2010-2011 00012 */ 00013 00014 #include <glib.h> 00015 #include <math.h> 00016 #include <pthread.h> 00017 #include <string.h> 00018 00019 #include <libaudcore/audstrings.h> 00020 #include <libaudcore/hook.h> 00021 00022 #include "equalizer.h" 00023 #include "misc.h" 00024 #include "types.h" 00025 00026 #define EQ_BANDS AUD_EQUALIZER_NBANDS 00027 #define MAX_CHANNELS 10 00028 00029 /* Q value for band-pass filters 1.2247 = (3/2)^(1/2) 00030 * Gives 4 dB suppression at Fc*2 and Fc/2 */ 00031 #define Q 1.2247449 00032 00033 /* Center frequencies for band-pass filters (Hz) */ 00034 /* These are not the historical WinAmp frequencies, because the IIR filters used 00035 * here are designed for each frequency to be twice the previous. Using WinAmp 00036 * frequencies leads to too much gain in some bands and too little in others. */ 00037 static const float CF[EQ_BANDS] = {31.25, 62.5, 125, 250, 500, 1000, 2000, 00038 4000, 8000, 16000}; 00039 00040 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 00041 static bool_t active; 00042 static int channels, rate; 00043 static float a[EQ_BANDS][2]; /* A weights */ 00044 static float b[EQ_BANDS][2]; /* B weights */ 00045 static float wqv[MAX_CHANNELS][EQ_BANDS][2]; /* Circular buffer for W data */ 00046 static float gv[MAX_CHANNELS][EQ_BANDS]; /* Gain factor for each channel and band */ 00047 static int K; /* Number of used eq bands */ 00048 00049 /* 2nd order band-pass filter design */ 00050 static void bp2 (float * a, float * b, float fc, float q) 00051 { 00052 float th = 2 * M_PI * fc; 00053 float C = (1 - tanf (th * q / 2)) / (1 + tanf (th * q / 2)); 00054 00055 a[0] = (1 + C) * cosf (th); 00056 a[1] = -C; 00057 b[0] = (1 - C) / 2; 00058 b[1] = -1.005; 00059 } 00060 00061 void eq_set_format (int new_channels, int new_rate) 00062 { 00063 int k; 00064 00065 pthread_mutex_lock (& mutex); 00066 00067 channels = new_channels; 00068 rate = new_rate; 00069 00070 /* Calculate number of active filters */ 00071 K = EQ_BANDS; 00072 00073 while (CF[K - 1] > (float) rate / 2.2) 00074 K --; 00075 00076 /* Generate filter taps */ 00077 for (k = 0; k < K; k ++) 00078 bp2 (a[k], b[k], CF[k] / (float) rate, Q); 00079 00080 /* Reset state */ 00081 memset (wqv[0][0], 0, sizeof wqv); 00082 00083 pthread_mutex_unlock (& mutex); 00084 } 00085 00086 static void eq_set_bands_real (double preamp, double * values) 00087 { 00088 float adj[EQ_BANDS]; 00089 for (int i = 0; i < EQ_BANDS; i ++) 00090 adj[i] = preamp + values[i]; 00091 00092 for (int c = 0; c < MAX_CHANNELS; c ++) 00093 for (int i = 0; i < EQ_BANDS; i ++) 00094 gv[c][i] = pow (10, adj[i] / 20) - 1; 00095 } 00096 00097 void eq_filter (float * data, int samples) 00098 { 00099 int channel; 00100 00101 pthread_mutex_lock (& mutex); 00102 00103 if (! active) 00104 { 00105 pthread_mutex_unlock (& mutex); 00106 return; 00107 } 00108 00109 for (channel = 0; channel < channels; channel ++) 00110 { 00111 float * g = gv[channel]; /* Gain factor */ 00112 float * end = data + samples; 00113 float * f; 00114 00115 for (f = data + channel; f < end; f += channels) 00116 { 00117 int k; /* Frequency band index */ 00118 float yt = * f; /* Current input sample */ 00119 00120 for (k = 0; k < K; k ++) 00121 { 00122 /* Pointer to circular buffer wq */ 00123 float * wq = wqv[channel][k]; 00124 /* Calculate output from AR part of current filter */ 00125 float w = yt * b[k][0] + wq[0] * a[k][0] + wq[1] * a[k][1]; 00126 00127 /* Calculate output from MA part of current filter */ 00128 yt += (w + wq[1] * b[k][1]) * g[k]; 00129 00130 /* Update circular buffer */ 00131 wq[1] = wq[0]; 00132 wq[0] = w; 00133 } 00134 00135 /* Calculate output */ 00136 * f = yt; 00137 } 00138 } 00139 00140 pthread_mutex_unlock (& mutex); 00141 } 00142 00143 static void eq_update (void * data, void * user) 00144 { 00145 pthread_mutex_lock (& mutex); 00146 00147 active = get_bool (NULL, "equalizer_active"); 00148 00149 double values[EQ_BANDS]; 00150 eq_get_bands (values); 00151 eq_set_bands_real (get_double (NULL, "equalizer_preamp"), values); 00152 00153 pthread_mutex_unlock (& mutex); 00154 } 00155 00156 void eq_init (void) 00157 { 00158 eq_update (NULL, NULL); 00159 hook_associate ("set equalizer_active", eq_update, NULL); 00160 hook_associate ("set equalizer_preamp", eq_update, NULL); 00161 hook_associate ("set equalizer_bands", eq_update, NULL); 00162 } 00163 00164 void eq_cleanup (void) 00165 { 00166 hook_dissociate ("set equalizer_active", eq_update); 00167 hook_dissociate ("set equalizer_preamp", eq_update); 00168 hook_dissociate ("set equalizer_bands", eq_update); 00169 } 00170 00171 void eq_set_bands (const double * values) 00172 { 00173 char * string = double_array_to_string (values, EQ_BANDS); 00174 g_return_if_fail (string); 00175 set_string (NULL, "equalizer_bands", string); 00176 g_free (string); 00177 } 00178 00179 void eq_get_bands (double * values) 00180 { 00181 memset (values, 0, sizeof (double) * EQ_BANDS); 00182 char * string = get_string (NULL, "equalizer_bands"); 00183 string_to_double_array (string, values, EQ_BANDS); 00184 g_free (string); 00185 } 00186 00187 void eq_set_band (int band, double value) 00188 { 00189 g_return_if_fail (band >= 0 && band < EQ_BANDS); 00190 double values[EQ_BANDS]; 00191 eq_get_bands (values); 00192 values[band] = value; 00193 eq_set_bands (values); 00194 } 00195 00196 double eq_get_band (int band) 00197 { 00198 g_return_val_if_fail (band >= 0 && band < EQ_BANDS, 0); 00199 double values[EQ_BANDS]; 00200 eq_get_bands (values); 00201 return values[band]; 00202 }