annotate libaf/af_equalizer.c @ 25317:7f3cb5408f28

Fixed VIDIX color bug that was introduced when Radeon VIDIX driver was synchronized with vidix.sf.net. The red color was saturating. Corrected value fixes the issue and restore the color to the level it used to have before synchronization. Meaning of the value remains unknow but was retrieved from register's value of a Radeon 9000 card, so it may need further testing. Patch by Guillaume Lecerf (foxcore at gmail dot com)
author ben
date Mon, 10 Dec 2007 19:27:46 +0000
parents 9079c9745ff9
children 72d0b1444141
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
1 /*=============================================================================
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
2 //
13602
14090f7300a8 The full name of the GPL is GNU General Public License.
diego
parents: 8607
diff changeset
3 // This software has been released under the terms of the GNU General Public
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
4 // license. See http://www.gnu.org/copyleft/gpl.html for details.
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
5 //
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
6 // Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
7 //
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
8 //=============================================================================
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
9 */
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
10
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
11 /* Equalizer filter, implementation of a 10 band time domain graphic
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
12 equalizer using IIR filters. The IIR filters are implemented using a
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
13 Direct Form II approach, but has been modified (b1 == 0 always) to
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
14 save computation.
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
15 */
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
16
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
17 #include <stdio.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
18 #include <stdlib.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
19
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
20 #include <inttypes.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
21 #include <math.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
22
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
23 #include "af.h"
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
24
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
25 #define L 2 // Storage for filter taps
e8832e66babd New features:
anders
parents: 8073
diff changeset
26 #define KM 10 // Max number of bands
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
27
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
28 #define Q 1.2247449 /* Q value for band-pass filters 1.2247=(3/2)^(1/2)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
29 gives 4dB suppression @ Fc*2 and Fc/2 */
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
30
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
31 /* Center frequencies for band-pass filters
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
32 The different frequency bands are:
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
33 nr. center frequency
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
34 0 31.25 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
35 1 62.50 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
36 2 125.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
37 3 250.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
38 4 500.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
39 5 1.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
40 6 2.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
41 7 4.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
42 8 8.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
43 9 16.00 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
44 */
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
45 #define CF {31.25,62.5,125,250,500,1000,2000,4000,8000,16000}
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
46
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
47 // Maximum and minimum gain for the bands
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
48 #define G_MAX +12.0
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
49 #define G_MIN -12.0
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
50
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
51 // Data for specific instances of this filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
52 typedef struct af_equalizer_s
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
53 {
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
54 float a[KM][L]; // A weights
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
55 float b[KM][L]; // B weights
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
56 float wq[AF_NCH][KM][L]; // Circular buffer for W data
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
57 float g[AF_NCH][KM]; // Gain factor for each channel and band
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
58 int K; // Number of used eq bands
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
59 int channels; // Number of channels
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
60 float gain_factor; // applied at output to avoid clipping
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
61 } af_equalizer_t;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
62
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
63 // 2nd order Band-pass Filter design
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
64 static void bp2(float* a, float* b, float fc, float q){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
65 double th= 2.0 * M_PI * fc;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
66 double C = (1.0 - tan(th*q/2.0))/(1.0 + tan(th*q/2.0));
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
67
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
68 a[0] = (1.0 + C) * cos(th);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
69 a[1] = -1 * C;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
70
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
71 b[0] = (1.0 - C)/2.0;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
72 b[1] = -1.0050;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
73 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
74
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
75 // Initialization and runtime control
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
76 static int control(struct af_instance_s* af, int cmd, void* arg)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
77 {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
78 af_equalizer_t* s = (af_equalizer_t*)af->setup;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
79
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
80 switch(cmd){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
81 case AF_CONTROL_REINIT:{
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
82 int k =0, i =0;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
83 float F[KM] = CF;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
84
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
85 s->gain_factor=0.0;
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
86
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
87 // Sanity check
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
88 if(!arg) return AF_ERROR;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
89
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
90 af->data->rate = ((af_data_t*)arg)->rate;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
91 af->data->nch = ((af_data_t*)arg)->nch;
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 13602
diff changeset
92 af->data->format = AF_FORMAT_FLOAT_NE;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
93 af->data->bps = 4;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
94
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
95 // Calculate number of active filters
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
96 s->K=KM;
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
97 while(F[s->K-1] > (float)af->data->rate/2.2)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
98 s->K--;
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
99
e8832e66babd New features:
anders
parents: 8073
diff changeset
100 if(s->K != KM)
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
101 af_msg(AF_MSG_INFO,"[equalizer] Limiting the number of filters to"
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
102 " %i due to low sample rate.\n",s->K);
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
103
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
104 // Generate filter taps
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
105 for(k=0;k<s->K;k++)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
106 bp2(s->a[k],s->b[k],F[k]/((float)af->data->rate),Q);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
107
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
108 // Calculate how much this plugin adds to the overall time delay
24900
9079c9745ff9 A/V sync: take audio filter buffers into account
uau
parents: 24888
diff changeset
109 af->delay = 2 * af->data->nch * af->data->bps;
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
110
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
111 // Calculate gain factor to prevent clipping at output
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
112 for(k=0;k<AF_NCH;k++)
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
113 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
114 for(i=0;i<KM;i++)
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
115 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
116 if(s->gain_factor < s->g[k][i]) s->gain_factor=s->g[k][i];
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
117 }
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
118 }
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
119
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
120 s->gain_factor=log10(s->gain_factor + 1.0) * 20.0;
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
121
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
122 if(s->gain_factor > 0.0)
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
123 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
124 s->gain_factor=0.1+(s->gain_factor/12.0);
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
125 }else{
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
126 s->gain_factor=1;
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
127 }
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
128
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
129 return af_test_output(af,arg);
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
130 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
131 case AF_CONTROL_COMMAND_LINE:{
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
132 float g[10]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
133 int i,j;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
134 sscanf((char*)arg,"%f:%f:%f:%f:%f:%f:%f:%f:%f:%f", &g[0], &g[1],
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
135 &g[2], &g[3], &g[4], &g[5], &g[6], &g[7], &g[8] ,&g[9]);
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
136 for(i=0;i<AF_NCH;i++){
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
137 for(j=0;j<KM;j++){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
138 ((af_equalizer_t*)af->setup)->g[i][j] =
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
139 pow(10.0,clamp(g[j],G_MIN,G_MAX)/20.0)-1.0;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
140 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
141 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
142 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
143 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
144 case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET:{
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
145 float* gain = ((af_control_ext_t*)arg)->arg;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
146 int ch = ((af_control_ext_t*)arg)->ch;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
147 int k;
17774
30fa0638b78d We start with 0, so ch (channel number) == AF_NCH is invalid, too (not just >)
reimar
parents: 17068
diff changeset
148 if(ch >= AF_NCH || ch < 0)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
149 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
150
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
151 for(k = 0 ; k<KM ; k++)
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
152 s->g[ch][k] = pow(10.0,clamp(gain[k],G_MIN,G_MAX)/20.0)-1.0;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
153
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
154 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
155 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
156 case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_GET:{
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
157 float* gain = ((af_control_ext_t*)arg)->arg;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
158 int ch = ((af_control_ext_t*)arg)->ch;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
159 int k;
17774
30fa0638b78d We start with 0, so ch (channel number) == AF_NCH is invalid, too (not just >)
reimar
parents: 17068
diff changeset
160 if(ch >= AF_NCH || ch < 0)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
161 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
162
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
163 for(k = 0 ; k<KM ; k++)
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
164 gain[k] = log10(s->g[ch][k]+1.0) * 20.0;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
165
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
166 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
167 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
168 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
169 return AF_UNKNOWN;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
170 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
171
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
172 // Deallocate memory
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
173 static void uninit(struct af_instance_s* af)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
174 {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
175 if(af->data)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
176 free(af->data);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
177 if(af->setup)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
178 free(af->setup);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
179 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
180
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
181 // Filter data through filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
182 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
183 {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
184 af_data_t* c = data; // Current working data
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
185 af_equalizer_t* s = (af_equalizer_t*)af->setup; // Setup
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
186 uint32_t ci = af->data->nch; // Index for channels
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
187 uint32_t nch = af->data->nch; // Number of channels
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
188
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
189 while(ci--){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
190 float* g = s->g[ci]; // Gain factor
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
191 float* in = ((float*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
192 float* out = ((float*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
193 float* end = in + c->len/4; // Block loop end
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
194
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
195 while(in < end){
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 13602
diff changeset
196 register int k = 0; // Frequency band index
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
197 register float yt = *in; // Current input sample
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
198 in+=nch;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
199
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
200 // Run the filters
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
201 for(;k<s->K;k++){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
202 // Pointer to circular buffer wq
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
203 register float* wq = s->wq[ci][k];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
204 // Calculate output from AR part of current filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
205 register float w=yt*s->b[k][0] + wq[0]*s->a[k][0] + wq[1]*s->a[k][1];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
206 // Calculate output form MA part of current filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
207 yt+=(w + wq[1]*s->b[k][1])*g[k];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
208 // Update circular buffer
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
209 wq[1] = wq[0];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
210 wq[0] = w;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
211 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
212 // Calculate output
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
213 *out=yt*s->gain_factor;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
214 out+=nch;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
215 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
216 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
217 return c;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
218 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
219
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
220 // Allocate memory and set function pointers
22746
fd6f824ef894 Rename open to af_open so as not to conflict with a previous header definition.
diego
parents: 17812
diff changeset
221 static int af_open(af_instance_t* af){
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
222 af->control=control;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
223 af->uninit=uninit;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
224 af->play=play;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 22748
diff changeset
225 af->mul=1;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
226 af->data=calloc(1,sizeof(af_data_t));
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
227 af->setup=calloc(1,sizeof(af_equalizer_t));
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
228 if(af->data == NULL || af->setup == NULL)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
229 return AF_ERROR;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
230 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
231 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
232
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
233 // Description of this filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
234 af_info_t af_info_equalizer = {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
235 "Equalizer audio filter",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
236 "equalizer",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
237 "Anders",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
238 "",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
239 AF_FLAGS_NOT_REENTRANT,
22746
fd6f824ef894 Rename open to af_open so as not to conflict with a previous header definition.
diego
parents: 17812
diff changeset
240 af_open
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
241 };
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
242
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
243
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
244
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
245
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
246
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
247
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
248