import numpy
import struct

_big_endian = False

# assumes file pointer is immediately
#  after the 'fmt ' id
def _read_fmt_chunk(fid):
    if _big_endian:
        fmt = '>'
    else:
        fmt = '<'
    res = struct.unpack(fmt+'ihHIIHH',fid.read(20))
    size, comp, noc, rate, sbytes, ba, bits = res
    if (comp != 1 or size > 16):
        print "Warning:  unfamiliar format bytes..."
        if (size>16):
            fid.read(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):
    if _big_endian:
        fmt = '>i'
    else:
        fmt = '<i'
    size = struct.unpack(fmt,fid.read(4))[0]
    if bits == 8:
        data = numpy.fromfile(fid, dtype=numpy.ubyte, count=size)
        if noc > 1:
            data = data.reshape(-1,noc)
    else:
        bytes = bits//8
        if _big_endian:
            dtype = '>i%d' % bytes
        else:
            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):
    global _big_endian
    str1 = fid.read(4)
    if str1 == 'RIFX':
        _big_endian = True
    elif str1 != 'RIFF':
        raise ValueError, "Not a WAV file."
    if _big_endian:
        fmt = '>I'
    else:
        fmt = '<I'
    fsize = struct.unpack(fmt, fid.read(4))[0] + 8
    str2 = fid.read(4)
    if (str2 != 'WAVE'):
        raise ValueError, "Not a WAV file."
    if str1 == 'RIFX':
        _big_endian = True
    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
    else:
        fid = open(file, 'rb')

    fsize = _read_riff_chunk(fid)
    noc = 1
    bits = 8
    while (fid.tell() < fsize):
        # read the next chunk
        chunk_id = fid.read(4)
        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)
        else:
            print "Warning:  %s chunk not understood"
            size = struct.unpack('I',fid.read(4))[0]
            bytes = fid.read(size)
    fid.close()
    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')
    fid.write('RIFF')
    fid.write('\x00\x00\x00\x00')
    fid.write('WAVE')
    # fmt chunk
    fid.write('fmt ')
    if data.ndim == 1:
        noc = 1
    else:
        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('data')
    fid.write(struct.pack('<i', data.nbytes))
    import sys
    if data.dtype.byteorder == '>' or (data.dtype.byteorder == '=' and sys.byteorder == 'big'):
        data = data.byteswap()
    data.tofile(fid)
    # Determine file size and place it in correct
    #  position at start of the file.
    size = fid.tell()
    fid.seek(4)
    fid.write(struct.pack('<i', size-8))
    fid.close()

@@ -19,16 +19,77 @@
 t struct
+%0Aimport warnings%0A%0Aclass WavFileWarning(UserWarning):%0A    pass
 %0A%0A_big_e
@@ -403,26 +403,24 @@
     
-print %22Warning:  u
+warnings.warn(%22U
 nfam
@@ -441,12 +441,26 @@
 ytes
-...%22
+%22, WavFileWarning)
 %0A   
@@ -1367,34 +1367,33 @@
 raise ValueError
-, 
+(
 %22Not a WAV file.
@@ -1385,32 +1385,33 @@
 Not a WAV file.%22
+)
 %0A    if _big_end
@@ -1586,18 +1586,17 @@
 lueError
-, 
+(
 %22Not a W
@@ -1604,16 +1604,17 @@
 V file.%22
+)
 %0A    if 
@@ -2257,46 +2257,8 @@
  ':%0A
-            print %22Reading fmt chunk%22%0A
     
@@ -2365,47 +2365,8 @@
 a':%0A
-            print %22Reading data chunk%22%0A
     
@@ -2443,28 +2443,23 @@
     
-print %22Warning:  %25s 
+warnings.warn(%22
 chun
@@ -2475,16 +2475,33 @@
 erstood%22
+, WavFileWarning)
 %0A       

remove debug prints from wavfile (fix #1051)