何时考虑音频的双(64 位)浮点数

信息处理 声音的 算法 软件实现 固定点
2022-01-06 03:58:14

在现代处理器上合成和处理音频时,什么时候会考虑使用单精度(32 位)浮点以外的东西?显然,进出现实世界的音频是 16/24 位的,所以我只是在谈论软件中信号的精度(包括音频本身和滤波器系数之类的东西)。

假使,假设:

  • CPU/DSP 对单精度和双精度都有硬件浮点支持
  • 优先级是高质量的音频,而不是高性能。例如,如果双精度提供更好的(感知)质量,则会考虑双精度。
4个回答

IEEE 浮点数仅提供大约 24 位尾数。但是许多 DSP/滤波算法(在单位圆附近具有极点/零点的 IIR 双二阶等)需要远多于 24 位的尾数用于中间计算产品(累加器等),以使最终结果精确到接近 16 或24 位。对于这些类型的算法,32、40 和 48 位缩放整数累加器通常与没有 FPU 的 DSP 一起使用。

但是在许多当前的处理器实现(用于 PC、智能手机等)上,当您的算法需要超过 24 位的中间产品时,双精度 FPU 比尝试使用 32 或 64 位缩放整数快得多。

为了防止破坏数据缓存,原始数据可以是短整数或单精度浮点格式,而只有更本地的计算内核可能使用更高分辨率的格式。但如果您在 DSP 模块之间共享中间计算结果,模块之间的交换协议也可能受益于更高分辨率(超过 24 位尾数)总线或数据格式。

CPU/DSP 对单精度和双精度都有硬件浮点支持。

这真的取决于你在谈论什么样的支持。在 x86 上,当使用 x87 风格的浮点指令时,您可以获得完整的 80 位内部精度和相同的处理时间——无论您使用的是单精度还是双精度。

但是在使用 SIMD 指令时,使用 32 位浮点数可以比使用 64 位浮点数多完成两倍的工作。这是一件大事。

要考虑的另一件事是内存 - 使用双精度将适合最快级别高速缓存的数据量除以 2。

在现代处理器上合成和处理音频时,

这将归结为您进行什么样的合成和处理。如果它涉及 IIR 滤波器(或更一般地说是任何带有状态变量和/或反馈的东西),你可以更容易地用 32 位射击自己(如果你不这样做,则使用 32 位)想太多你在做什么。一些过滤器拓扑在 32 位上完美运行。

无论如何,这是一个数值精度问题——就质量而言,不会有任何感知差异。请记住,期望硬件音频链具有超过 20 位的精度是非常荒谬的(假设电路板的布线无可挑剔并且所有部件都是理想的,我们仍然会遇到约翰逊噪声的限制!) - 和这种精度主要由单精度浮点数覆盖。高端混音台上的信号路径有 50 个运算放大器,它们的失真比单精度浮点算术运算的量化噪声大几个数量级。

您需要了解算法的数值要求并相应地选择精度。

所以让我们在这里算一下:32 位浮点有一个 24 位尾数和一个 8 位指数。这在大约 1540 dB 的动态范围内为您提供大约 150 dB 的信噪比。对于大多数音频而言,这已经足够了。双精度给你大约两倍。

每种算法对数值精度都有一定的要求。如果设计得当,我所知道的所有音频算法都可以很好地处理 32 位浮点。“设计得当”是这里的关键词。例如,在 44.1kHz 采样的 40-200Hz 的 6 阶带通作为直接来自 II IIR 双四阶滤波器的实现在 32 位时确实会存在一些噪声问题。然而,它作为转置形式 II 或直接形式 I 过滤器工作得非常好。

如果您尝试使用例如 Matlab 的 residualz() 函数对同一带通滤波器进行部分分数扩展,即使使用双精度也会得到不好的结果。同样,该特定输入数据的算法的数值要求超过了双精度必须提供的要求。解决这个问题的关键不是盲目地提高精度,而是使用更好的算法。

最后让我们看看是什么让浮动(32 位或 64 位)易受攻击:您拥有巨大的动态范围,即您可以将信号按比例缩小 200dB,放大 500dB,再减小 300dB,然后您就可以在开始的地方结束几乎没有任何精度损失。所以不是这样。浮点数难以添加大小差异很大的数字。有一点,添加一个小数并没有任何区别,即你得到 1 + dx =1。这个数字“dx”对于 32 位浮点约为 1.2e-7,对于 64 位约为 2.2e-16。如果您的算法包括添加或减去数量级相差那么远的数字,您可能会遇到问题。

一个很好的例子是前面提到的 Direct Form II 过滤器:Direct From II 过滤器(参见例如https://ccrma.stanford.edu/~jos/fp/Direct_Form_II.html)基本上通过过滤输入来计算状态变量首先使用仅极点传递函数,然后使用零点进行滤波以创建输出。现在,如果极点接近单位圆,则仅极点传递函数变得非常非常大。因此状态变量可以比输入大得多(大 80 分贝到 100 分贝),并且将状态变量与输入相加会产生很多噪声。

这里的解决方案是使用转置的 Form II 或直接的 Form I 过滤器。分析表明,状态变量不能大于输入/输出,那么可能是12dB左右,所以问题大小不匹配首先不会发生。

如果您正在使用在生成和渲染之间经过大量处理(转换为 16/24 位整数)的合成音频,那么您将受益于您的机器具有的最佳数值精度。

区分整数和浮点数也很重要。双精度浮点(64 位)与 64 位整数不同,您甚至可以在软件中处理任意精度整数,具体取决于您使用的软件工具。如果您必须录制声音而不是生成声音,那将很重要(据我所知,AD 转换总是以整数格式保存采样的声音)。

我不能完全确定,但是如果您已经以浮点方式生成声音,那么根据定义,很可能不会出现更常见的伪影,并且您可以以更高的“音频质量”对其进行处理。也许您甚至可以在您已经将一些效果应用到发生器本身之后才生成声音样本。您真正引入任何潜在工件的唯一时刻是将其转换为某种整数文件格式的输出,例如 .WAV。

实际上,由于现在大多数机器都具有原生“双”(64 位)精度,我看不出有理由再使用 32 位......

希望有帮助!