读取 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 中转换,只需使用 subprocess
或 os
模块调用此命令即可。
【讨论】:
以上是关于读取 u-LAW 编码的 WAV 文件并不压缩保存的主要内容,如果未能解决你的问题,请参考以下文章
wav音频文件解析读取 定点转浮点分析 幅值提取(C语言实现)