Floating point 假设WAV或AIFF文件中的浮点样本将被规范化,这是否正确?

Floating point 假设WAV或AIFF文件中的浮点样本将被规范化,这是否正确?,floating-point,normalization,wav,aiff,Floating Point,Normalization,Wav,Aiff,假设我有一个读取.WAV或.AIFF文件的程序,该文件的音频被编码为浮点采样值。我的程序假设任何格式良好的(基于浮点的).WAV或.AIFF文件只包含[-1.0f、+1.0f]范围内的样本值,这是否正确?我在WAV或AIFF规范中找不到任何可以解决这一点的东西 如果这不是一个有效的假设,我们怎么知道文件中音频的完整动态范围是什么?(我可以读取整个文件,并找出文件的实际最小和最大样本值,但这有两个问题:(1)如果文件非常大,这将是一个缓慢/昂贵的操作;(2)它将丢失信息,因为如果文件的创建者希望文

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


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

我知道这个问题并不特定于给定的编程语言或框架,但我无法在任何规范中找到答案。我可以肯定的是,在为.NET framework编写的应用程序中,广泛用于处理.WAV文件的NAudio库假定浮点样本在[-1.0,+1.0]范围内

以下是its中的适用代码:

namespace NAudio.Wave
{
公共类WaveFileReader:WaveStream
{
...
/// 
///尝试读取下一个样本或样本组,将其作为标准化为-1.0f到1.0f范围的浮点
/// 
///一个样本数组,1个用于单声道,2个用于立体声等。Null表示到达文件末尾
/// 
public float[]ReadNextSampleFrame()
{
...
var sampleFrame=新浮点[波形通道];
int bytesToRead=波形通道*(波形位采样/8);
...
用于(int通道=0;通道<波形通道;通道++)
{
if(waveFormat.BitsPerSample==16)
...
else if(waveFormat.BitsPerSample==32&&waveFormat.Encoding==WaveFormatEncoding.IeeeFloat)
{
sampleFrame[通道]=位转换器.ToSingle(原始,偏移);
偏移量+=4;
}
...
}
返回采样框;
}
...
}
}

因此,它只是将浮点复制到数组中,而不对其进行任何转换,并保证它在给定的范围内。

如您所述,公共可用文档没有详细介绍用于浮点的范围。然而,从过去几年的行业实践来看,从以浮点文件形式存在的实际数据来看,我认为这是一个有效的假设

这有实际原因,也有一个非常常见的高精度数据标准化范围,即颜色、音频、3D等

该范围处于区间[-1,1]内的主要原因是,它可以快速且容易地缩放/转换到目标位范围。您只需要提供目标范围并进行乘法运算

例如:

如果您想在16位播放它,您可以这样做(伪,假设有符号四舍五入到整数结果):

sample=in<0?in*0x8000:in*0x7fff;
或24位:

sample = in < 0 ? in * 0x800000 : in * 0x7fffff;
sample=in<0?in*0x800000:in*0x7fffff;
或8位:

sample = in < 0 ? in * 0x80 : in * 0x7f;
sample=in<0?in*0x80:in*0x7f;
无需以任何方式调整原始输入值-1和1表示转换为目标时的最小/最大值(1x=x)

如果使用[-0.5,0.5]的范围,则首先(或在某个点上)必须调整输入值,以便转换到例如16位将需要额外的步骤-这不仅需要额外的步骤,而且还需要额外的成本,因为我们将在计算量更大的浮点域中工作(后者可能是一个遗留的原因,因为现在浮点处理速度非常快,但无论如何)

in=in*2;
样本=英寸<0英寸*0x8000:英寸*0x7fff;
将其保持在[-1,1]范围内,而不是某些预先缩放的范围内(例如[-32768,32767]),也允许使用更多位来提高精度(使用IEEE 754表示法)

更新2017/07

测验 基于评论中的问题,我决定通过使用三个文件和1秒正弦波进行测试来进行三重检查:

A) 浮点剪裁
B) 浮点最大值为0dB,且
C) 整数剪裁(从A转换)

然后从
数据
区块和大小字段之后开始扫描正值=1.0的文件,以使最小值/最大值反映音频数据中的实际值

结果证实,在不剪裁时,范围确实在[-1,1]包含范围内(非真是)。

充当一个或多个音频数据通道的载体。该音频数据已使用特定的编码。每个编码格式都使用一个。算法是重要的部分。我们可以将文件和编码格式的值传递出去

AIFF和WAV都使用或其子代。(如果您查看此项,您会注意到在“基于PCM的算法的编码/压缩类型”列表下。)PCM的工作原理是以固定的时间间隔对音频正弦波进行采样并选择最接近的数字表示。这里的重点是“正弦波”

正弦波调制在1到1之间,因此所有PCM导出编码都将按照这个原理工作。考虑MU定律的实现:在其范围内的通知需要是-1到1。 为了简单地回答这个问题,我做了很多手势。有时我们必须这样做。如果你想更深入地研究浮点和定点,那么

sample = in < 0 ? in * 0x800000 : in * 0x7fffff;
sample = in < 0 ? in * 0x80 : in * 0x7f;
in = in * 2;
sample = in < 0 ? in * 0x8000 : in * 0x7fff;