数字音乐均衡器

很多音乐播放软件都有均衡器,例如千千静听的数字均衡器效果如下:

这是一个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段的数字均衡器,并且可方便移植到任何嵌入式设备上的完整解决方案。

posted @ 2013-03-09 11:35  celerychen  阅读(907)  评论(0编辑  收藏  举报