假设WAV或AIFF文件中的浮点样本将被标准化是否正确?

Jer*_*ner 14 floating-point normalization wav aiff

假设我有一个读取.WAV或.AIFF文件的程序,文件的音频被编码为浮点样本值.我的程序假设任何格式良好(基于浮点的).WAV或.AIFF文件只包含[-1.0f,+ 1.0f]范围内的样本值是否正确?我找不到解决这一点的WAV或AIFF规范中的任何内容.

如果这不是一个有效的假设,那么如何才能知道文件中音频的完整动态范围是什么?(我可以读取整个文件并找出文件的实际最小和最大样本值是什么,但是有两个问题:(1)如果文件非常大,那将是一个缓慢/昂贵的操作,(2) )它会丢失信息,因为如果文件的创建者打算让文件有一些"余量",以免在dbFS最大点播放,我的程序将无法检测到这一点)

小智 7

正如您所述,公共可用文档不会详细介绍浮点使用的范围.但是,从过去几年的行业实践,以及作为浮点文件存在的实际数据,我认为这是一个有效的假设.

这有实际的原因,以及高精度数据标准化的常见范围,如颜色,音频,3D等.

范围在区间[-1,1]中的主要原因是它快速且易于缩放/转换为目标位范围.您只需提供目标范围并乘以.

例如:

如果你想以16位播放它你会做(伪,假设有符号舍入到整数结果):

sample = in < 0 ? in * 0x8000 : in * 0x7fff;
Run Code Online (Sandbox Code Playgroud)

或24位:

sample = in < 0 ? in * 0x800000 : in * 0x7fffff;
Run Code Online (Sandbox Code Playgroud)

或8位:

sample = in < 0 ? in * 0x80 : in * 0x7f;
Run Code Online (Sandbox Code Playgroud)

等,无需以任何方式调整原始输入值.-1和1表示转换为目标时的最小/最大值(1x = x).

如果您使用[-0.5,0.5]的范围,您将首先(或在某些时候)必须调整输入值,因此转换为例如16位需要额外的步骤 - 这需要额外的成本,不仅仅是额外的步骤,但也因为我们将在浮点域工作,这是一个更重要的计算(后者可能有点遗留的原因,因为浮点处理现在非常快,但无论如何).

in = in * 2;
sample = in < 0 ? in * 0x8000 : in * 0x7fff;
Run Code Online (Sandbox Code Playgroud)

将其保持在[-1,1]范围而不是某些预先缩放的范围(例如[-32768,32767])也允许使用更多位来实现精度(使用IEEE 754表示).

更新2017/07

测试

根据评论中的问题,我决定使用三个带有1秒正弦波的文件进行三重检查:

A)浮点削波
B)浮点最大0dB,和
C)整数削波(从A转换)

然后,在data块和大小字段之后开始扫描正值<= -1.0和> = 1.0的文件,以使最小值/最大值反映在音频数据中找到的实际值.

结果证实,当不进行削波时,该范围确实在[-1,1]包含范围内(非真实<= 0 dB).

但它也揭示了另一个方面 -

保存为浮点WAV文件允许超过0 dB的范围值.这意味着对于通常会剪切的值,范围实际上超出[-1,1].

对此的解释可能是浮点格式旨在用于生产设置中的中间使用,因为动态范围的损失非常小,未来的处理(增益分段,压缩,限制等)可以带回值(无损失)在最终和正常-0.2 - 0 dB范围内; 因此保留了原样.

结论

使用浮点的WAV文件将在不剪切(<= 0dB)时保存[-1,1]中的值,但允许被视为剪切的值

但是当转换为整数格式时,这些值剪切到等于整数格式的位范围的等效[-1,1]范围,无论如何.这是自然的,因为每个宽度可以容纳的范围有限.

因此,通过标准化数据或简单地剪回[-1,1],可以使播放器/ DAW /编辑软件处理剪切的浮点值.

文件1
注意:所有文件的最大值都是直接从样本数据中测量的.

文件2
注意:产生剪切浮点数(+ 6 dB),然后转换为带符号的16位并返回浮点数

文件3
注意:削减到+6 dB

文件4
注意:剪切为+12 dB

可在此处找到简单的测试脚本和文件.