我想从音频文件中生成振幅的数字列表。我应该能够:
- 指定采样率(16kHz、44.1kHz 等)
- 指定振幅样本的数据类型(8 位整数、32 位浮点数等)
- 轻松解析列表,以便我可以将其导入其他工具,如 Python 的 numpy(换行符分隔、csv 等)
- 反过来,我还想要一种方法来将这样的列表重新编码为任意音频格式。
我相信我以前曾使用过 ffmpeg 来做这件事,但一直找不到解决方案。(或者可能是 Audacity?)
当我看到我最近的 ffmpeg 支持的编解码器集时(摘自ffmpeg -codecs
),我认为我已经找到了答案:
DEA..S pcm_f64be PCM 64-bit floating point big-endian
DEA..S pcm_s24be PCM signed 24-bit big-endian
DEA..S pcm_s64be PCM signed 64-bit big-endian
DEA..S pcm_s8 PCM signed 8-bit
DEA..S pcm_u32be PCM unsigned 32-bit big-endian
DEA..S pcm_u8 PCM unsigned 8-bit
以上 ”相控阵相机“方法似乎准确地描述了我想要做的事情,但我只需要知道如何以可解析的格式提取样本。
我尝试过的所有命令都会以某种二进制编码创建文件,这些文件似乎需要某种解码器才能理解。以下是一个例子:
ffmpeg -i audio.wav -f u8 -c:a pcm_u8 -ar 16000 out.raw
ffmpeg 顺利完成该命令,但输出却难以辨认。
答案1
所有格式都需要一些一种解析器/解码器,但是,您示例中的 PCM 格式所需的解析器实际上比 CSV 所需的更简单。-f u8
是一种非常简单的格式 - “PCM”不涉及任何压缩,在您的情况下它实际上是每个样本 1 个字节。
这意味着可以使用各种内置 Python 和/或 Numpy 函数来读取它。使用u8
(每个样本 1 个字节),您不需要任何额外的东西,因为 Python 已经为您提供了bytearray
由无符号整数值组成的数据:
注意:所有示例均适用于 Python 3。
with open("out_pcm_u8.raw", "rb") as fh:
samples = list(fh.read())
对于这样的格式u32be
,您可以使用“struct”或“array”模块,以及numpy.frombuffer()。所有必要的信息都已包含在格式名称中,您只需使用它help(struct)
来查找匹配的类型(>
对于 big-endian、I
对于 u32、i
对于 s32)。例如:
import struct
with open("out_pcm_u32be.raw", "rb") as fh:
buf = fh.read()
samples = [t[0] for t in struct.iter_unpack(">I", buf)]
import numpy
dt = numpy.dtype(">u4")
with open("out_pcm_u32be.raw", "rb") as fh:
buf = fh.read()
samples = numpy.frombuffer(buf, dtype=dt)
为了完整性,前面的例子的扩展版本struct
:
import struct
samples = []
with open("out_pcm_u32be.raw", "rb") as fh:
while True:
buf = fh.read(32 // 8)
if buf:
(samp,) = struct.unpack(">I", buf)
samples.append(samp)
else:
break