c++实现巴特沃斯带通滤波器代码
时间: 2023-09-19 21:11:46 浏览: 53
以下是一个简单的 C++ 实现巴特沃斯带通滤波器的代码:
```c++
#include <cmath>
#include <vector>
// 巴特沃斯带通滤波器
class ButterworthBandpassFilter {
public:
// 构造函数
ButterworthBandpassFilter(double sampleRate, double lowCutoffFreq, double highCutoffFreq, int order)
: sampleRate_(sampleRate), lowCutoffFreq_(lowCutoffFreq), highCutoffFreq_(highCutoffFreq), order_(order)
{
// 计算截止频率
double omegaLow = 2.0 * M_PI * lowCutoffFreq_ / sampleRate_;
double omegaHigh = 2.0 * M_PI * highCutoffFreq_ / sampleRate_;
// 计算极点
poles_.resize(order_ * 2);
for (int i = 0; i < order_; ++i) {
double theta = M_PI * (2.0 * i + 1.0) / (2.0 * order_);
double alpha = sin(theta) * sinh(log(2.0) / 2.0 * omegaLow / sin(theta));
double realPart = -alpha;
double imagPart = cosh(log(2.0) / 2.0 * omegaLow / sin(theta));
poles_[i*2] = std::complex<double>(realPart, imagPart);
poles_[i*2+1] = std::complex<double>(realPart, -imagPart);
}
// 计算标准化后的极点和零点
std::vector<std::complex<double>> normPoles(order_ * 2);
std::vector<std::complex<double>> normZeros(order_ * 2);
double omegaC = sqrt(omegaLow * omegaHigh);
for (int i = 0; i < order_ * 2; ++i) {
normPoles[i] = poles_[i] / omegaC;
normZeros[i] = std::complex<double>(0.0, 0.0);
}
// 计算数字滤波器的系数
b_.resize(order_ * 2 + 1);
a_.resize(order_ * 2 + 1);
b_[0] = 1.0;
a_[0] = 1.0;
for (int i = 0; i < order_ * 2; ++i) {
b_[i+1] = 0.0;
a_[i+1] = 0.0;
for (int j = 0; j <= i; ++j) {
b_[i+1] += std::pow(-1, i-j) * normPoles[j] * b_[i-j];
if (j < i) {
a_[i+1] += std::pow(-1, i-j-1) * normPoles[j] * a_[i-j-1];
}
}
}
// 归一化系数
double sumB = 0.0;
for (int i = 0; i < order_ * 2 + 1; ++i) {
sumB += b_[i];
}
for (int i = 0; i < order_ * 2 + 1; ++i) {
b_[i] /= sumB;
a_[i] /= sumB;
}
}
// 滤波函数
double filter(double x) {
double y = b_[0] * x;
for (int i = 1; i < order_ * 2 + 1; ++i) {
y += b_[i] * xHistory_[i-1] - a_[i] * yHistory_[i-1];
}
xHistory_.push_back(x);
yHistory_.push_back(y);
if (xHistory_.size() > order_ * 2) {
xHistory_.erase(xHistory_.begin());
yHistory_.erase(yHistory_.begin());
}
return y;
}
private:
double sampleRate_;
double lowCutoffFreq_;
double highCutoffFreq_;
int order_;
std::vector<std::complex<double>> poles_;
std::vector<double> b_;
std::vector<double> a_;
std::vector<double> xHistory_;
std::vector<double> yHistory_;
};
```
使用该滤波器的示例代码:
```c++
#include <iostream>
#include <vector>
#include "ButterworthBandpassFilter.h"
int main() {
double sampleRate = 1000.0;
double lowCutoffFreq = 50.0;
double highCutoffFreq = 150.0;
int order = 4;
ButterworthBandpassFilter filter(sampleRate, lowCutoffFreq, highCutoffFreq, order);
std::vector<double> inputSignal = {1.0, 2.0, 3.0, 4.0, 5.0};
std::vector<double> outputSignal;
for (double x : inputSignal) {
double y = filter.filter(x);
outputSignal.push_back(y);
}
std::cout << "Input signal: ";
for (double x : inputSignal) {
std::cout << x << " ";
}
std::cout << std::endl;
std::cout << "Output signal: ";
for (double y : outputSignal) {
std::cout << y << " ";
}
std::cout << std::endl;
return 0;
}
```