c++实现巴特沃斯带通滤波器代码
时间: 2023-06-02 08:01:31 浏览: 48
巴特沃斯带通滤波器是一种数字滤波器,它可以将指定范围内的频率信号通过,而将其他频率信号滤除。下面是一个C语言实现的巴特沃斯带通滤波器代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14159265358979323846
//定义结构体保存滤波器状态
typedef struct {
double *x; //输入数据数组
double *y; //输出数据数组
int n; //滤波器阶数
double *a; //分母系数
double *b; //分子系数
} ButterworthFilter;
//计算巴特沃斯带通滤波器系数
void butterworth_bandpass_coeff(int n, double f1, double f2, double fs, double *a, double *b)
{
double omega1 = 2 * PI * f1 / fs;
double omega2 = 2 * PI * f2 / fs;
double c1 = cos(omega1);
double s1 = sin(omega1);
double c2 = cos(omega2);
double s2 = sin(omega2);
double alpha = s1 * s2 / (c1 * c2);
double beta = 1 / tan((omega2 - omega1) / 2);
double gamma = (1 - alpha) / 2;
double a0 = 1 + alpha * beta + gamma * beta * beta;
double a1 = 2 * (gamma * beta * beta - 1);
double a2 = 1 - alpha * beta + gamma * beta * beta;
double b0 = gamma * beta * beta;
double b1 = 0;
double b2 = -gamma * beta * beta;
//归一化系数
double k = a0;
a[0] = a0 / k;
a[1] = a1 / k;
a[2] = a2 / k;
b[0] = b0 / k;
b[1] = b1 / k;
b[2] = b2 / k;
}
//初始化滤波器
void butterworth_filter_init(ButterworthFilter *filter, int n)
{
filter->n = n;
filter->a = (double *) malloc((n + 1) * sizeof(double));
filter->b = (double *) malloc((n + 1) * sizeof(double));
filter->x = (double *) calloc(n + 1, sizeof(double));
filter->y = (double *) calloc(n + 1, sizeof(double));
}
//释放滤波器内存
void butterworth_filter_free(ButterworthFilter *filter)
{
free(filter->a);
free(filter->b);
free(filter->x);
free(filter->y);
}
//巴特沃斯带通滤波器
double butterworth_bandpass_filter(ButterworthFilter *filter, double x)
{
int i;
double y = filter->b[0] * x;
for (i = 1; i <= filter->n; i++)
y += filter->b[i] * filter->x[i] - filter->a[i] * filter->y[i];
for (i = filter->n; i > 0; i--)
filter->x[i] = filter->x[i - 1];
for (i = filter->n; i > 0; i--)
filter->y[i] = filter->y[i - 1];
filter->x[0] = x;
filter->y[0] = y;
return y;
}
//测试代码
int main()
{
int n = 2; //滤波器阶数
double f1 = 20; //通带下边界频率
double f2 = 2000; //通带上边界频率
double fs = 8000; //采样频率
ButterworthFilter filter;
butterworth_filter_init(&filter, n);
butterworth_bandpass_coeff(n, f1, f2, fs, filter.a, filter.b);
//模拟输入信号
int i, len = 1000;
double x[len], y[len];
for (i = 0; i < len; i++) {
x[i] = sin(2 * PI * 1000 * i / fs) + sin(2 * PI * 3000 * i / fs) + sin(2 * PI * 5000 * i / fs);
y[i] = butterworth_bandpass_filter(&filter, x[i]);
printf("%f,%f\n", x[i], y[i]);
}
butterworth_filter_free(&filter);
return 0;
}
```
该代码实现了一个二阶巴特沃斯带通滤波器,可以通过修改滤波器阶数、通带频率范围和采样频率来适应不同的应用场景。在测试代码中,我们使用正弦信号模拟了一个频率为1kHz、3kHz和5kHz的混合信号,并将其输入到巴特沃斯带通滤波器中,输出滤波后的信号。由于滤波器只允许通过1kHz到3kHz之间的频率信号,因此输出信号中只有1kHz和3kHz的成分。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)