annotate libaf/af_equalizer.c @ 33263:5f527a9a9521

Add an exit function. This function will allow performing clean-up operations. (MPlayer calls guiDone() before exiting, but only if the GUI has been initialized, i.e. if guiInit() has been called successfully. Any exit_player()/exit_player_with_rc() after GUI's cfg_read() until guiInit(), or any exit_player() during guiInit() itself will end the GUI without calling guiDone(). This exit function will at least handle abortions during guiInit() itself. It will be called twice in case of an guiExit() after GUI initialization - first directly, next by guiDone() via MPlayer's exit_player_with_rc().)
author ib
date Tue, 03 May 2011 12:19:22 +0000
parents 8fa2f43cb760
children a93891202051
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
28229
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
1 /*
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
2 * Equalizer filter, implementation of a 10 band time domain graphic
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
3 * equalizer using IIR filters. The IIR filters are implemented using a
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
4 * Direct Form II approach, but has been modified (b1 == 0 always) to
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
5 * save computation.
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
6 *
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
7 * Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
8 *
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
9 * This file is part of MPlayer.
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
10 *
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
11 * MPlayer is free software; you can redistribute it and/or modify
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
12 * it under the terms of the GNU General Public License as published by
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
13 * the Free Software Foundation; either version 2 of the License, or
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
14 * (at your option) any later version.
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
15 *
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
16 * MPlayer is distributed in the hope that it will be useful,
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
19 * GNU General Public License for more details.
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
20 *
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
21 * You should have received a copy of the GNU General Public License along
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
22 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
72d0b1444141 Replace informal license notices by standard license header
diego
parents: 24900
diff changeset
24 */
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
25
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
26 #include <stdio.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
27 #include <stdlib.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
28
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
29 #include <inttypes.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
30 #include <math.h>
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
31
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
32 #include "af.h"
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
33
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
34 #define L 2 // Storage for filter taps
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
35 #define KM 10 // Max number of bands
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
36
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
37 #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
38 gives 4dB suppression @ Fc*2 and Fc/2 */
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
39
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
40 /* Center frequencies for band-pass filters
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
41 The different frequency bands are:
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
42 nr. center frequency
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
43 0 31.25 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
44 1 62.50 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
45 2 125.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
46 3 250.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
47 4 500.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
48 5 1.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
49 6 2.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
50 7 4.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
51 8 8.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
52 9 16.00 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
53 */
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
54 #define CF {31.25,62.5,125,250,500,1000,2000,4000,8000,16000}
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
55
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
56 // Maximum and minimum gain for the bands
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
57 #define G_MAX +12.0
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
58 #define G_MIN -12.0
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
59
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
60 // Data for specific instances of this filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
61 typedef struct af_equalizer_s
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
62 {
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
63 float a[KM][L]; // A weights
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
64 float b[KM][L]; // B weights
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
65 float wq[AF_NCH][KM][L]; // Circular buffer for W data
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
66 float g[AF_NCH][KM]; // Gain factor for each channel and band
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
67 int K; // Number of used eq bands
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
68 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
69 float gain_factor; // applied at output to avoid clipping
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
70 } af_equalizer_t;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
71
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
72 // 2nd order Band-pass Filter design
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
73 static void bp2(float* a, float* b, float fc, float q){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
74 double th= 2.0 * M_PI * fc;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
75 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
76
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
77 a[0] = (1.0 + C) * cos(th);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
78 a[1] = -1 * C;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
79
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
80 b[0] = (1.0 - C)/2.0;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
81 b[1] = -1.0050;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
82 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
83
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
84 // Initialization and runtime control
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
85 static int control(struct af_instance_s* af, int cmd, void* arg)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
86 {
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
87 af_equalizer_t* s = (af_equalizer_t*)af->setup;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
88
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
89 switch(cmd){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
90 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
91 int k =0, i =0;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
92 float F[KM] = CF;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
93
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
94 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
95
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
96 // Sanity check
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
97 if(!arg) return AF_ERROR;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
98
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
99 af->data->rate = ((af_data_t*)arg)->rate;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
100 af->data->nch = ((af_data_t*)arg)->nch;
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 13602
diff changeset
101 af->data->format = AF_FORMAT_FLOAT_NE;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
102 af->data->bps = 4;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
103
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
104 // Calculate number of active filters
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
105 s->K=KM;
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
106 while(F[s->K-1] > (float)af->data->rate/2.2)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
107 s->K--;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
108
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
109 if(s->K != KM)
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
110 mp_msg(MSGT_AFILTER, MSGL_INFO, "[equalizer] Limiting the number of filters to"
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
111 " %i due to low sample rate.\n",s->K);
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
112
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
113 // Generate filter taps
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
114 for(k=0;k<s->K;k++)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
115 bp2(s->a[k],s->b[k],F[k]/((float)af->data->rate),Q);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
116
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
117 // 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
118 af->delay = 2 * af->data->nch * af->data->bps;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
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 // 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
121 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
122 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
123 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
124 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
125 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
126 }
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
127 }
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
128
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
129 s->gain_factor=log10(s->gain_factor + 1.0) * 20.0;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
130
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
131 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
132 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
133 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
134 }else{
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
135 s->gain_factor=1;
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
136 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
137
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
138 return af_test_output(af,arg);
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
139 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
140 case AF_CONTROL_COMMAND_LINE:{
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
141 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
142 int i,j;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
143 sscanf((char*)arg,"%f:%f:%f:%f:%f:%f:%f:%f:%f:%f", &g[0], &g[1],
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
144 &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
145 for(i=0;i<AF_NCH;i++){
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
146 for(j=0;j<KM;j++){
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
147 ((af_equalizer_t*)af->setup)->g[i][j] =
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
148 pow(10.0,clamp(g[j],G_MIN,G_MAX)/20.0)-1.0;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
149 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
150 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
151 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
152 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
153 case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET:{
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
154 float* gain = ((af_control_ext_t*)arg)->arg;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
155 int ch = ((af_control_ext_t*)arg)->ch;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
156 int k;
17774
30fa0638b78d We start with 0, so ch (channel number) == AF_NCH is invalid, too (not just >)
reimar
parents: 17068
diff changeset
157 if(ch >= AF_NCH || ch < 0)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
158 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
159
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
160 for(k = 0 ; k<KM ; k++)
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
161 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
162
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
163 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
164 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
165 case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_GET:{
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
166 float* gain = ((af_control_ext_t*)arg)->arg;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
167 int ch = ((af_control_ext_t*)arg)->ch;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
168 int k;
17774
30fa0638b78d We start with 0, so ch (channel number) == AF_NCH is invalid, too (not just >)
reimar
parents: 17068
diff changeset
169 if(ch >= AF_NCH || ch < 0)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
170 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
171
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
172 for(k = 0 ; k<KM ; k++)
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
173 gain[k] = log10(s->g[ch][k]+1.0) * 20.0;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
174
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
175 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
176 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
177 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
178 return AF_UNKNOWN;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
179 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
180
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
181 // Deallocate memory
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
182 static void uninit(struct af_instance_s* af)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
183 {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
184 free(af->data);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
185 free(af->setup);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
186 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
187
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
188 // Filter data through filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
189 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
190 {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
191 af_data_t* c = data; // Current working data
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
192 af_equalizer_t* s = (af_equalizer_t*)af->setup; // Setup
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
193 uint32_t ci = af->data->nch; // Index for channels
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
194 uint32_t nch = af->data->nch; // Number of channels
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
195
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
196 while(ci--){
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
197 float* g = s->g[ci]; // Gain factor
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
198 float* in = ((float*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
199 float* out = ((float*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
200 float* end = in + c->len/4; // Block loop end
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
201
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
202 while(in < end){
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 13602
diff changeset
203 register int k = 0; // Frequency band index
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
204 register float yt = *in; // Current input sample
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
205 in+=nch;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
206
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
207 // Run the filters
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
208 for(;k<s->K;k++){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
209 // Pointer to circular buffer wq
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
210 register float* wq = s->wq[ci][k];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
211 // Calculate output from AR part of current filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
212 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
213 // Calculate output form MA part of current filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
214 yt+=(w + wq[1]*s->b[k][1])*g[k];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
215 // Update circular buffer
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
216 wq[1] = wq[0];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
217 wq[0] = w;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
218 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
219 // Calculate output
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
220 *out=yt*s->gain_factor;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
221 out+=nch;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
222 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
223 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
224 return c;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
225 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
226
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
227 // 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
228 static int af_open(af_instance_t* af){
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
229 af->control=control;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
230 af->uninit=uninit;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
231 af->play=play;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 22748
diff changeset
232 af->mul=1;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
233 af->data=calloc(1,sizeof(af_data_t));
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
234 af->setup=calloc(1,sizeof(af_equalizer_t));
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
235 if(af->data == NULL || af->setup == NULL)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
236 return AF_ERROR;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
237 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
238 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
239
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
240 // Description of this filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
241 af_info_t af_info_equalizer = {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
242 "Equalizer audio filter",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
243 "equalizer",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
244 "Anders",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
245 "",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
246 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
247 af_open
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
248 };