使用Python更改wav文件的音量

时间:2018-07-22 20:11:53

标签: python wav

我尝试使用Pydub库;但是,它仅允许减少或增加一定量的分贝。例如,如果我想将wav的体积减少一定百分比,该如何处理?

2 个答案:

答案 0 :(得分:1)

您可以使用mul function中的built-in audioop module。将分贝值转换为乘法因子后,pydub uses internally就是这样。

答案 1 :(得分:1)

这很简单,只需使用stdlib中的工具即可。

首先,您使用wave打开输入文件并创建输出文件:

pathout = os.path.splitext(path)[0] + '-quiet.wav' 
with wave.open(path, 'rb') as fin, wave.open(pathout, 'wb') as fout:

现在,您必须复制所有wave参数,并保留样本宽度以备后用:

fout.setparams(fin.getparams())
sampwidth = fin.getsampwidth()

然后遍历帧直到完成:

while True:
    frames = bytearray(fin.readframes(1024))
    if not frames:
        break

您可以使用audioop处理此数据:

frames = audioop.mul(frames, sampwidth, factor)

…但这仅适用于16位小尾数签名LPCM波形文件(最常见的一种,但不是唯一的一种)。您可以使用其他功能来解决该问题-最重要的是,lin2lin可处理8位无符号LPCM(第二种最常见的类型)。但是值得了解如何手动进行:

for i in range(0, len(frames), sampwidth):
    if sampwidth == 1:
        # 8-bit unsigned
        frames[i] = int(round((sample[0] - 128) * factor + 128)
    else:
        # 16-, 24-, or 32-bit signed
        sample = int.from_bytes(frames[i:i+sampwidth], 'little', signed=True)
        quiet = round(sample * factor)
        frames[i:i+sampwidth] = int(quiet).to_bytes(sampwidth, 'little', signed=True)

audioop.mul仅处理else部分,但是它比我在这里所做的更多。特别是,它必须处理因子大于1的情况-天真的乘法会削波,这只会增加怪异的失真而不会增加所需的最大能量。 (如果您想学习这本书的基础知识,则值得阅读the pure Python implementation from PyPy。)

如果您还想处理float32文件,则需要查看格式,因为它们与int32具有相同的sampwidth,并且您可能希望使用struct模块或{{ 1}}模块以打包和解压缩它们。如果要处理甚至不太常见的格式(例如a-law和µ-law),则需要阅读a more detailed format spec。请注意,array具有处理大多数工具的工具,例如audioop可以将µ-law转换为LPCM,因此您可以对其进行处理并将其转换回去,但是同样,值得学习如何做手动。对于其中的某些工具(例如CoolEdit float24 / 32),您几乎必须手动执行。

无论如何,一旦获得了安静的帧,就将它们写出来:

ulaw2lin