双线性变换法设计iir数字滤波器的代码
时间: 2023-07-23 13:32:21 浏览: 47
以下是使用双线性变换法设计IIR数字滤波器的C++代码示例:
```c++
#include <iostream>
#include <cmath>
using namespace std;
const double pi = 3.14159265358979323846;
// 双线性变换函数
void bilinear_transform(double b[], double a[], double num[], double den[], double fs, double fc, int order) {
double wc = 2 * pi * fc / fs;
double wcp = tan(wc / 2);
double a1 = 2 * fs - 2 * wcp;
double a2 = 2 * fs + 2 * wcp;
double b0 = 0, b1 = 0, b2 = 0, a0 = 0, a1z = 0, a2z = 0;
if (order == 1) {
b0 = b[0] / a[0];
b1 = b[1] / a[0];
a0 = 1;
a1z = a1 / a[0];
a2z = a2 / a[0];
} else if (order == 2) {
b0 = b[0] / a[0];
b1 = b[1] / a[0];
b2 = b[2] / a[0];
a0 = 1;
a1z = (a1 + sqrt(a1 * a1 - 4 * a2)) / 2 / a[0];
a2z = (a1 - sqrt(a1 * a1 - 4 * a2)) / 2 / a[0];
}
num[0] = b0;
num[1] = b1 * a1z;
num[2] = b2 * a2z;
den[0] = a0;
den[1] = -a1z;
den[2] = -a2z;
}
int main() {
double fs = 44100; // 采样率
double fc = 1000; // 截止频率
int order = 2; // 滤波器阶数
double b[] = {1, 0, 0}; // 分子系数
double a[] = {1, 0.1, 1}; // 分母系数
double num[3], den[3]; // 双线性变换后的系数
bilinear_transform(b, a, num, den, fs, fc, order);
cout << "双线性变换后的系数:" << endl;
cout << "b[0] = " << num[0] << endl;
cout << "b[1] = " << num[1] << endl;
cout << "b[2] = " << num[2] << endl;
cout << "a[0] = " << den[0] << endl;
cout << "a[1] = " << den[1] << endl;
cout << "a[2] = " << den[2] << endl;
return 0;
}
```
在这个例子中,我们使用了双线性变换来将模拟滤波器的系数转换为数字滤波器的系数。`fs` 和 `fc` 分别表示采样率和截止频率,`order` 表示滤波器的阶数,`b` 和 `a` 数组分别表示模拟滤波器的分子系数和分母系数。`num` 和 `den` 数组则表示双线性变换后的数字滤波器的分子系数和分母系数。
在函数 `bilinear_transform` 中,我们首先计算了截止频率的模拟角频率 `wc` 和双线性变换的参数 `wcp`,然后根据公式计算了双线性变换的系数。最后,将计算得到的系数存储到 `num` 和 `den` 数组中,并输出结果。
需要注意的是,在实际应用中,我们需要根据具体的滤波器类型和设计要求选择合适的阶数、截止频率和系数。同时,由于双线性变换会引入数字滤波器的频率响应失真和幅度响应非线性等问题,因此需要进行进一步的优化和校准。