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 /编辑软件处理剪切的浮点值.
注意:所有文件的最大值都是直接从样本数据中测量的.
注意:产生剪切浮点数(+ 6 dB),然后转换为带符号的16位并返回浮点数
注意:削减到+6 dB
注意:剪切为+12 dB
可在此处找到简单的测试脚本和文件.