Signal processing 如何将频率箱与傅里叶变换幅值对齐?

Signal processing 如何将频率箱与傅里叶变换幅值对齐?,signal-processing,fft,stm32,Signal Processing,Fft,Stm32,我正试图在STM32F411RE核子开发板上实现一个具有相关复振幅函数的快速傅里叶变换。我的目标是将具有多个正弦元素的组合信号分离为具有正确振幅的单独频率分量 我的问题是,我无法将复震级函数的频率箱结果与频率正确对齐。我也开始质疑这些结果本身的有效性 我曾尝试使用人们发布的许多不同的FFT算法实现,最显著的例子是和 我有一个类似的方法,但不知何故,他们的方法产生了预期的结果,而我的方法却没有。下面是我的代码,我通过SleuthEye创建的实现对其进行了修改 int main(void) {

我正试图在STM32F411RE核子开发板上实现一个具有相关复振幅函数的快速傅里叶变换。我的目标是将具有多个正弦元素的组合信号分离为具有正确振幅的单独频率分量

我的问题是,我无法将复震级函数的频率箱结果与频率正确对齐。我也开始质疑这些结果本身的有效性

我曾尝试使用人们发布的许多不同的FFT算法实现,最显著的例子是和

我有一个类似的方法,但不知何故,他们的方法产生了预期的结果,而我的方法却没有。下面是我的代码,我通过SleuthEye创建的实现对其进行了修改

int main(void)
{
    fftLen = 32;    // can be 32, 64, 128, 256, 512, 1024, 2048, 4096
    half_fftLen = fftLen/2;
    volatile float32_t sampleFreq = 50 * fftLen;    // Fs = binsize * fft length, desired binsize = 50 hz

    arm_rfft_fast_instance_f32 inst;
    arm_status status;
    status = arm_rfft_fast_init_f32(&inst, fftLen);

    float32_t signalCombined[fftLen] = {0};
    float32_t fftCombined[fftLen] = {0};
    float32_t fftMagnitude[fftLen] = {0};
    volatile float32_t fftFreq[fftLen] = {0};

    float32_t maxAmp;
    uint32_t maxAmpInd;

    while (1)
    {
        for (int i = 0; i< fftLen; i++)
        {
            signalCombined[i] = 40 * arm_sin_f32(450 * i); // 450 frequency at 40 amplitude
        }

        arm_rfft_fast_f32(&inst, signalCombined, fftCombined, 0); // perhaps switch to complex transform to allow for negative frequencies?
        arm_cmplx_mag_f32(fftCombined, fftMagnitude, half_fftLen);
        fftMagnitude[0] = fftCombined[0];
        fftMagnitude[half_fftLen] = fftCombined[1];

        arm_max_f32(fftMagnitude, half_fftLen, &maxAmp, &maxAmpInd); // We need the 3 max values

        for (int k = 0; k < fftLen ; k++)
        {
            fftFreq[k] = ((k*sampleFreq)/fftLen);
        }
}

您的音调生成没有考虑1600Hz的采样频率,因此您实际上是在
450*1600/(2*PI)~114591Hz
的频率下生成音调,该频率会混叠到~608Hz。当使用32的FFT大小时,608Hz频率大致对应于12左右的频率指数

在1600Hz采样频率下产生450Hz音调的步骤如下:

for (int i = 0; i< fftLen; i++)
{
    signalCombined[i] = 40 * arm_sin_f32(2 * PI * 450 * i / sampleFreq);
}
for(int i=0;i

至于匹配振幅,请注意时域和频域之间的比例因子约为
0.5*fftLen
(请参阅)。

感谢您的帮助,我现在可以在使用32的fft长度时找到正确的频率。然而,当我随后切换到2048的更长fft长度进行最终实现时,它似乎不再工作,尽管采样频率也适当缩放?我也很难实现你的大量信息链接帖子信息:从你的代码
2*(1/N)*abs(X(k))^2
我创建了实现
fftMagnitude[j]=2*powf(fabs(fftMagnitude[j]),2)/fftLen
,但出于某种原因,这似乎也没有给我所需的输出?另一篇文章指出,计算幅值
abs(X(k))
得到的值大约是时域振幅的
0.5*fftLen
倍。因此,如果你想得到时域振幅近似值,你应该计算
2*abs(X(k))/fftLen
。这实际上更有意义,无论是从我的文献中还是从我手动计算箱子时得到的正确结果来看。我发现我的问题是我计算的绝对值是错误的,这也影响了我生成的值(复合问题非常有趣:/)。无论如何,在你的帮助下,通过使用正确的fabsf()函数来计算最大值,我能够得到正确的频率和正确的振幅!谢谢,伙计,我真的很感激!
for (int i = 0; i< fftLen; i++)
{
    signalCombined[i] = 40 * arm_sin_f32(2 * PI * 450 * i / sampleFreq);
}