Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

110 lines (100 sloc) 3.327 kb
import numpy
import struct
# assumes file pointer is immediately
# after the 'fmt ' id
def _read_fmt_chunk(fid):
res = struct.unpack('ihHIIHH',
size, comp, noc, rate, sbytes, ba, bits = res
if (comp != 1 or size > 16):
print "Warning: unfamiliar format bytes..."
if (size>16):
return size, comp, noc, rate, sbytes, ba, bits
# assumes file pointer is immediately
# after the 'data' id
def _read_data_chunk(fid, noc, bits):
size = struct.unpack('i',[0]
if bits == 8:
data = numpy.fromfile(fid, dtype=numpy.ubyte, count=size)
if noc > 1:
data = data.reshape(-1,noc)
bytes = bits//8
dtype = 'i%d' % bytes
data = numpy.fromfile(fid, dtype=dtype, count=size//bytes)
if noc > 1:
data = data.reshape(-1,noc)
return data
def _read_riff_chunk(fid):
str1 =
fsize = struct.unpack('I',[0] + 8
str2 =
if (str1 != 'RIFF' or str2 != 'WAVE'):
raise ValueError, "Not a WAV file."
return fsize
# open a wave-file
def read(file):
"""Return the sample rate (in samples/sec) and data from a WAV file
The file can be an open file or a filename.
The returned sample rate is a Python integer
The data is returned as a numpy array with a
data-type determined from the file.
if hasattr(file,'read'):
fid = file
fid = open(file, 'rb')
fsize = _read_riff_chunk(fid)
noc = 1
bits = 8
while (fid.tell() < fsize):
# read the next chunk
chunk_id =
if chunk_id == 'fmt ':
print "Reading fmt chunk"
size, comp, noc, rate, sbytes, ba, bits = _read_fmt_chunk(fid)
elif chunk_id == 'data':
print "Reading data chunk"
data = _read_data_chunk(fid, noc, bits)
print "Warning: %s chunk not understood"
size = struct.unpack('I',[0]
bytes =
return rate, data
# Write a wave-file
# sample rate, data
def write(filename, rate, data):
"""Write a numpy array as a WAV file
filename -- The name of the file to write (will be over-written)
rate -- The sample rate (in samples/sec).
data -- A 1-d or 2-d numpy array of integer data-type.
The bits-per-sample will be determined by the data-type
To write multiple-channels, use a 2-d array of shape
(Nsamples, Nchannels)
Writes a simple uncompressed WAV file.
fid = open(filename, 'wb')
# fmt chunk
fid.write('fmt ')
if data.ndim == 1:
noc = 1
noc = data.shape[1]
bits = data.dtype.itemsize * 8
sbytes = rate*(bits / 8)*noc
ba = noc * (bits / 8)
fid.write(struct.pack('ihHIIHH', 16, 1, noc, rate, sbytes, ba, bits))
# data chunk
fid.write(struct.pack('i', data.nbytes))
# Determine file size and place it in correct
# position at start of the file.
size = fid.tell()
fid.write(struct.pack('i', size-8))
Jump to Line
Something went wrong with that request. Please try again.