参数均衡器(PEQ)制作指南(一)


前言

在我们日常生活中,音频设备已经无处不在,从手机到电视,从电脑到汽车,它们都有一个共同的特点,那就是都有音频输出。为了让音频输出更加符合我们的听觉习惯,或者说更加悦耳,我们通常会使用一种被称为“均衡器”的设备或软件来调整音频信号的频率响应。
均衡器可以分为固定频率均衡器(EQ)和参数化均衡器(PEQ)两种。
固定频率均衡器是最早出现的均衡器类型,它的工作原理相对简单,但调整范围有限。如下图:
网易云均衡器
参数均衡器(PEQ)则是一种更先进的技术,它不仅可以调整特定频率的增益,还可以调整中心频率和带宽,因此可以更精细地控制音频信号的频率响应。如下图:
海贝音乐参数化均衡器


一、参数均衡器(PEQ)如何实现?

1.数字双二阶滤波器

参数化均衡器(PEQ)本质上是一个滤波器。为了能在终端实现高效的处理,我们一般使用IIR滤波器来实现,也就是数字双二阶滤波器(digital biquad filter )是一种二阶递归线性滤波器,它包含两个极点和两个零点。"Biquad"是"biquadratic"的缩写,它指的是在Z域中,其传递函数是两个二次函数的比值。
H ( z ) = b 0 + b 1 z − 1 + b 2 z − 2 a 0 + a 1 z − 1 + a 2 z − 2 H(z) = \frac{b_0 + b_1 z^{-1} + b_2 z^{-2}}{a_0 + a_1 z^{-1} + a_2 z^{-2}} H(z)=a0+a1z1+a2z2b0+b1z1+b2z2
系数通常被归一化,分子分母同时除以 a 0 a_0 a0重新计算系数,使得 a 0 = 1 a_0 = 1 a0=1
H ( z ) = b 0 + b 1 z − 1 + b 2 z − 2 1 + a 1 z − 1 + a 2 z − 2 H(z) = \frac{b_0 + b_1 z^{-1} + b_2 z^{-2}}{1 + a_1 z^{-1} + a_2 z^{-2}} H(z)=1+a1z1+a2z2b0+b1z1+b2z2
把上面的公式切换为时域表示:
y ( n ) = b 0 ∗ x ( n ) + b 1 ∗ x ( n − 1 ) + b 2 ∗ x ( n − 2 ) − a 1 ∗ y ( n − 1 ) − a 2 ∗ y ( n − 2 ) y(n) = b_0*x(n) + b_1*x(n-1) + b_2*x(n-2) - a_1*y(n-1) - a_2*y(n-2) y(n)=b0x(n)+b1x(n1)+b2x(n2)a1y(n1)a2y(n2)
x ( n ) x(n) x(n)是当前输入的音频数据,
x ( n − 1 ) x(n-1) x(n1)是前一个时刻的输入的音频数据,
x ( n − 2 ) x(n-2) x(n2)是前第二个时刻输入的音频数据

y ( n ) y(n) y(n)是当前输出音频中的数据,
y ( n − 1 ) y(n-1) y(n1)是前一个时刻的输出的音频数据,
y ( n − 2 ) y(n-2) y(n2)是前第二个时刻输出的音频数据
b 0 , b 1 , b 2 , a 1 , a 2 b_0,b_1,b_2,a_1,a_2 b0,b1,b2,a1,a2这五个数就是滤波器系数。
高阶无限脉冲响应滤波器对其系数的量化非常敏感,很容易变得不稳定。这对一阶和二阶滤波器来说问题要小得多;因此,高阶滤波器通常实现为串联级联的双二阶段(如果需要的话,还有一个一阶滤波器)。双二阶滤波器的两个极点必须在单位圆内才能保持稳定。一般来说,这对所有离散滤波器都是成立的,即所有的极点必须在Z域的单位圆内,滤波器才能保持稳定。
双二阶滤波器在直接形式中的流程图:滤波器流程图

2.自定义参数

接下来我会详细介绍在PEQ中常见的滤波器类型,以及每种滤波器该如何计算滤波器系数。在此之前需要先介绍用户输入的自定义参数。

符号表示
F s F_s Fs采样率
F 0 F_0 F0“中心频率"或"角频率”,滤波器需要修改的频率点
d B g a i n dBgain dBgain增益

Q Q Q or B W BW BW or S S S(控制滤波器影响范围的参数):

符号表示
Q Q Q Q Q Q值是用来定义受到提升影响的频率范围的宽窄的,其描述了提升或者衰减的频率范围,其实就是带宽。 Q Q Q值越大,曲线越窄,影响范围越小; Q Q Q值越小,曲线越宽,影响范围越大。 Q Q Q值的含义,就是中心频率/带宽。
B W BW BW带宽是指从中心频率两边受到的提升或者衰减的影响,刚好比中心频率对应的幅值少变化3dB的两个频率之差。带宽也即是以中心频率为基准,左右延伸至增益下降或增加到3dB的位置
S S S主要应用在高低切滤波器。当 S = 1 S = 1 S=1时,高低切滤波器斜率尽可能陡峭,并且随着频率单调增加或减少。高低切斜率,以dB/八度音阶为单位,对于固定的 F 0 / F F_0/F F0/F和dBgain,保持与 S S S成比例。

二、计算滤波器系数

1.中间变量的计算

  • 1. A = 1 0 d B g a i n 20 = 1 0 d B g a i n 40 1.A = \sqrt{10^{\frac{dBgain}{20}}} = 10^{\frac{dBgain}{40}} 1.A=1020dBgain =1040dBgain

  • 2. ω 0 = 2 π ( f 0 F s ) 2.\omega_0 = 2\pi \left(\frac{f_0}{F_s}\right) 2.ω0=2π(Fsf0)

  • 3. α = sin ⁡ ω 0 2 Q ( c a s e : Q ) 3. \alpha = \frac{\sin \omega_0}{2Q} \qquad(case:Q) 3.α=2Qsinω0(case:Q)

  • α = sin ⁡ ω 0 sinh ⁡ ( log ⁡ 2 2 ⋅ B W ⋅ ω 0 sin ⁡ ω 0 ) ( c a s e : B W ) \alpha = \sin \omega_0 \sinh\left(\frac{\log 2}{2} \cdot BW\cdot\frac{\omega_0}{\sin \omega_0}\right)\qquad(case:BW) α=sinω0sinh(2log2BWsinω0ω0)(case:BW)

  • α = sin ⁡ ω 0 2 ( A + 1 A ) ( 1 S − 1 ) + 2 ( c a s e : S ) \alpha = \frac{\sin \omega_0}{2} \sqrt{ \left( A + \frac{1}{A} \right)\left(\frac{1}{S} - 1\right) + 2 }\qquad(case:S) α=2sinω0(A+A1)(S11)+2 (case:S)
    其中带宽 B W BW BW Q Q Q值的关系:

  • 1 Q = 2 sinh ⁡ ( log ⁡ 2 2 ⋅ B W ⋅ ω 0 sin ⁡ ω 0 ) = 2 sinh ⁡ ( log ⁡ 2 2 ⋅ B W ) \frac{1}{Q} = 2 \sinh \left( \frac{\log_2}{2} \cdot BW \cdot \frac{\omega_0}{\sin\omega_0}\right) = 2 \sinh\left( \frac{\log_2}{2} \cdot BW\right) Q1=2sinh(2log2BWsinω0ω0)=2sinh(2log2BW)

其中 S S S值和 Q Q Q值的关系:

  • 1 Q = ( A + 1 A ) ( 1 S − 1 ) + 2 \frac{1}{Q} = \sqrt{ \left( A + \frac{1}{A} \right)\left(\frac{1}{S} - 1\right) + 2 } Q1=(A+A1)(S11)+2
  • 2 A = ( sin ⁡ ω 0 ) ( A 2 + 1 ) ( 1 S − 1 ) + 2 A 2\sqrt{A} = (\sin\omega_0)\sqrt{\left(A^2 +1\right) \left(\frac{1}{S} - 1\right)+ 2A} 2A =(sinω0)(A2+1)(S11)+2A

2.常见滤波器类型

参数均衡器主要使用的滤波器类型包括:低通滤波器(LPF)、高通滤波器(HPF)、带通滤波器(BPF)、陷波滤波器(Notch)、全通滤波器(APF) 、低架滤波器(lowShelf)、高架滤波器(highShelf)、峰值滤波器(PF)。

2.1 低通滤波器

H ( s ) = 1 s 2 + s Q + 1 H(s) = \frac{1}{s^2 + \frac{s}{Q} + 1} H(s)=s2+Qs+11
系数的计算方式:

  • b 0 = 1 − cos ⁡ ω 0 2 b_0 = \frac{1 - \cos \omega_0}{2} b0=21cosω0
  • b 1 = 1 − cos ⁡ ω 0 b_1 = 1 - \cos \omega_0 b1=1cosω0
  • b 2 = 1 − cos ⁡ ω 0 2 b_2 = \frac{1 - \cos \omega_0}{2} b2=21cosω0
  • a 0 = 1 + α a_0 = 1 + \alpha a0=1+α
  • a 1 = − 2 cos ⁡ ω 0 a_1 = -2\cos \omega_0 a1=2cosω0
  • a 2 = 1 − α a_2 = 1 - \alpha a2=1α

2.2 高通滤波器

H ( s ) = s 2 s 2 + s Q + 1 H(s) = \frac{s^2}{s^2 + \frac{s}{Q} + 1} H(s)=s2+Qs+1s2
系数的计算方式:

  • b 0 = 1 + cos ⁡ ω 0 2 b_0 = \frac{1 + \cos \omega_0}{2} b0=21+cosω0
  • b 1 = − ( 1 + cos ⁡ ω 0 ) b_1 = - (1 + \cos \omega_0) b1=(1+cosω0)
  • b 2 = 1 + cos ⁡ ω 0 2 b_2 = \frac{1 + \cos \omega_0}{2} b2=21+cosω0
  • a 0 = 1 + α a_0 = 1 + \alpha a0=1+α
  • a 1 = − 2 cos ⁡ ω 0 a_1 = -2\cos\omega_0 a1=2cosω0
  • a 2 = 1 − α a_2 = 1 - \alpha a2=1α

2.3 带通滤波器

H ( s ) = s / Q s 2 + s / Q + 1 H(s) = \frac{s/Q}{s^2 + s/Q + 1} H(s)=s2+s/Q+1s/Q
系数的计算方式:

  • b 0 = α b_0 = \alpha b0=α
  • b 1 = 0 b_1 = 0 b1=0
  • b 2 = − α b_2 = -\alpha b2=α
  • a 0 = 1 + α a_0 = 1 + \alpha a0=1+α
  • a 1 = − 2 cos ⁡ ω 0 a_1 = -2\cos\omega_0 a1=2cosω0
  • a 2 = 1 − α a_2 = 1 - \alpha a2=1α

2.4 陷波滤波器

H ( s ) = s 2 + 1 s 2 + s Q + 1 H(s) = \frac{s^2 + 1}{s^2 + \frac{s}{Q} + 1} H(s)=s2+Qs+1s2+1
系数的计算方式:

  • b 0 = 1 b_0 = 1 b0=1
  • b 1 = − 2 cos ⁡ ω 0 b_1 = -2 \cos\omega_0 b1=2cosω0
  • b 2 = 1 b_2 = 1 b2=1
  • a 0 = 1 + α a_0 = 1 + \alpha a0=1+α
  • a 1 = − 2 cos ⁡ ω 0 a_1 = -2 \cos\omega_0 a1=2cosω0
  • a 2 = 1 − α a_2 = 1 - \alpha a2=1α

2.5 全通滤波器

H ( s ) = s 2 − s Q + 1 s 2 + s Q + 1 H(s) = \frac{s^2 - \frac{s}{Q} + 1}{s^2 + \frac{s}{Q} + 1} H(s)=s2+Qs+1s2Qs+1
系数的计算方式:

  • b 0 = 1 b_0 = 1 b0=1
  • b 1 = − 2 cos ⁡ ω 0 b_1 = -2 \cos\omega_0 b1=2cosω0
  • b 2 = 1 + α b_2 = 1 + \alpha b2=1+α
  • a 0 = 1 a_0 = 1 a0=1
  • a 1 = − 2 cos ⁡ ω 0 a_1 = -2 \cos\omega_0 a1=2cosω0
  • a 2 = 1 − α a_2 = 1-\alpha a2=1α

2.5 峰值滤波器

H ( s ) = s 2 + A Q s + 1 s 2 + s A Q + 1 H(s) = \frac{s^2 + \frac{A}{Q}s + 1}{s^2 + \frac{s}{AQ} + 1} H(s)=s2+AQs+1s2+QAs+1
系数的计算方式:

  • b 0 = 1 + α A b_0 = 1 + \alpha A b0=1+αA
  • b 1 = − 2 cos ⁡ ω b_1 = -2 \cos \omega b1=2cosω
  • b 2 = 1 − α A b_2 = 1 - \alpha A b2=1αA
  • a 0 = 1 + α A a_0 = 1 + \frac{\alpha}{A} a0=1+Aα
  • a 1 = − 2 cos ⁡ ω a_1 = -2 \cos \omega a1=2cosω
  • a 2 = 1 − α A a_2 = 1 - \frac{\alpha}{A} a2=1Aα

2.6 低架滤波器

H ( s ) = A s 2 + A Q s + 1 A s 2 + A Q s + 1 H(s) = A\frac{s^2 + \frac{\sqrt{A}}{Q}s + 1}{As^2 +\frac{\sqrt{A}}{Q}s + 1} H(s)=AAs2+QA s+1s2+QA s+1
系数的计算方式:

  • b 0 = A ( ( A + 1 ) − ( A − 1 ) cos ⁡ ω 0 + 2 A α ) b_0 = A ((A + 1) - (A - 1) \cos\omega_0 + 2\sqrt{A} \alpha) b0=A((A+1)(A1)cosω0+2A α)
  • b 1 = 2 A ( ( A − 1 ) − ( A + 1 ) cos ⁡ ω 0 ) b_1 = 2A((A - 1) - (A + 1) \cos\omega_0) b1=2A((A1)(A+1)cosω0)
  • b 2 = A ( ( A + 1 ) − ( A − 1 ) cos ⁡ ω 0 − 2 A α ) b_2 = A ((A + 1) - (A - 1) \cos\omega_0 - 2\sqrt{A} \alpha) b2=A((A+1)(A1)cosω02A α)
  • a 0 = ( A + 1 ) + ( A − 1 ) cos ⁡ ( ω 0 ) + 2 A α a_0 = (A + 1) + (A - 1) \cos(\omega_0) + 2\sqrt{A} \alpha a0=(A+1)+(A1)cos(ω0)+2A α
  • a 1 = − 2 ( ( A − 1 ) + ( A + 1 ) cos ⁡ ( ω 0 ) ) a_1 = -2 ((A - 1) + (A + 1) \cos(\omega_0)) a1=2((A1)+(A+1)cos(ω0))
  • a 2 = ( A + 1 ) + ( A − 1 ) cos ⁡ ( ω 0 ) − 2 A α a_2 = (A + 1) + (A - 1) \cos(\omega_0) - 2\sqrt{A} \alpha a2=(A+1)+(A1)cos(ω0)2A α

2.7 高架滤波器

H ( s ) = A A s 2 + A Q s + 1 s 2 + A Q s + A H(s) = A \frac{As^2 + \frac{\sqrt{A}}{Q}s + 1}{s^2 + \frac{\sqrt{A}}{Q}s + A} H(s)=As2+QA s+AAs2+QA s+1
系数的计算方式:

  • b 0 = A ( ( A + 1 ) + ( A − 1 ) cos ⁡ ω 0 + 2 A α ) b_0 = A ((A + 1) + (A - 1) \cos\omega_0+ 2\sqrt{A} \alpha) b0=A((A+1)+(A1)cosω0+2A α)
  • b 1 = − 2 A ( ( A − 1 ) + ( A + 1 ) cos ⁡ ω 0 ) b_1 = -2A((A - 1)+ (A + 1) \cos\omega_0) b1=2A((A1)+(A+1)cosω0)
  • b 2 = A ( ( A + 1 ) + ( A − 1 ) cos ⁡ ω 0 − 2 A α ) b_2 = A ((A + 1) +(A - 1) \cos\omega_0 - 2\sqrt{A} \alpha) b2=A((A+1)+(A1)cosω02A α)
  • a 0 = ( A + 1 ) − ( A − 1 ) cos ⁡ ω 0 + 2 A α a_0 = (A + 1) - (A - 1) \cos\omega_0 + 2\sqrt{A} \alpha a0=(A+1)(A1)cosω0+2A α
  • a 1 = 2 ( ( A − 1 ) − ( A + 1 ) cos ⁡ ω 0 ) a_1 = 2 ((A - 1) - (A + 1) \cos\omega_0) a1=2((A1)(A+1)cosω0)
  • a 2 = ( A + 1 ) − ( A − 1 ) cos ⁡ ω 0 − 2 A α a_2 = (A + 1) - (A - 1) \cos\omega_0- 2\sqrt{A} \alpha a2=(A+1)(A1)cosω02A α

三、C++实现

代码源自开源软件EqualizerAPO-src-1.3.2

BiQuad.cpp


#include "BiQuad.h"

#include "BiQuad.h"

#define _USE_MATH_DEFINES
#include <cmath>
#include <climits>
#include <cstdarg>
#include <cstdio>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <exception>
#include <unordered_map>
#include <unordered_set>
#include <regex>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Shlwapi.h>
#include <Ks.h>
#include <KsMedia.h>
 
using namespace std;
 
// 构造函数:初始化BiQuad滤波器
BiQuad::BiQuad(Type type, double dbGain, double freq, double srate, double bandwidthOrQOrS, bool isBandwidthOrS)
{
    // 计算增益因子A
    double A;
    if (type == PEAKING || type == LOW_SHELF || type == HIGH_SHELF)
        A = pow(10, dbGain / 40); // 对于这些类型,增益因子A使用dbGain/40计算
    else
        A = pow(10, dbGain / 20); // 对于其他类型,增益因子A使用dbGain/20计算
 
    // 计算omega, sn, cs
    double omega = 2 * M_PI * freq / srate; // 角频率
    double sn = sin(omega);                // 正弦
    double cs = cos(omega);                // 余弦
    double alpha;                          // 滤波器带宽因子
 
    // 根据带宽或Q因子或斜率来计算alpha
    if (!isBandwidthOrS) // Q
        alpha = sn / (2 * bandwidthOrQOrS);
    else if (type == LOW_SHELF || type == HIGH_SHELF) // S
        alpha = sn / 2 * sqrt((A + 1 / A) * (1 / bandwidthOrQOrS - 1) + 2);
    else // 带宽
        alpha = sn * sinh(M_LN2 / 2 * bandwidthOrQOrS * omega / sn);
 
    double beta = 2 * sqrt(A) * alpha; // 用于计算低架和高架滤波器系数的中间值
 
    // 定义滤波器系数
    double b0, b1, b2, a0, a1, a2;
 
    // 根据滤波器类型选择不同的系数公式
    switch (type)
    {
    case LOW_PASS:
        b0 = (1 - cs) / 2;
        b1 = 1 - cs;
        b2 = (1 - cs) / 2;
        a0 = 1 + alpha;
        a1 = -2 * cs;
        a2 = 1 - alpha;
        break;
    case HIGH_PASS:
        b0 = (1 + cs) / 2;
        b1 = -(1 + cs);
        b2 = (1 + cs) / 2;
        a0 = 1 + alpha;
        a1 = -2 * cs;
        a2 = 1 - alpha;
        break;
    case BAND_PASS:
        b0 = alpha;
        b1 = 0;
        b2 = -alpha;
        a0 = 1 + alpha;
        a1 = -2 * cs;
        a2 = 1 - alpha;
        break;
    case NOTCH:
        b0 = 1;
        b1 = -2 * cs;
        b2 = 1;
        a0 = 1 + alpha;
        a1 = -2 * cs;
        a2 = 1 - alpha;
        break;
    case ALL_PASS:
        b0 = 1 - alpha;
        b1 = -2 * cs;
        b2 = 1 + alpha;
        a0 = 1 + alpha;
        a1 = -2 * cs;
        a2 = 1 - alpha;
        break;
    case PEAKING:
        b0 = 1 + (alpha * A);
        b1 = -2 * cs;
        b2 = 1 - (alpha * A);
        a0 = 1 + (alpha / A);
        a1 = -2 * cs;
        a2 = 1 - (alpha / A);
        break;
    case LOW_SHELF:
        b0 = A * ((A + 1) - (A - 1) * cs + beta);
        b1 = 2 * A * ((A - 1) - (A + 1) * cs);
        b2 = A * ((A + 1) - (A - 1) * cs - beta);
        a0 = (A + 1) + (A - 1) * cs + beta;
        a1 = -2 * ((A - 1) + (A + 1) * cs);
        a2 = (A + 1) + (A - 1) * cs - beta;
        break;
    case HIGH_SHELF:
        b0 = A * ((A + 1) + (A - 1) * cs + beta);
        b1 = -2 * A * ((A - 1) + (A + 1) * cs);
        b2 = A * ((A + 1) + (A - 1) * cs - beta);
        a0 = (A + 1) - (A - 1) * cs + beta;
        a1 = 2 * ((A - 1) - (A + 1) * cs);
        a2 = (A + 1) - (A - 1) * cs - beta;
        break;
    }
 
    // 规范化滤波器系数
    this->a0 = b0 / a0;
    this->a[0] = b1 / a0;
    this->a[1] = b2 / a0;
    this->a[2] = a1 / a0;
    this->a[3] = a2 / a0;
 
    // 初始化延迟线
    x1 = 0;
    x2 = 0;
    y1 = 0;
    y2 = 0;
}
 
// 计算给定频率下的增益
double BiQuad::gainAt(double freq, double srate)
{
    double omega = 2 * M_PI * freq / srate; // 角频率
    double sn = sin(omega / 2.0);           // 半角正弦
    double phi = sn * sn;                   // phi = sin^2(omega/2)
    
    // 获取滤波器系数
    double b0 = this->a0;
    double b1 = this->a[0];
    double b2 = this->a[1];
    double a0 = 1.0;
    double a1 = this->a[2];
    double a2 = this->a[3];
 
    // 计算dB增益
    double dbGain = 10 * log10(pow(b0 + b1 + b2, 2) - 4 * (b0 * b1 + 4 * b0 * b2 + b1 * b2) * phi + 16 * b0 * b2 * phi * phi)
        - 10 * log10(pow(a0 + a1 + a2, 2) - 4 * (a0 * a1 + 4 * a0 * a2 + a1 * a2) * phi + 16 * a0 * a2 * phi * phi);
 
    return dbGain; // 返回增益值
}

BiQuad.h

#pragma once  // 确保该文件在编译过程中只被包含一次

#define _USE_MATH_DEFINES  // 启用数学常数的定义,例如 M_PI
#include <cmath>  // 包含 cmath 库,用于数学函数和常数
#include <climits>  // 包含 climits 库,用于常数,如 DBL_MIN
#include <string>  // 包含 string 库,用于使用字符串类

#define IS_DENORMAL(d) (abs(d) < DBL_MIN)  // 宏定义,用于检查浮点数是否是反规范化数(非常接近于零)

// BiQuad 类用于实现二阶滤波器
class BiQuad
{
public:
    // 滤波器类型的枚举
    enum Type
    {
        LOW_PASS, HIGH_PASS, BAND_PASS, NOTCH, ALL_PASS, PEAKING, LOW_SHELF, HIGH_SHELF
    };

    // 默认构造函数
    BiQuad() {}

    // 带参数的构造函数,用于滤波器类型、增益、频率、采样率、带宽/Q/S以及指示使用带宽或S的标志
    BiQuad(Type type, double dbGain, double freq, double srate, double bandwidthOrQOrS, bool isBandwidthOrS);

    // 内联函数,用于去除反规范化值
    __forceinline
    void removeDenormals()
    {
        if (IS_DENORMAL(x1))
            x1 = 0.0;
        if (IS_DENORMAL(x2))
            x2 = 0.0;
        if (IS_DENORMAL(y1))
            y1 = 0.0;
        if (IS_DENORMAL(y2))
            y2 = 0.0;
    }

    // 内联函数,用于处理单个样本通过二阶滤波器
    __forceinline
    double process(double sample)
    {
        // 使用二阶滤波器方程计算输出样本
        // 改变加法的顺序以获得更好的流水线性能
        double result = a0 * sample + a[1] * x2 + a[0] * x1 - a[3] * y2 - a[2] * y1;

        // 更新状态变量
        x2 = x1;
        x1 = sample;

        y2 = y1;
        y1 = result;

        return result;  // 返回滤波后的样本
    }

    // 内联函数,用于设置滤波器系数
    __forceinline
    void setCoefficients(double ain[], const double& a0in)
    {
        // 将输入数组的系数复制到成员变量中
        for (int i = 0; i < 4; i++)
            a[i] = ain[i];
        a0 = a0in;  // 设置 a0 系数
    }

    // 计算在特定频率下的滤波器增益
    double gainAt(double freq, double srate);

private:
    __declspec(align(16)) double a[4];  // 滤波器系数,按16字节对齐以提高性能
    double a0;  // 滤波器系数 a0

    double x1, x2;  // 输入样本的状态变量
    double y1, y2;  // 输出样本的状态变量
};


总结

本章介绍了设计参数均衡器(PEQ)所要用到的理论知识。下节将在win11环境下构建一个可以作用在音频上的PEQ。
如有错误,欢迎在评论区中指出。

参考

1.A rewritten Java/JavaScript biquadratic filter designer
2.Cookbook formulae for audio equalizer biquad filter coefficients
3.【凌逆战】EQ 均衡器
4.EqualizerAPO-src-1.3.2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值