我想使用窗口函数制作FIR滤镜。我有一些样本数据, size 变量是样本数。 windowSize 变量是窗口函数的大小。 首先我创建窗口函数(blackman窗口):变量 window 然后我需要将它乘以sin(x)/ x函数并与真实数据(变量 data )进行卷积:
for (int i = 0; i < size; ++i) {
for (j = 0; j < windowSize; ++j) {
double arg = 2.0 * PI * ((double)j - (double)windowSize / 2.0) / (double)windowSize;
if (i + j - windowSize / 2 < 0)
continue;
if (arg == 0) {
filteredData[i] += data[i + j - windowSize / 2] * window[j] * 1.0 / (double)windowSize;
} else
filteredData[i] += data[i + j - windowSize / 2] * window[j] * (sin(arg) / arg) / (double)windowSize;
}
}
问题:
结果我得到的滤波数据的平均值与原始数据的平均值非常不同。哪里出错?
在DSP书中写道,为了制作FIR滤波器,我们应该将函数sin(x)/ x乘以窗函数,然后执行卷积,但没有写任何关于 sin(x)/ x 中的x ,所以我使用了:
double arg = 2.0 * PI *((double)j - (double)windowSize / 2.0)/(double)windowSize;
对于 x 值,sine的参数是正确的吗?
答案 0 :(得分:4)
sin(x)/x
过滤器是低通过滤器。也就是说,它抑制高于某个截止频率的所有频率。
如果采样频率为Fs
(赫兹),并且您希望截止频率为fc
(赫兹),那么您应该使用x = 2*PI*fc/(2*Fs)*n
n
来自-N
{1}}到+N
和N
足够大,sin(x)/ x函数接近于零。当x为零时,不要忘记sin(x)/ x为1。
要保持信号的平均值,必须将滤波器系数的和值标准化。即,设置f_norm [k] = f [k] / sum(f [k],k = ...)
这就是我现在要说的全部内容。看起来你有很多需要学习的东西。我建议写一本关于信号处理的好书。
答案 1 :(得分:1)
就实施而言,您似乎需要初始化filteredData[i]
,例如
for (int i = 0; i < size; ++i) {
filteredData[i] = 0;
for (j = 0; j < windowSize; ++j) {
...