zoukankan      html  css  js  c++  java
  • 数字音乐均衡器

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

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

  • 相关阅读:
    leetcode Majority Element
    Missing Number 三种解法
    Effective C++学习笔记 chapter 1
    C++ 笔记
    三色排序
    归并排序-就地排序
    506,display有哪些值?说明他们的作用
    505,display,float,position之间的关系(有疑问)
    504,什么是FOUC?怎么避免
    503,display:none;与visibility:hidden;的区别
  • 原文地址:https://www.cnblogs.com/celerychen/p/2951276.html
Copyright © 2011-2022 走看看