C/C++ 中的 Butterworth BP 滤波,奇怪的频谱
Butterworth BP filtering in C/C++, strange spectrum
我从这里得到了 Bw BP C 代码,https://www-users.cs.york.ac.uk/~fisher/mkfilter,正如其他 OS 主题中所评论的那样,并制作了 250Hz,四阶,从 10 到 20Hz。
以下是此滤波器的代码,改编自本网站提供的代码,并添加了将输入信号的实部和虚部相乘的行(来自 fw FFT R2C):
const unsigned char NZEROS = 8,
NPOLES = 8;
double GAIN = 1.121655430e+02,
xv[NZEROS + 2] = {}, // NZEROS + 1 for real and + 1 for imag
yv[NPOLES + 2] = {}; // NPOLES + 1 for real and + 1 for imag
for (size_t i = 0; i < array_length_fft_1D; i++)
{
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = xv[3]; xv[3] = xv[4];
xv[4] = xv[5]; xv[5] = xv[6];
xv[6] = xv[7]; xv[7] = xv[8];
xv[8] = fft_complex_1D[0][i] / GAIN; // Real part, input
xv[9] = fft_complex_1D[1][i] / GAIN; // Imaginary part, input
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = yv[3]; yv[3] = yv[4];
yv[4] = yv[5]; yv[5] = yv[6];
yv[6] = yv[7]; yv[7] = yv[8];
// Multiplying the real part
yv[8] = (xv[0] + xv[8]) - 4 * (xv[2] + xv[6]) + 6 * xv[4]
+ (-0.1316807150 * yv[0]) + (1.2338753102 * yv[1])
+ (-5.2054087885 * yv[2]) + (12.8890751850 * yv[3])
+ (-20.5097097890 * yv[4]) + (21.4961146820 * yv[5])
+ (-14.4728919700 * yv[6]) + (5.7005626010 * yv[7]);
// Multiplying the imaginary part
yv[9] = (xv[0] + xv[9]) - 4 * (xv[2] + xv[6]) + 6 * xv[4]
+ (-0.1316807150 * yv[0]) + (1.2338753102 * yv[1])
+ (-5.2054087885 * yv[2]) + (12.8890751850 * yv[3])
+ (-20.5097097890 * yv[4]) + (21.4961146820 * yv[5])
+ (-14.4728919700 * yv[6]) + (5.7005626010 * yv[7]);
fft_complex_1D[0][i] = static_cast<float>(yv[8]); // At this point the real part of the complex array is overwritten
fft_complex_1D[1][i] = static_cast<float>(yv[9]); // At this point the imaginary part of the complex array is overwritten
}
fft_complex_1D 是来自 fw FFT 的输入数组,它在每次迭代结束时将实部和虚部乘以系数。它随后被发送到逆向 FFT C2R,并输出一个浮点数组。
然后,当我去 Octave 绘制频谱并查看是否真的被过滤时,10Hz 之前和 20Hz 之后的频率被衰减,但其他一切似乎都没有受到影响,我预计衰减。请参见下图,其中显示了标记为绿色的 10-20Hz 区域。蓝色是输入的、未过滤的数据(从 -5 到 +5 的实数)。红色是过滤后的数据。没有对任何数据应用缩放。
此过滤器代码中有错误或缺失。你们能提供一些反馈吗(没有双关语)?
生成的C代码是描述时域滤波器行为的递归关系。每个索引指的是经过过滤的输入信号的样本(您可能从 ADC 获得的信号)。
您 'broke' 代码由:
- 添加第 9 个样本,其中应该有 none。
- 以某种方式将数据拆分为 real/imaginary 个组件(Q/I?),这不是代码的目的。
我从这里得到了 Bw BP C 代码,https://www-users.cs.york.ac.uk/~fisher/mkfilter,正如其他 OS 主题中所评论的那样,并制作了 250Hz,四阶,从 10 到 20Hz。
以下是此滤波器的代码,改编自本网站提供的代码,并添加了将输入信号的实部和虚部相乘的行(来自 fw FFT R2C):
const unsigned char NZEROS = 8,
NPOLES = 8;
double GAIN = 1.121655430e+02,
xv[NZEROS + 2] = {}, // NZEROS + 1 for real and + 1 for imag
yv[NPOLES + 2] = {}; // NPOLES + 1 for real and + 1 for imag
for (size_t i = 0; i < array_length_fft_1D; i++)
{
xv[0] = xv[1]; xv[1] = xv[2];
xv[2] = xv[3]; xv[3] = xv[4];
xv[4] = xv[5]; xv[5] = xv[6];
xv[6] = xv[7]; xv[7] = xv[8];
xv[8] = fft_complex_1D[0][i] / GAIN; // Real part, input
xv[9] = fft_complex_1D[1][i] / GAIN; // Imaginary part, input
yv[0] = yv[1]; yv[1] = yv[2];
yv[2] = yv[3]; yv[3] = yv[4];
yv[4] = yv[5]; yv[5] = yv[6];
yv[6] = yv[7]; yv[7] = yv[8];
// Multiplying the real part
yv[8] = (xv[0] + xv[8]) - 4 * (xv[2] + xv[6]) + 6 * xv[4]
+ (-0.1316807150 * yv[0]) + (1.2338753102 * yv[1])
+ (-5.2054087885 * yv[2]) + (12.8890751850 * yv[3])
+ (-20.5097097890 * yv[4]) + (21.4961146820 * yv[5])
+ (-14.4728919700 * yv[6]) + (5.7005626010 * yv[7]);
// Multiplying the imaginary part
yv[9] = (xv[0] + xv[9]) - 4 * (xv[2] + xv[6]) + 6 * xv[4]
+ (-0.1316807150 * yv[0]) + (1.2338753102 * yv[1])
+ (-5.2054087885 * yv[2]) + (12.8890751850 * yv[3])
+ (-20.5097097890 * yv[4]) + (21.4961146820 * yv[5])
+ (-14.4728919700 * yv[6]) + (5.7005626010 * yv[7]);
fft_complex_1D[0][i] = static_cast<float>(yv[8]); // At this point the real part of the complex array is overwritten
fft_complex_1D[1][i] = static_cast<float>(yv[9]); // At this point the imaginary part of the complex array is overwritten
}
fft_complex_1D 是来自 fw FFT 的输入数组,它在每次迭代结束时将实部和虚部乘以系数。它随后被发送到逆向 FFT C2R,并输出一个浮点数组。
然后,当我去 Octave 绘制频谱并查看是否真的被过滤时,10Hz 之前和 20Hz 之后的频率被衰减,但其他一切似乎都没有受到影响,我预计衰减。请参见下图,其中显示了标记为绿色的 10-20Hz 区域。蓝色是输入的、未过滤的数据(从 -5 到 +5 的实数)。红色是过滤后的数据。没有对任何数据应用缩放。
此过滤器代码中有错误或缺失。你们能提供一些反馈吗(没有双关语)?
生成的C代码是描述时域滤波器行为的递归关系。每个索引指的是经过过滤的输入信号的样本(您可能从 ADC 获得的信号)。
您 'broke' 代码由:
- 添加第 9 个样本,其中应该有 none。
- 以某种方式将数据拆分为 real/imaginary 个组件(Q/I?),这不是代码的目的。