你在这里看到的是一个有限脉冲响应 (FIR) 滤波器的低音实现,它实现了一个boxcar 窗口函数。考虑 DSP 方面的问题,您需要vector
使用NO_OF_NEIGHBOURS
相等的 FIR 系数过滤输入,每个系数的值都为1/NO_OF_NEIGHBOURS
. 通常最好使用已建立的算法,而不是重新发明轮子。
这是一个相当邋遢的实现,我快速敲定了过滤器加倍。您可以轻松地对其进行修改以过滤您的数据类型。该演示显示了对上升锯函数 (0,.25,.5,1) 的几个周期的过滤,仅用于演示目的。它可以编译,因此您可以使用它。
#include <iostream>
#include <vector>
using namespace std;
class boxFIR
{
int numCoeffs; //MUST be > 0
vector<double> b; //Filter coefficients
vector<double> m; //Filter memories
public:
boxFIR(int _numCoeffs) :
numCoeffs(_numCoeffs)
{
if (numCoeffs<1)
numCoeffs = 1; //Must be > 0 or bad stuff happens
double val = 1./numCoeffs;
for (int ii=0; ii<numCoeffs; ++ii) {
b.push_back(val);
m.push_back(0.);
}
}
void filter(vector<double> &a)
{
double output;
for (int nn=0; nn<a.size(); ++nn)
{
//Apply smoothing filter to signal
output = 0;
m[0] = a[nn];
for (int ii=0; ii<numCoeffs; ++ii) {
output+=b[ii]*m[ii];
}
//Reshuffle memories
for (int ii = numCoeffs-1; ii!=0; --ii) {
m[ii] = m[ii-1];
}
a[nn] = output;
}
}
};
int main(int argc, const char * argv[])
{
boxFIR box(1); //If this is 1, then no filtering happens, use bigger ints for more smoothing
//Make a rising saw function for demo
vector<double> a;
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
box.filter(a);
for (int nn=0; nn<a.size(); ++nn)
{
cout << a[nn] << endl;
}
}
使用这条线增加滤波器系数的数量,以查看逐渐平滑的输出。只有 1 个滤波器系数,没有平滑。
boxFIR box(1);
该代码足够灵活,您甚至可以根据需要更改窗口形状。通过修改构造函数中定义的系数来做到这一点。
注意:这将为您的实现提供稍微不同的输出,因为这是一个因果过滤器(仅取决于当前样本和以前的样本)。您的实现不是因果关系,因为它会在未来的样本中提前进行平均,这就是为什么您需要条件语句来处理接近向量末尾的情况。如果您想要输出类似于您尝试使用此算法对您的过滤器执行的操作,请通过此算法反向运行您的向量(只要窗口函数是对称的,这工作正常)。这样,您可以获得类似的输出,而无需算法的讨厌的条件部分。