数字音乐均衡器
很多音乐播放软件都有均衡器,例如千千静听的数字均衡器效果如下:
这是一个10段均衡器。
均衡器实际上就是一组带通滤波器。对于学过数字信号处理的人,要设计这样一组滤波器并不是什么难事情。
这里我做了一个简单的均衡器,这个均衡器只有3段,即对低频,中频和高频进行调整。
1. 均衡器相关结构定义如下:
1 typedef struct
2 {
3 // Filter #1 (Low band)
4
5 double lf; // Frequency
6 double f1p0; // Poles ...
7 double f1p1;
8 double f1p2;
9 double f1p3;
10
11 // Filter #2 (High band)
12
13 double hf; // Frequency
14 double f2p0; // Poles ...
15 double f2p1;
16 double f2p2;
17 double f2p3;
18
19 // Sample history buffer
20
21 double sdm1; // Sample data minus 1
22 double sdm2; // 2
23 double sdm3; // 3
24
25 // Gain Controls
26
27 double lg; // low gain
28 double mg; // mid gain
29 double hg; // high gain
30
31 } EQSTATE;
2. 初始化均衡器的状态
1 void init_3band_state(EQSTATE* es, int lowfreq, int highfreq, int sample_rate)
2 {
3 // Clear state
4
5 memset(es,0,sizeof(EQSTATE));
6
7 // Set Low/Mid/High gains to unity
8
9 es->lg = 1.0;
10 es->mg = 1.0;
11 es->hg = 1.0;
12
13 // Calculate filter cutoff frequencies
14
15 es->lf = 2 * sin(M_PI * ((double)lowfreq / (double)sample_rate));
16 es->hf = 2 * sin(M_PI * ((double)highfreq / (double)sample_rate));
17 }
3. 执行滤波的过程
1 double do_3band(EQSTATE* es, double sample)
2 {
3 // Locals
4
5 double l,m,h; // Low / Mid / High - Sample Values
6
7 // Filter #1 (lowpass)
8
9 es->f1p0 += (es->lf * (sample - es->f1p0)) + vsa;
10 es->f1p1 += (es->lf * (es->f1p0 - es->f1p1));
11 es->f1p2 += (es->lf * (es->f1p1 - es->f1p2));
12 es->f1p3 += (es->lf * (es->f1p2 - es->f1p3));
13
14 l = es->f1p3;
15
16 // Filter #2 (highpass)
17
18 es->f2p0 += (es->hf * (sample - es->f2p0)) + vsa;
19 es->f2p1 += (es->hf * (es->f2p0 - es->f2p1));
20 es->f2p2 += (es->hf * (es->f2p1 - es->f2p2));
21 es->f2p3 += (es->hf * (es->f2p2 - es->f2p3));
22
23 h = es->sdm3 - es->f2p3;
24
25 // Calculate midrange (signal - (low + high))
26
27 m = es->sdm3 - (h + l);
28
29 // Scale, Combine and store
30
31 l *= es->lg;
32 m *= es->mg;
33 h *= es->hg;
34
35 // Shuffle history buffer
36
37 es->sdm3 = es->sdm2;
38 es->sdm2 = es->sdm1;
39 es->sdm1 = sample;
40
41 // Return result
42
43 return(l + m + h);
44 }
其中,变量 vsa 是一个很小很小的常数,也可以不加。
4. 使用上述代码。
4.1 定义一个均衡器的全局变量:
EQSTATE eq;
4.2 初始化均衡器,假定采样率为48k:
set_3band_state(eq,880,5000,48000);
这样,你的均衡器的频段如下:
low band = 0Hz to 880Hz
mid band = 880Hz to 5000Hz
high band = 5000Hz to 24000Hz
4.3 设定提升参数:
1 eq.lg = 1.5; // Boost bass by 50%
2 eq.mg = 0.75; // Cut mid by 25%
3 eq.hg = 1.0; // Leave high band alone
4.4 对每一个PCM样本,执行计算过程:
out_sample = do_3band(eq,in_sample);
上述代码仅仅是个很简单的均衡器。
在本人的项目当中,实现了更加精确高效的可商用均衡器,包括支持常用的采样率,更多高达31段的数字均衡器,并且可方便移植到任何嵌入式设备上的完整解决方案。