#!/usr/bin/python
# -*- coding: UTF-8 -*-

#
# Copyright (C) 2006 by Hernán Ordiales
# <audiocode@uint8.com.ar>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#

try:
	import wave
	from sys import exit
	import math
	import array
	from pylab import fromstring, Int16, clip
	from FFT import fft, inverse_fft
except:
	print 'libraries import error!'
	sys.exit()


# at the moment only mono wav files

# Example: [ y, Fs, bits ] = wavread( 'filename' )
def wavread( name,verbose=False ):
	file = wave.open( name, 'r' )
	[Channels,Bytes,Fs,Frames,Compress,CompressName] = file.getparams() # (nchannels, sampwidth in bytes, sampling frequency, nframes, comptype, compname)
	Bits = Bytes*8 # 16 bits per sample
	Data = file.readframes( Frames )
	Data = fromstring( Data, Int16 ) / 32767.0 # -1..1 values, Int16 because Bits=2x8=16
	if verbose:
		print "Fs: ",Fs,"\nBits: ",Bits,"\nChannels: ",Channels
	file.close()
	return Data, Fs, Bits

# Example: wavwrite( y, Fs, filename )
def wavwrite( data_array, Fs, name ):
	file = wave.open( name, 'w' )
	file.setframerate( Fs ) # sets sampling frequency
	file.setnchannels( 1 ) # sets number of channels
	file.setsampwidth( 2 ) # number of bytes: 16bits/8=2, 16 bits per sample

	clipped = False
	block_size = 1024*10 # write block size: 10k
	a_max = 32767 # max amp
	a_min = -32767 # min amp
	n = 0
	len_data_array = len( data_array ) # 2 bytes (int16) data
	while n < len_data_array :
		frame = '' # string frame of 'block_size'
		for i in range( block_size ) :
			if n < len_data_array :
				twodatabytes = int( data_array[n] * a_max )
				if twodatabytes > a_max or twodatabytes < a_min : clipped = True
				twodatabytes = min( max(twodatabytes,a_min), a_max ) # normalization, -32767..32767
				#twodatabytes.clip( min=a_min, max=a_max ) # normalization, -32767..32767
				frame += chr( twodatabytes & 0xFF ) # takes first byte, converts it to char and adds it to the frame
				frame += chr( (twodatabytes >> 8) & 0xFF ) # takes the second byte
				n += 1
		file.writeframes( frame )
	if clipped == True : print "Warning: Some values were clipped"
	print "Final length:", len_data_array/512,"kb" # n*2/1024 (bytes size/1024) = n/512
	file.close()
	
