2012-11-11 17 views
10

Mam 2-sekundowy 16-bitowy, jednokanałowy plik wav 8khz i muszę zmienić jego głośność.Zmiana głośności pliku wav w pythoniu

Powinno być całkiem proste, ponieważ zmiana głośności jest taka sama, jak zmiana amplitudy sygnału, a ja po prostu muszę ją tłumić, to znaczy mnożyć ją dla liczby między 0 a 1. Ale nie robi tego ". t praca: nowy dźwięk jest niższy, ale BARDZO pełen hałasu. Co ja robię źle?

Oto mój kod:

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() 

Dziękuję chłopaki!

+2

Dlaczego używasz '* 5/10' zamiast'/2'? –

+1

Gdybym musiał zgadnąć, powiedziałbym, że część '* 5' jest wycinana i przepełniana. –

+2

Czy czytasz plik w poprawnej endianness? [Pliki WAV są mało-endianowe.] (Http://web.archive.org/web/19991115123323/http://www.borg.com/~jglatt/tech/wave.htm) Użycie innego endianu zmniejszy o połowę próbka i dodaj DUŻO hałasu. –

Odpowiedz

3

Jak widać w komentarzach na pytanie, istnieje kilka rozwiązań, niektóre bardziej wydajne.

Problem został natychmiast wykryty przez Jana Dvoraka (zwanego dalej „* 5 część jest wycinek i przepełnione”) i proste rozwiązanie było:

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

W tym przypadku rozwiązanie to było idealne dla mnie, po prostu dobre dość.

Dziękuję wszystkim!

11

Napisałem library to simplify this type of thing

Można to zrobić tak:

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") 
+0

Czy możesz zamiast tego złagodzić Mr. Astley'a o 36 dB? – msw

+0

@musi, że to będzie 'song = song - 36' – Jiaaro