[英]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.