c++实现巴特沃斯带通滤波器
时间: 2023-05-30 09:07:14 浏览: 133
巴特沃斯带通滤波器是一种常见的数字滤波器,它可以用于去除信号中的低频和高频噪声,保留信号中间的频率成分。这种滤波器的特点是,它可以在一定范围内通过调整滤波器的截止频率来控制滤波效果。
以下是一种基于C语言的巴特沃斯带通滤波器实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14159265358979323846
// 巴特沃斯带通滤波器结构体
typedef struct {
double *a; // 分母系数
double *b; // 分子系数
int order; // 滤波器阶数
double *x; // 输入信号
double *y; // 输出信号
double *z; // 中间变量
} butterworth_bp_filter;
// 初始化巴特沃斯带通滤波器
void init_butterworth_bp_filter(butterworth_bp_filter *filter, int order, double *a, double *b) {
filter->a = (double*)malloc((order+1)*sizeof(double));
filter->b = (double*)malloc((order+1)*sizeof(double));
filter->x = (double*)calloc(order+1, sizeof(double));
filter->y = (double*)calloc(order+1, sizeof(double));
filter->z = (double*)calloc(order+1, sizeof(double));
filter->order = order;
for (int i = 0; i <= order; i++) {
filter->a[i] = a[i];
filter->b[i] = b[i];
}
}
// 释放巴特沃斯带通滤波器所占用的内存
void release_butterworth_bp_filter(butterworth_bp_filter *filter) {
free(filter->a);
free(filter->b);
free(filter->x);
free(filter->y);
free(filter->z);
}
// 巴特沃斯带通滤波器的滤波函数
void butterworth_bp_filter_function(butterworth_bp_filter *filter, double *input, double *output, int len) {
for (int i = 0; i < len; i++) {
filter->x[0] = input[i];
filter->z[0] = filter->b[0] * filter->x[0];
for (int j = 1; j <= filter->order; j++) {
filter->z[j] = filter->b[j] * filter->x[j] - filter->a[j] * filter->z[j-1] + filter->z[j-1];
}
filter->y[0] = filter->z[0];
for (int j = 1; j <= filter->order; j++) {
filter->y[j] = filter->z[j] - filter->a[j] * filter->y[j-1];
}
output[i] = filter->y[filter->order];
for (int j = filter->order; j >= 1; j--) {
filter->x[j] = filter->x[j-1];
filter->y[j] = filter->y[j-1];
filter->z[j] = filter->z[j-1];
}
}
}
// 计算巴特沃斯带通滤波器的系数
void compute_butterworth_bp_filter_coefficients(int order, double *a, double *b, double fs, double f1, double f2) {
double omega1 = 2.0 * PI * f1 / fs;
double omega2 = 2.0 * PI * f2 / fs;
double c1 = cos(omega1);
double c2 = cos(omega2);
double s1 = sin(omega1);
double s2 = sin(omega2);
double k = tan((omega2 - omega1) / 2.0);
double k2 = k * k;
double w0 = omega1 * omega2 / k;
double w02 = w0 * w0;
double a0 = 1.0 + k / Q + k2;
a[0] = k2 / a0;
a[1] = 2.0 * k2 / a0;
a[2] = a[0];
b[0] = 1.0;
b[1] = -2.0 * c1 / a0;
b[2] = (1.0 - k / Q + k2) / a0;
}
int main() {
// 生成测试信号
double fs = 1000; // 采样频率
double f1 = 10; // 带通滤波器下限频率
double f2 = 50; // 带通滤波器上限频率
double T = 1.0 / fs;
int len = 1000;
double *input = (double*)malloc(len*sizeof(double));
double *output = (double*)malloc(len*sizeof(double));
for (int i = 0; i < len; i++) {
input[i] = sin(2.0*PI*20*i*T) + sin(2.0*PI*100*i*T) + 0.1*rand()/RAND_MAX;
}
// 计算滤波器系数
int order = 2; // 滤波器阶数
double *a = (double*)malloc((order+1)*sizeof(double));
double *b = (double*)malloc((order+1)*sizeof(double));
compute_butterworth_bp_filter_coefficients(order, a, b, fs, f1, f2);
// 初始化滤波器
butterworth_bp_filter filter;
init_butterworth_bp_filter(&filter, order, a, b);
// 滤波
butterworth_bp_filter_function(&filter, input, output, len);
// 输出结果
for (int i = 0; i < len; i++) {
printf("%f\n", output[i]);
}
// 释放内存
release_butterworth_bp_filter(&filter);
free(a);
free(b);
free(input);
free(output);
return 0;
}
```
在上面的代码中,我们首先生成了一个包含低频和高频噪声的测试信号,然后通过`compute_butterworth_bp_filter_coefficients`函数计算了滤波器的系数,接着调用`init_butterworth_bp_filter`函数初始化滤波器,最后调用`butterworth_bp_filter_function`函数对输入信号进行滤波,得到输出信号。
需要注意的是,巴特沃斯滤波器的阶数越高,滤波器的截止频率越陡峭,但同时也会导致滤波器的相位响应出现明显的延迟,因此在实际应用中需要根据具体情况进行选择。
相关推荐
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![application/pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![mp4](https://img-home.csdnimg.cn/images/20210720083504.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rpm](https://img-home.csdnimg.cn/images/20210720083646.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)