Reading *.wav files in Python

271,784

Solution 1

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 wavfile
samplerate, data = wavfile.read('./output/audio.wav')

Solution 2

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, 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]))

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

wavedata = wavefile.readframes(13)
data = struct.unpack("<13h", wavedata)

Solution 3

Different Python modules to read wav:

There is at least these following libraries to read wave audio files:

The most simple example:

This is a simple example with SoundFile:

import soundfile as sf
data, 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 audiolab
from scipy.io import wavfile
from sys import argv
for 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 wavread
samplerate, x = wavread(audiofilename)  # x is a numpy array of integers, representing the samples 
# scale to -1.0 -- 1.0
if x.dtype == 'int16':
    nb_bits = 16  # -> 16-bit wav files
elif x.dtype == 'int32':
    nb_bits = 32  # -> 32-bit wav files
max_nb_bit = float(2 ** (nb_bits - 1))
samples = x / (max_nb_bit + 1)  # samples is a numpy array of floats representing the samples 

Solution 4

IMHO, the easiest way to get audio data from a sound file into a NumPy array is SoundFile:

import soundfile as sf
data, fs = sf.read('/usr/share/sounds/ekiga/voicemail.wav')

This also supports 24-bit files out of the box.

There are many sound file libraries available, I've written an overview where you can see a few pros and cons. It also features a page explaining how to read a 24-bit wav file with the wave module.

Solution 5

You can accomplish this using the scikits.audiolab module. It requires NumPy and SciPy to function, and also libsndfile.

Note, I was only able to get it to work on Ubunutu and not on OSX.

from scikits.audiolab import wavread

filename = "testfile.wav"

data, sample_frequency,encoding = wavread(filename)

Now you have the wav data

Share:
271,784

Related videos on Youtube

Roman
Author by

Roman

Updated on February 10, 2022

Comments

  • Roman
    Roman over 2 years

    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?

  • Roman
    Roman over 14 years
    OK. I just installed the SciPy but I cannot find any example of the usage of scipy.io.wavfile.
  • Ignacio Vazquez-Abrams
    Ignacio Vazquez-Abrams over 14 years
    Nothing like the interactive interpreter for figuring out how things work! Be ambitious!
  • endolith
    endolith over 13 years
    You can combine this with command line conversion tools to open other formats.
  • bastibe
    bastibe over 13 years
    It seriously lacks the number of channels though. How are you supposed to work with audio without knowing the number of channels?
  • Alex S
    Alex S almost 11 years
    throwns some weird struct unpacking errors on my computer. I think it's using struct.unpack('<i',data) instead of the struct.unpack('<h',data) nak used below.
  • Finn Årup Nielsen
    Finn Årup Nielsen over 10 years
    Does this library work? I run into a number of problems: scipy.io.wavfile.read('/usr/lib/python2.7/dist-packages/pyga‌​me/examples/data/hou‌​se_lo.wav') -> No data. scipy.io.wavfile.read('/usr/lib/python2.7/dist-packages/pyga‌​me/examples/data/sec‌​osmic_lo.wav') -> ZeroDivisionError: integer division or modulo by zero
  • Basj
    Basj over 10 years
    how to handle 24bits stereo files ?
  • Coder404
    Coder404 over 9 years
    this gives me the error: "struct.error: unpack requires a string argument of length 2"
  • ArthurLambert
    ArthurLambert about 9 years
    If you run this piece of code with a very big audio file. Your computer will be die to due the memory need by this program. Need to process audio file by block for big audio file
  • jmilloy
    jmilloy almost 9 years
    @Coder404 You probably have a stereo wave file, or a different bit depth.
  • Dennis Golomazov
    Dennis Golomazov over 8 years
    For those who, like me, are wondering what is 2s complementary binary, see here stackoverflow.com/questions/1049722/what-is-2s-complement
  • optimus prime
    optimus prime almost 8 years
    But what about 24 bit stereo file?
  • Quetzalcoatl
    Quetzalcoatl about 7 years
    Note: soundfile.read() normalizes by 2^(n_bits - 1) as in sandoval's scipy.io.wavfile example
  • jeromej
    jeromej about 7 years
    @Basj <hh maybe?
  • ATOMP
    ATOMP about 6 years
    @Coder404 To use struct.unpack, you have to specify the number of values encoded. For example, to read 11 values using struct.unpack, use struct.unpack("<11h", waveData)
  • dant
    dant about 6 years
    This is exactly what I was looking for, thanks for doing the digging! I don't know if I would have ever figured this out on my own.
  • stenlytw
    stenlytw about 6 years
    github.com/scipy/scipy/issues/1930#issuecomment-28460402 For anyone who needs to read 24 bit files, use wavio by Warren Weckesser: github.com/WarrenWeckesser/wavio
  • hobs
    hobs almost 5 years
    @bastibe data is a 2-D numpy array so data.shape returns a tuple of (num_samples, num_channels)
  • Derek Ledbetter
    Derek Ledbetter almost 5 years
    You can also try struct.iter_unpack.
  • Tigran Aivazian
    Tigran Aivazian over 4 years
    Using scipy.io.wavfile() won't work on 24bit WAV files. It will fail with ""Unsupported bit depth: the wav file has 24-bit data" error.
  • BlackJack
    BlackJack almost 4 years
    @FinnÅrupNielsen Yes it works. But WAV is a container format which can contain samples in many different formats/audio codecs. wavfile knows PCM samples and IEEE float samples. The house_lo.wav is 8 bit PCM and can be read on my machine. The secosmic_lo.wav contains Microsoft ADPCM samples which can't be read and result in a ValueError: Unknown wave file format here.
  • BlackJack
    BlackJack almost 4 years
    @ArthurLambert It won't die due to memory exhaustion. It will be slow but it doesn't use much memory at all.
  • BlackJack
    BlackJack almost 4 years
    Instead of the struct module I would use the array module or Numpy arrays. With struct the "<" is wrong by the way. The wave module converts the endianess to ”native” endieness, so "<" makes the code platform dependent.
  • Boris Verkhovskiy
    Boris Verkhovskiy over 3 years
    scikits.audiolab has not been updated since 2010 and it's probably Python 2 only.
  • Kedaar Rao
    Kedaar Rao over 3 years
    But when executed, the read returns an error: Error opening '../audio.wav': File contains data in an unimplemented format. The file I’m trying to open begins with: OggS Any idea what’s wrong here?
  • EntangledLoops
    EntangledLoops about 2 years
    @Matthias: I can see that you are the maintainer of soundfile, and also that you are posting on many stackoverflow audio-related posts and promoting soundfile as the solution everywhere. Whether or not your solution works, this isn't your personal advertising platform or Github. (You can be banned for this.)
  • hobs
    hobs about 2 years
    @hobs @bastibe correction: wavefile.read(...)[1].data is a np.ndarray so for a mono track it will be a 1-D array. For stereo 2-D array with .shape = (num_samples, 2)