通过简单地缩放数据来增加幅度(可能是FFT质量)是否有效?


10

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

我发现,如果输入幅度较低,则许多浮点结果值都会为零,但是如果我仅对输入进行缩放(例如乘以系数16),则输出值将为零,因此输出似乎包含更多详情。(这对我来说不是很重要,但是为了保持一致性,我然后将结果浮点值除以相同的比例因子。)

无论如何,这似乎很有效,就产生结果而言,以前我只是得到几乎全为零的缓冲区,但是我想知道是否有某些原因可能不是有效的方法。

(请注意,这种方法意味着数据具有更多的“粗度​​” /粒度,尤其是通常不会出现的低级噪声。我几乎想知道注入是否明智?一些低电平噪声来代替输入中的零值。)


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

Answers:


7

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

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

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

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


我正在使用动态技术进行缩放,效果似乎很好。而且,正如幸运的那样,极端的瞬变被视为噪声并且无论如何都会被削波,因此偶尔的削波不应该成为问题。您认为通过除以输入比例因子来“缩小”输出是否有效?
Daniel R Hicks

1

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


我已经将当前的FFT算法交给了我这个项目,而在这一点上我不愿意再考虑。而且这一切都是实时在手机上进行的,因此性能绝对是一个问题。
Daniel R Hicks,2012年

明白了 您是否知道FFT内部是固定点还是浮点数?如果已解决,则需要担心剪切,上溢和下溢
Hilmar 2012年

在没有文档和注释的情况下,它是例外的,但是我在代码中看到很多内容,而很少有浮点数和双精度数。它似乎包括用于从16位切换到32位或浮点数的粗略#ifdef框架,但该框架显然已被长期禁用。
Daniel R Hicks

一个iPhone(ARM + NEON CPU)可以做的浮子FFT更快(通过加速框架)中比在C.整数FFT
hotpaw2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.