16-bit PCM 音频格式转换
一、认识
16-bit PCM
音频格式转换: 将经过 16kHz
将采样的 浮点音频数据 转换为 16-bit PCM
格式。这是为了将音频数据转化为更加通用、标准的格式,便于存储、传输或进一步处理。另外, 16-bit PCM
能够表示从 -32768
到 32767
的整数范围,这足以容纳大部分音频信号的动态范围, 也是最常见的音频存储格式之一, 提供了足够的精度来处理大多数音频录制和播放任务。而且, 使用 16-bit PCM
格式相比于浮点数格式(如 32-bit float
)能够显著减少存储空间和带宽需求,并且在处理音频时具有较好的性能,尤其是在低延迟和实时处理场景中。具体思路为: 将浮动的音频信号(通常在范围 -1
到 1
之间)映射到 16
位整数的音频格式。具体转换逻辑为: 根据输入的浮点音频数据计算出转换后的 16-bit
数据所需的字节数长度, 这个长度创建一个新的 ArrayBuffer
,这个缓冲区将用来存储最终的 16-bit PCM
数据。ArrayBuffer
是一种用于存储原始二进制数据的对象。在根据 ArrayBuffer
创建一个 DataView
对象, 允许你以不同的数据类型读取和写入 ArrayBuffer
中的数据。遍历输入的浮点音频数据, 并将每个样本值转换为 16-bit PCM
格式, 注意, 每次迭代, offset
增加 2
,因为每个 16-bit PCM
样本占 2
字节。遍历过程中, 首先将输入的浮动音频数据限制在 -1
到 1
的范围内, 这样做是为了确保音频信号不会超过正常的范围,避免发生溢出。通过 dataView.setInt16
将一个 16-bit
整数值写入到 ArrayBuffer
中指定的偏移位置 offset
。s < 0 ? s * 0x8000 : s * 0x7fff:
表示如果 s
为负数,乘以 0x8000
(即 32768
);如果 s
为正数,乘以 0x7fff
(即 32767
)。这将浮点数映射到 16-bit PCM
范围内的整数值。浮点数被乘以 32767
或 -32768
来保证其能够正确表示在 16-bit PCM
的有符号整数范围内。true
表示使用小端字节序(little-endian
),这在许多音频格式(如 WAV
)中是常见的字节顺序。
二、实现
function to16BitPCM(input) {
const dataLength = input.length * (16 / 8);
const dataBuffer = new ArrayBuffer(dataLength);
const dataView = new DataView(dataBuffer);
let offset = 0;
for (let i = 0; i < input.length; i++, offset += 2) {
const s = Math.max(-1, Math.min(1, input[i]));
dataView.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
}
return dataView;
}