【问题标题】:Conflicting results when computing an FFT using ARM DSP libraries and in MatLab使用 ARM DSP 库和 MatLab 计算 FFT 时的结果冲突
【发布时间】:2016-04-01 14:30:44
【问题描述】:

我正在尝试使用 STM32L4 微处理器计算 FFT,但得到了奇怪的结果。 我从 SD 卡中读取了一个 .wav 文件,删除了填充并将 1024 字节的数据存储在一个数组中。 通过在我的电脑上的十六进制编辑器中打开相同的 wav 文件,我已经确认这些数据是正确的。 当我在 MatLab 中计算 FFT 并取其大小时,对应于输入正弦波频率的频率箱匹配。在我的 C 代码中不是这种情况(如我正在使用的 Keil 调试器中所见)。 ARM DSP 库给出的值与 MatLab 中生成的值之间几乎没有任何相关性,例如,MatLab 中的 bin[0] = 5.2,C 中的 bin[0] = 131246...有事! (见编辑...) 我已经尝试了两种不同版本的 FFT,我将在下面将它们都包括在内:

/* Carry out an FFT on the (correctly formatted) input data */
arm_cfft_f32(&arm_cfft_sR_f32_len1024, inputBuffer, IFFTFLAG, BRFLAG);
/* Calculate the complex magnitude of the FFT */
arm_cmplx_mag_f32(inputBuffer, outputBuffer, FFTSIZE);

不推荐使用的代码:

arm_cfft_radix4_instance_f32 S;
arm_cfft_radix4_init_f32(&S, FFTSIZE, IFFTFLAG, BITREVERSEFLAG);
arm_cfft_radix4_f32(&S, inputBuffer);
arm_cmplx_mag_f32(inputBuffer, outputBuffer, FFTSIZE);   

两者都导致相同(错误)的值。在 C 中完成的所有预处理都是正确的,我形成了一个长度为 FFTSIZE * 2 的数组,排列为: Re[0]、Im[0]、Re[1]、Im[1]、...、Re[1023]、Im[1023]。

任何想法或帮助将不胜感激! :)

编辑: 我已经意识到,除了 DC bin 之外,两个计算之间的值实际上是相关的。 即对于这两种计算,bin 47 具有最大值(这是有道理的,因为它是以 22.05kHz 采样的 1kHz 正弦波)。 任何想法为什么 ARM DSP 库如此缩放 bin 的输出?

【问题讨论】:

  • @OliverCharlesworth 与我的 matlab 脚本中的值相比,C 中生成的所有值都是巨大的。我将列出前 10 个左右的垃圾箱作为示例。 C: bin[0] - 131486, bin[1] - 413.7, bin[2] - 410, bin[3] - 415, bin[4] - 408. Matlab: bin[0] - 5.2, bin[1] - 5.2, bin[2] - 5.3, bin[3] - 5.2, bin[4] - 5.3.
  • @OliverCharlesworth 我已经意识到,除了 DC bin 之外,这些值是相关的(即对于两个计算 bin 48 是最大值),只有 C 的所有结果都被大规模放大。您知道是什么原因造成的吗?
  • 一些想法:负频率和正频率交换了吗?您是在一个而不是另一个中计算 mag2(幅度平方:不使用 sqrt)吗?
  • 是否有窗口(HAMMING,HANNING)或相关的东西?啊!一些 FFT 例程在正向 FFT 上按 FFT 的大小进行缩放,但在反向 FFT 上则不然。或者也许一个 FFT 按大小缩放,而另一个没有? (记住,有一个 1/n 乘数,其中 n 是 FFT 的大小)
  • 嗯:缩小 0.015?你的 FFT 是 64 号的吗?那么 1/64.0 就是 0.015625,我敢打赌就是这样。

标签: c arm signal-processing fft stm32


【解决方案1】:

arm_cfft_f32 需要 32 位浮点样本数据。而 .wav 文件通常包含 16 位 little-endian 有符号整数样本。

【讨论】:

  • 你的想法是他正在失去动态范围与那里的转换?
  • @rts1 我猜他是说当 int16 缓冲区传递给浮点函数时数据是类型双关的。
  • @hotpaw2 我认为你可能是正确的,事实上我的 .wav 中的数据是 8 位的。我创建了一个我认为将每个样本转换为 float32_t 并将数据格式化为所需格式的函数,但它的行为可能与我想象的不同? Going to attempt to insert my code here. 你能看看那个函数,让我知道它的行为是否如我所想(获取 8 位输入数据,并将其与浮点数组中的零交错)?谢谢。
  • 我注意到你说过他们通常使用有符号整数,我要到周一才能访问 IDE / MCU,但这可能是问题,因为我一直在使用 uint8_t 进行所有计算.
猜你喜欢
  • 2017-09-28
  • 2015-11-16
  • 1970-01-01
  • 2014-04-23
  • 2019-05-30
  • 1970-01-01
  • 2017-11-09
  • 2011-08-06
  • 2013-12-06
相关资源
最近更新 更多