问题
I have a 2 seconds 16bit single channel 8khz wav file and I need to change its volume.
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. 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!
回答1:
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")
回答2:
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:
s = numpy.fromstring(s, numpy.int16) / 10 * 5
In this case, this solution was perfect for me, just good enough.
Thank you all folks!
来源:https://stackoverflow.com/questions/13329617/change-the-volume-of-a-wav-file-in-python