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!
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:
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.
This way, no dependencies like pydub
or numpy
are needed.
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With