Reading *.wav files in Python
Per the documentation, 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:
from scipy.io import wavfilesamplerate, data = wavfile.read('./output/audio.wav')
Using the struct
module, you can take the wave frames (which are in 2's complementary binary between -32768 and 32767 (i.e. 0x8000
and 0x7FFF
). This reads a MONO, 16-BIT, WAVE file. I found this webpage quite useful in formulating this:
import wave, structwavefile = 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]))
This snippet reads 1 frame. To read more than one frame (e.g., 13), use
wavedata = wavefile.readframes(13)data = struct.unpack("<13h", wavedata)
Different Python modules to read wav:
There is at least these following libraries to read wave audio files:
- SoundFile
- scipy.io.wavfile (from scipy)
- wave (to read streams. Included in Python 2 and 3)
- scikits.audiolab (unmaintained since 2010)
- sounddevice (play and record sounds, good for streams and real-time)
- pyglet
- librosa (music and audio analysis)
- madmom (strong focus on music information retrieval (MIR) tasks)
The most simple example:
This is a simple example with SoundFile:
import soundfile as sfdata, samplerate = sf.read('existing_file.wav')
Format of the output:
Warning, the data are not always in the same format, that depends on the library. For instance:
from scikits import audiolabfrom scipy.io import wavfilefrom sys import argvfor filepath in argv[1:]: x, fs, nb_bits = audiolab.wavread(filepath) print('Reading with scikits.audiolab.wavread:', x) fs, x = wavfile.read(filepath) print('Reading with scipy.io.wavfile.read:', x)
Output:
Reading with scikits.audiolab.wavread: [ 0. 0. 0. ..., -0.00097656 -0.00079346 -0.00097656]Reading with scipy.io.wavfile.read: [ 0 0 0 ..., -32 -26 -32]
SoundFile and Audiolab return floats between -1 and 1 (as matab does, that is the convention for audio signals). Scipy and wave return integers, which you can convert to floats according to the number of bits of encoding, for example:
from scipy.io.wavfile import read as wavreadsamplerate, x = wavread(audiofilename) # x is a numpy array of integers, representing the samples # scale to -1.0 -- 1.0if x.dtype == 'int16': nb_bits = 16 # -> 16-bit wav fileselif x.dtype == 'int32': nb_bits = 32 # -> 32-bit wav filesmax_nb_bit = float(2 ** (nb_bits - 1))samples = x / (max_nb_bit + 1) # samples is a numpy array of floats representing the samples