[英]Changing a wav file's volume using Python
我尝试过使用Pydub库; 但是,它仅允许减少或增加一定量的分贝。 例如,如果我想将wav的体积减少一定百分比,我将如何进行?
您可以使用内置audioop
模块中的mul
功能 。 这是pydub在将分贝值转换为乘法因子后内部使用的方法 。
这非常简单,仅使用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的情况-天真的乘法会削波,这只会增加怪异的失真而不会增加所需的最大能量。 (如果您想学习这些东西的基础知识,那么值得从PyPy阅读纯Python实现 。)
如果您还想处理float32文件,则需要查看格式,因为它们的sampwidth
与int32相同,并且您可能希望struct
模块或array
模块打包sampwidth
压缩它们。 如果您要处理甚至不太常见的格式(例如a-law和µ-law),则需要阅读更详细的格式规范 。 请注意, audioop
具有用于处理其中大多数工具的工具,例如ulaw2lin
可以将µ-law转换为LPCM,以便您可以对其进行处理并将其转换回来,但是同样,值得学习如何手动进行。 对于其中的某些工具(例如CoolEdit float24 / 32),您几乎必须手动执行。
无论如何,一旦获得了安静的帧,就将它们写出来:
fout.writeframes(frames)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.