WAV format audio file 以 44 字节的标头开头,后跟有效负载,这是未压缩的原始 PCM 音频数据...在有效负载区域中,当您遍历 PCM 数据时,每个样本(音频曲线上的点)将包含以下数据所有通道...标题将告诉您通道数...对于使用 16 位深度的立体声,您将看到给定通道的两个字节(16 位 == 位深度),紧接着是下一个通道的两个字节等...
对于给定的通道,给定的一组字节(在您的情况下为 2 个字节)将出现在两种可能的布局中,由选择的字节序决定...第一个字节后跟第二个字节...字节顺序的顺序在这里很重要.. . 标头还告诉您正在使用的字节序...通常 WAV 格式是小字节序
每个通道都会生成自己的音频曲线
在将 PCM 数据转换为可用音频曲线数据点的代码中,您必须将给定通道的给定样本的所有字节组合成一个值......通常是它的整数而不是浮点,标题定义了 which 。 ..如果是整数,它可以是有符号或无符号的......小端意味着当你读取文件时,第一个(最左边的)字节将成为最低有效字节,随后每个后续字节成为下一个最高有效字节
在伪代码中:
int mydatapoint // allocate your integer audio curve data point
步骤 0
mydatapoint = most-significant-byte
在位深度为 8 时停在这里
...如果您的位深度大于 8 位,现在将其左移以为下一个字节(如果有)腾出空间
第一步
mydatapoint = mydatapoint << 8 // shove data to the left by 8 bits
// which effectively jacks up its value
// and leaves empty those right most 8 bits
第二步
// following operation is a bit wise OR operation
mydatapoint = mydatapoint OR next-most-significant-byte
现在对 PCM 数据的每个后续下一个字节重复执行步骤 1 和 2,按照从最高有效到最低有效(对于小端)的顺序...对于任何超过 16 的位深度都是必不可少的,因此对于 24 位音频或 32 位您需要将 3 或 4 个字节的 PCM 数据组合到您的单个整数输出音频曲线数据点中
我们为什么要做这种移位废话
从模拟转换为数字时的音频保真度取决于您记录音频曲线的准确度...模拟音频是一条连续曲线,但是要变为数字音频,它必须沿曲线采样成离散点。 . 两个因素决定了对模拟曲线进行采样以创建其数字表示时的保真度 ... 沿模拟音频曲线的左右距离由采样率决定,而沿音频曲线的上下距离由位深度决定。 .. 更高的采样率为您提供每秒更多的样本,更大的位深度为您提供更多的垂直点,以近似模拟音频曲线的瞬时高度
bit depth 8 == 2^8 == 256 distinct vertical values to record curve height
bit depth 16 == 2^16 == 65536 distinct vertical values to record curve height
所以为了更准确地将模拟音频曲线的高度记录到数字中,我们希望变得尽可能细化......所以最终的音频曲线尽可能平滑并且不会出现锯齿状,如果我们只分配 2 位就会发生这种情况这会给我们 2^2 这是 4 个不同的值...当您的音频曲线在您的绘图上只有 4 个垂直值可供选择时,尝试连接这些点...位移只是从许多字节的数据...大于 256 的数字不能放在一个字节中,因此必须分布在 PCM 数据的多个字节中
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html