将 32 位浮点数转换为 16 位 PCM 范围



我有一些由javascript HTML5 Web audio api生成的数据。它生成 Float32Array,一个介于 -1 和 1 之间的 32 位浮点数组。我使用 websocket 将数据流式传输到我的服务器。

我需要将 32 位浮点数转换为 -32768 和 +32767(16 位有符号整数(之间的 16 位 PCM 范围。然后,这允许将数据用作 wav 文件。

我在转换时遇到问题。我怀疑答案是使用结构模块,但我无法获得正确的格式。

下面是

一个示例 Python 2.7 程序,该程序读取包含原始 32 位浮点音频样本的文件,并创建一个 WAV 文件,其中包含这些样本转换后的 16 位有符号整数样本:

import sys
import array
import struct
import wave
def convert(fin, fout, chunk_size = 1024 * 1024):
    chunk_size *= 4    # convert from samples to bytes
    waveout = wave.open(fout, "wb")
    waveout.setparams((1, 2, 44100, 0, "NONE", ""))
    while True:
        raw_floats = fin.read(chunk_size)
        if raw_floats == "":
            return
        floats = array.array('f', raw_floats)
        samples = [sample * 32767
                   for sample in floats]
        raw_ints = struct.pack("<%dh" % len(samples), *samples)
        waveout.writeframes(raw_ints)
convert(open(sys.argv[1], "rb"), open(sys.argv[2], "wb"))

该代码使用 array.array 将 32 位浮点样本转换为 Python 浮点数,因为它应该比 struct.unpack 快一点。它还使用本机计算机字节顺序,就像Float32Array一样。无法使用 array.array 创建 16 位整数样本,因为它们需要使用小字节序字节序,而不管本机顺序如何。范围转换由简单的 Python 代码处理。

最新更新