Reading *.wav files in Python


Question

I need to analyze sound written in a .wav file. For that I need to transform this file into set of numbers (arrays, for example). I think I need to use the wave package. However, I do not know how exactly it works. For example I did the following:

import wave
w = wave.open('/usr/share/sounds/ekiga/voicemail.wav', 'r')
for i in range(w.getnframes()):
    frame = w.readframes(i)
    print frame

As a result of this code I expected to see sound pressure as function of time. In contrast I see a lot of strange, mysterious symbols (which are not hexadecimal numbers). Can anybody, pleas, help me with that?

1
71
1/30/2016 12:49:40 PM

Accepted Answer

Per the sources, scipy.io.wavfile.read(somefile) returns a tuple of two items: the first is the sampling rate in samples per second, the second is a numpy array with all the data read from the file. Looks pretty easy to use!

e.g:

from scipy.io import wavfile
fs, data = wavfile.read('./output/audio.wav')
79
4/6/2018 11:56:14 AM

I did some research this evening and figured this out:

import wave, struct

waveFile = wave.open('sine.wav', 'r')

length = waveFile.getnframes()
for i in range(0,length):
    waveData = waveFile.readframes(1)
    data = struct.unpack("<h", waveData)
    print(int(data[0]))

Hopefully this snippet helps someone. Details: using the struct module, you can take the wave frames (which are in 2s complementary binary between -32768; 0x8000 and 32767; 0x7FFF) This reads a MONO, 16-BIT, WAVE file. I found this webpage quite useful in formulating this.

This snippet reads 1 frame. To read more than one frame (e.g., 13), use

waveData = waveFile.readframes(13)
data = struct.unpack("<13h", waveData)

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon