我正在使用Mark Borgerding撰写的“ KISS FFT”版本。它接受一个16位定点输入值的数组,并生成一个32位浮点结果数组。

我发现,如果输入幅度很低,则会浮出许多浮点结果值零,但如果我只是按比例缩放输入(例如乘以16倍),则较少的输出值为零,因此输出似乎包含更多细节。 (对我而言,这并不是很重要,但是为了保持一致,我然后将结果浮点值除以相同的比例因子。)

无论如何,这似乎是可行的,因为以前生成结果我实际上已经获得了几乎全为零的缓冲区,但我想知道是否有某种原因可能不是有效的方法。

(请注意,这种方法意味着还有很多其他的“数据的“粗度” /粒度,尤其是通常不会出现的低级噪声。我几乎想知道是否应该注入一些低级噪声来替换数据中的零值输入。)

评论

“我几乎想知道,注入一些低电平噪声来代替输入中的零值是否明智。” = en.wikipedia.org/wiki/Dither

#1 楼

这可能是有效的方法。您会看到一个非常实际的问题,该问题通常在使用定点(即整数)算法时出现(尽管它也可能在浮点数中发生)。当您用于执行计算的数字格式没有足够的精度来表示可能从您的计算中产生的所有值时,则需要某种形式的舍入(例如,截断,四舍五入等)。上)。这通常被建模为信号的附加量化误差。

但是,对于算法和舍入方案的某些组合,当输入信号的幅度非常低时,有可能获得您所观察到的结果:大量零输出。基本上,在操作序列中的某处,中间结果变得足够小,不会超过量化到非零水平所需的阈值。然后将该值舍入为零,该值通常可以向前传播到输出。正如您所指出的,结果是一种生成大量输出零的算法。

那么您可以通过按比例放大数据来解决此问题吗?有时(一直有效的技术很少!)。如果您的输入信号的幅度值限定为低于数字格式的满刻度的值(从-32768到+32767的16位有符号整数),则可以将输入信号放大到最大程度,以充分利用可用范围它。这可以帮助减轻舍入误差的影响,因为与相关信号相比,任何舍入误差的大小都会变小。因此,如果您的所有输出在算法内部都舍入为零,则可能会有所帮助。

这种技术何时会伤害您?根据算法计算的结构,按比例放大输入信号可能会使您面临数值溢出的问题。同样,如果信号中包含的背景噪声或干扰的幅度大于算法的舍入误差,那么在输出端获得的质量通常会受到环境的限制,而不是计算中引入的误差。

评论


$ \ begingroup $
我正在使用一种动态缩放技术,效果似乎很好。而且,正如幸运的那样,极端的瞬变被视为噪声并且无论如何都会被削波,因此偶尔的削波不应该成为问题。您认为通过除以输入比例因子对输出进行“缩放”是否有效?
$ \ endgroup $
–Daniel R Hicks
2012年5月15日上午11:44

#2 楼

解决此问题的最简单,最简单的方法是在FFT之前将数据转换为浮点并使用浮点FFT。这种方法的唯一缺点是您可能会消耗更多的处理器和内存。由于您的输出仍然是浮点数,因此实际差异可能很小。

评论


$ \ begingroup $
我已经将当前的FFT算法交付给了这个项目,而我现在不愿意对此进行处理。而且这一切都是实时在手机上进行的,因此性能绝对是一个问题。
$ \ endgroup $
–Daniel R Hicks
2012年5月15日上午11:45

$ \ begingroup $
理解了。您是否知道FFT内部是固定点还是浮点数?如果已修复,则需要担心剪切,上溢和下溢
$ \ endgroup $
–希尔马
2012年5月15日14:38

$ \ begingroup $
在没有文档和注释的情况下,它是例外的,但是我看到代码中有很多整数,很少有浮点数和双精度数。它似乎包括用于从16位切换到32位或浮点数的粗略#ifdef框架,但该框架显然已被长期禁用。
$ \ endgroup $
–Daniel R Hicks
2012年5月15日下午16:18

$ \ begingroup $
iPhone(ARM + NEON CPU)(通过Accelerate框架)比C语言中的整数FFT更快地执行浮点FFT。
$ \ endgroup $
– hotpaw2
2012年5月17日下午1:58