annotate libaf/af_equalizer.c @ 36089:d4056035c260

Set file prior to adding to the URL list. An already existing URL list item won't be added, but the allocated url string will be freed (which thus can't be uiSetFile() nor be added to the playlist).
author ib
date Mon, 29 Apr 2013 12:10:03 +0000
parents a93891202051
children 2b9bc3c2933d
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
34174
a93891202051 Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents: 32537
diff changeset
32 #include "mp_msg.h"
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
33 #include "af.h"
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
34
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
35 #define L 2 // Storage for filter taps
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
36 #define KM 10 // Max number of bands
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
37
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
38 #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
39 gives 4dB suppression @ Fc*2 and Fc/2 */
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
40
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
41 /* Center frequencies for band-pass filters
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
42 The different frequency bands are:
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
43 nr. center frequency
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
44 0 31.25 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
45 1 62.50 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
46 2 125.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
47 3 250.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
48 4 500.0 Hz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
49 5 1.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
50 6 2.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
51 7 4.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
52 8 8.000 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
53 9 16.00 kHz
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
54 */
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
55 #define CF {31.25,62.5,125,250,500,1000,2000,4000,8000,16000}
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
56
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
57 // Maximum and minimum gain for the bands
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
58 #define G_MAX +12.0
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
59 #define G_MIN -12.0
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
60
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
61 // Data for specific instances of this filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
62 typedef struct af_equalizer_s
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
63 {
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
64 float a[KM][L]; // A weights
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
65 float b[KM][L]; // B weights
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
66 float wq[AF_NCH][KM][L]; // Circular buffer for W data
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
67 float g[AF_NCH][KM]; // Gain factor for each channel and band
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
68 int K; // Number of used eq bands
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
69 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
70 float gain_factor; // applied at output to avoid clipping
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
71 } af_equalizer_t;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
72
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
73 // 2nd order Band-pass Filter design
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
74 static void bp2(float* a, float* b, float fc, float q){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
75 double th= 2.0 * M_PI * fc;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
76 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
77
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
78 a[0] = (1.0 + C) * cos(th);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
79 a[1] = -1 * C;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
80
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
81 b[0] = (1.0 - C)/2.0;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
82 b[1] = -1.0050;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
83 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
84
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
85 // Initialization and runtime control
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
86 static int control(struct af_instance_s* af, int cmd, void* arg)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
87 {
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
88 af_equalizer_t* s = (af_equalizer_t*)af->setup;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
89
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
90 switch(cmd){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
91 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
92 int k =0, i =0;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
93 float F[KM] = CF;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
94
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
95 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
96
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
97 // Sanity check
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
98 if(!arg) return AF_ERROR;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
99
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
100 af->data->rate = ((af_data_t*)arg)->rate;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
101 af->data->nch = ((af_data_t*)arg)->nch;
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 13602
diff changeset
102 af->data->format = AF_FORMAT_FLOAT_NE;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
103 af->data->bps = 4;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
104
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
105 // Calculate number of active filters
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
106 s->K=KM;
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
107 while(F[s->K-1] > (float)af->data->rate/2.2)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
108 s->K--;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
109
8167
e8832e66babd New features:
anders
parents: 8073
diff changeset
110 if(s->K != KM)
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
111 mp_msg(MSGT_AFILTER, MSGL_INFO, "[equalizer] Limiting the number of filters to"
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
112 " %i due to low sample rate.\n",s->K);
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
113
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
114 // Generate filter taps
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
115 for(k=0;k<s->K;k++)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
116 bp2(s->a[k],s->b[k],F[k]/((float)af->data->rate),Q);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
117
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
118 // 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
119 af->delay = 2 * af->data->nch * af->data->bps;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
120
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
121 // 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
122 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
123 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
124 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
125 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
126 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
127 }
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
128 }
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
129
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
130 s->gain_factor=log10(s->gain_factor + 1.0) * 20.0;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
131
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
132 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
133 {
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
134 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
135 }else{
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
136 s->gain_factor=1;
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
137 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
138
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
139 return af_test_output(af,arg);
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
140 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
141 case AF_CONTROL_COMMAND_LINE:{
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
142 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
143 int i,j;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
144 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
145 &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
146 for(i=0;i<AF_NCH;i++){
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
147 for(j=0;j<KM;j++){
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
148 ((af_equalizer_t*)af->setup)->g[i][j] =
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
149 pow(10.0,clamp(g[j],G_MIN,G_MAX)/20.0)-1.0;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
150 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
151 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
152 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
153 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
154 case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET:{
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
155 float* gain = ((af_control_ext_t*)arg)->arg;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
156 int ch = ((af_control_ext_t*)arg)->ch;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
157 int k;
17774
30fa0638b78d We start with 0, so ch (channel number) == AF_NCH is invalid, too (not just >)
reimar
parents: 17068
diff changeset
158 if(ch >= AF_NCH || ch < 0)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
159 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
160
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
161 for(k = 0 ; k<KM ; k++)
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
162 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
163
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
164 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
165 }
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
166 case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_GET:{
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
167 float* gain = ((af_control_ext_t*)arg)->arg;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
168 int ch = ((af_control_ext_t*)arg)->ch;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
169 int k;
17774
30fa0638b78d We start with 0, so ch (channel number) == AF_NCH is invalid, too (not just >)
reimar
parents: 17068
diff changeset
170 if(ch >= AF_NCH || ch < 0)
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
171 return AF_ERROR;
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
172
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
173 for(k = 0 ; k<KM ; k++)
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
174 gain[k] = log10(s->g[ch][k]+1.0) * 20.0;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
175
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
176 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
177 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
178 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
179 return AF_UNKNOWN;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
180 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
181
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
182 // Deallocate memory
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
183 static void uninit(struct af_instance_s* af)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
184 {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
185 free(af->data);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
186 free(af->setup);
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
187 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
188
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
189 // Filter data through filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
190 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
191 {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
192 af_data_t* c = data; // Current working data
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
193 af_equalizer_t* s = (af_equalizer_t*)af->setup; // Setup
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
194 uint32_t ci = af->data->nch; // Index for channels
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
195 uint32_t nch = af->data->nch; // Number of channels
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
196
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
197 while(ci--){
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
198 float* g = s->g[ci]; // Gain factor
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
199 float* in = ((float*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
200 float* out = ((float*)c->audio)+ci;
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
201 float* end = in + c->len/4; // Block loop end
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
202
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
203 while(in < end){
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 13602
diff changeset
204 register int k = 0; // Frequency band index
8607
d6f40a06867b Changes includes:
anders
parents: 8167
diff changeset
205 register float yt = *in; // Current input sample
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
206 in+=nch;
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
207
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
208 // Run the filters
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
209 for(;k<s->K;k++){
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
210 // Pointer to circular buffer wq
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
211 register float* wq = s->wq[ci][k];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
212 // Calculate output from AR part of current filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
213 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
214 // Calculate output form MA part of current filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
215 yt+=(w + wq[1]*s->b[k][1])*g[k];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
216 // Update circular buffer
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
217 wq[1] = wq[0];
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
218 wq[0] = w;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
219 }
29263
0f1b5b68af32 whitespace cosmetics: Remove all trailing whitespace.
diego
parents: 29049
diff changeset
220 // Calculate output
17812
1ade5769c97b added dinamically calculated gain factor at output stage to avoid clipping on sane ranges
reynaldo
parents: 17774
diff changeset
221 *out=yt*s->gain_factor;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
222 out+=nch;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
223 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
224 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
225 return c;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
226 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
227
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
228 // 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
229 static int af_open(af_instance_t* af){
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
230 af->control=control;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
231 af->uninit=uninit;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
232 af->play=play;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 22748
diff changeset
233 af->mul=1;
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
234 af->data=calloc(1,sizeof(af_data_t));
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
235 af->setup=calloc(1,sizeof(af_equalizer_t));
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
236 if(af->data == NULL || af->setup == NULL)
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
237 return AF_ERROR;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
238 return AF_OK;
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
239 }
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
240
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
241 // Description of this filter
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
242 af_info_t af_info_equalizer = {
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
243 "Equalizer audio filter",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
244 "equalizer",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
245 "Anders",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
246 "",
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
247 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
248 af_open
8073
c0e556f9986b Adding equalizer filter + some cosmetics
anders
parents:
diff changeset
249 };