Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
110 lines (100 sloc) 3.25 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.