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