简体   繁体   English

改变python中一个wav文件的音量

[英]Change the volume of a wav file in python

I have a 2 seconds 16bit single channel 8khz wav file and I need to change its volume.我有一个 2 秒 16 位单通道 8khz wav 文件,我需要更改它的音量。

It should be quite straightforward, because changing the volume is the same as changing the amplitude of the signal, and I just need to attenuate it, that is to multiply it for a number between 0 and 1. But it doesn't work: the new sound is lower but VERY full of noise.它应该很简单,因为改变音量和改变信号的幅度是一样的,我只需要衰减它,也就是乘以一个 0 到 1 之间的数字。但它不起作用:新的声音较低,但噪音很大。 What am I doing wrong?我究竟做错了什么?

Here is my code:这是我的代码:

import wave, numpy, struct

# Open
w = wave.open("input.wav","rb")
p = w.getparams()
f = p[3] # number of frames
s = w.readframes(f)
w.close()

# Edit
s = numpy.fromstring(s, numpy.int16) * 5 / 10  # half amplitude
s = struct.pack('h'*len(s), *s)

# Save
w = wave.open("output.wav","wb")
w.setparams(p)
w.writeframes(s)
w.close()

Thank you guys!感谢你们!

I wrote a library to simplify this type of thing我写了一个库来简化这种类型的事情

You can do that like so:你可以这样做:

from pydub import AudioSegment

song = AudioSegment.from_wav("never_gonna_give_you_up.wav")

# reduce volume by 10 dB
song_10_db_quieter = song - 10

# but let's make him *very* quiet
song = song - 36

# save the output
song.export("quieter.wav", "wav")

As you can see in the comments of the question, there are several solutions, some more efficient.正如您在问题的评论中看到的那样,有几种解决方案,其中一些更有效。

The problem was immediately detected by Jan Dvorak ("the * 5 part is clipping and overflowing") and the straightforward solution was: Jan Dvorak 立即发现了这个问题(“* 5 部分正在裁剪和溢出”),直接的解决方案是:

s = numpy.fromstring(s, numpy.int16) / 10 * 5

In this case, this solution was perfect for me, just good enough.在这种情况下,这个解决方案对我来说是完美的,刚刚好。

Thank you all folks!谢谢大家!

This can be done with the audioop module in Python's standard library.这可以通过 Python 标准库中的audioop模块来完成。 This way, no dependencies like pydub or numpy are needed.这样,不需要像pydubnumpy这样的依赖pydub

import wave, audioop

factor = 0.5

with wave.open('input.wav', 'rb') as wav:
    p = wav.getparams()
    with wave.open('output.wav', 'wb') as audio:
        audio.setparams(p)
        frames = wav.readframes(p.nframes)
        audio.writeframesraw( audioop.mul(frames, p.sampwidth, factor))

The code which makes sound louder plus filter low and high frequencies使声音更大的代码加上过滤低频和高频

from pydub import AudioSegment

audio_file = "first.mp3"

song = AudioSegment.from_mp3(audio_file)

new = song.low_pass_filter(1000)

new1 = new.high_pass_filter(1000)

# increae volume by 6 dB
song_6_db_quieter = new1 + 6

# save the output
song_6_db_quieter.export("C://Users//User//Desktop//second.mp3", "mp3")

Simple amplification can also be done easily with librosa :使用librosa也可以轻松完成简单的放大:

import librosa
import soundfile as sf

data, sr = librosa.load("input.wav")
factor = 0.5
data *= factor
sf.write("output.wav", data, sr)

Noise reduction is a more complicated problem.降噪是一个更复杂的问题。 Simpler approaches include low and high-pass filtering, but it generally depends heavily on the characteristics of your signal and the noise.更简单的方法包括低通和高通滤波,但它通常在很大程度上取决于信号和噪声的特性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM