读取 u-LAW 编码的 WAV 文件并不压缩保存

Posted

技术标签:

【中文标题】读取 u-LAW 编码的 WAV 文件并不压缩保存【英文标题】:Read u-LAW encoded WAV file and save it with no compression 【发布时间】:2020-12-18 13:18:45 【问题描述】:

我有一个使用 u-LAW 编码压缩的 WAV 文件,我需要它完全没有压缩,因为wavio 不支持压缩文件。

我调查了audioop 那个claims to support this kind of compression:

此模块支持 a-LAW、u-LAW 和 Intel/DVI ADPCM 编码。

显然,audioop.ulaw2lin() 函数完全符合我的需要,但我不明白如何读取我的文件以将其传递给该函数。

我尝试了以下方法:

import wave
wav_file = wave.open(PATH_TO_AUDIO_FILE)

但是,正如我上面所说,由于音频是 u-LAW 编码的,那段代码会引发异常:

Error: unknown format: 7

有谁知道如何执行此操作?

【问题讨论】:

【参考方案1】:

audioloop 获取原始字节作为输入,因此您必须将 wav 文件作为原始二进制文件打开并仅提取数据,而不提取文件头。 算法是:

    打开压缩文件。 读取数据块。 转换为 PCM。 添加wav标头。

通常wav标头是44字节长,所以要获取数据部分:

with open('input.wav') as f:
    f.seek(44, os.SEEK_SET)
    data = f.read  # Caution here!

您可能必须以较小的块读取数据,以免出现内存异常。 现在你可以转换数据了 -

converted_data = audioloop.ulaw2lin(data, width)

其中width 是所需的输出宽度 - 1 表示 8 位,2 表示 16 位。 要将数据写入有效的wav 文件,我建议使用scipy - 它有一个wave module。

【讨论】:

我收到以下异常:'charmap' codec can't decode byte 0x9d in position 8171: character maps to <undefined>。你知道我打开文件时应该使用什么编码吗? 我认为你应该将它作为二进制文件打开 - open(''input.wav', 'rb'). 当我尝试使用 scipy.io.wavfile.write("output.wav", 8000, converted_data) 保存 converted_data 时,我得到另一个异常:AttributeError: 'bytes' object has no attribute 'dtype' 好吧,scipy.io.wavfile.write 应该得到nd.array 作为数据,所以你必须转换你的converted_data。我认为this link 可能会有所帮助。【参考方案2】:

我一直在处理这个问题,但我使用ffmpeg解决了它

在 Ubuntu 上 ffmpeg 可以通过以下方式安装:

sudo apt install ffmpeg

然后将 raw G.711 μ-law 转换为 wav 只需使用此命令(如果您想要另一个采样率,只需在命令中替换 44100):

ffmpeg -f mulaw -ar 44100 -i input_raw_g711u_file output_file.wav

现在您可以像打开普通 wav 文件一样打开output_file.wav

如果你想在 Python 中转换,只需使用 subprocessos 模块调用此命令即可。

【讨论】:

以上是关于读取 u-LAW 编码的 WAV 文件并不压缩保存的主要内容,如果未能解决你的问题,请参考以下文章

wav音频文件解析读取 定点转浮点分析 幅值提取(C语言实现)

音频转码

求ffmpeg音频压缩代码(wav压缩成wma)

gstreamer 将多通道 wav 文件拆分为单独的通道并将每个通道编码为 mp3、alac 等并保存到文件

哈夫曼编码器

音视频开发进阶指南