我在用着arm_rfft_fast_f32
因为我的数据将来会是浮点数,但我在输出数组中得到的结果是疯狂的(我认为)——我得到的频率低于 0。
The arm_rfft_fast_f32 https://www.keil.com/pack/doc/CMSIS/DSP/html/group__RealFFT.html#ga180d8b764d59cbb85d37a2d5f7cd9799函数不返回频率,而是返回使用以下函数计算的复值系数快速傅立叶变换 (FFT) https://en.wikipedia.org/wiki/Fast_Fourier_transform。因此,这些系数为负是完全合理的。更具体地说,单周期的预期系数sin
幅度为 15 的测试音输入为:
0.0, 0.0; // special case packing real-valued X[0] and X[N/2]
0.0, -3840.0; // X[1]
0.0, 0.0; // X[2]
0.0, 0.0; // X[3]
...
0.0, 0.0; // X[255]
请注意,如中所示文档 https://www.keil.com/pack/doc/CMSIS/DSP/html/group__RealFFT.html#details前两个输出对应于纯实数系数X[0]
and X[N/2]
(在随后的调用中,您应该特别小心这种特殊情况arm_cmplx_mag_f32
;请参阅下面的最后一点)。
每个频率分量的频率由下式给出k*fs/N
, where N
是样本数(在你的情况下l_probek
) and fs = 1/dt
是采样率(在你的情况下freq*l_probek
):
X[0] -> 0*freq*l_probek/l_probek = 0
X[1] -> 1*freq*l_probek/l_probek = freq = 5000
X[2] -> 2*freq*l_probek/l_probek = 2*freq = 10000
X[3] -> 3*freq*l_probek/l_probek = 2*freq = 15000
...
最后,由于前两个值的特殊包装,计算时需要小心N/2+1
幅度:
// General case for the magnitudes
arm_cmplx_mag_f32(data_out.f+2, data_mag.f+1, l_probek/2 - 1);
// Handle special cases
data_mag.f[0] = data_out.f[0];
data_mag.f[l_probek/2] = data_out.f[1];