# Stuff to parse AIFF-C and AIFF files.
#
# Unless explicitly stated otherwise, the description below is true
# both for AIFF-C files and AIFF files.
#
# An AIFF-C file has the following structure.
#
#	+-----------------+
#	| FORM            |
#	+-----------------+
#	| <size>          |
#	+----+------------+
#	|    | AIFC       |
#	|    +------------+
#	|    | <chunks>   |
#	|    |    .       |
#	|    |    .       |
#	|    |    .       |
#	+----+------------+
#
# An AIFF file has the string "AIFF" instead of "AIFC".
#
# A chunk consists of an identifier (4 bytes) followed by a size (4 bytes,
# big endian order), followed by the data.  The size field does not include
# the size of the 8 byte header.
#
# The following chunk types are recognized.
#
#	FVER
#		<version number of AIFF-C defining document> (AIFF-C only).
#	MARK
#		<# of markers> (2 bytes)
#		list of markers:
#			<marker ID> (2 bytes, must be > 0)
#			<position> (4 bytes)
#			<marker name> ("pstring")
#	COMM
#		<# of channels> (2 bytes)
#		<# of sound frames> (4 bytes)
#		<size of the samples> (2 bytes)
#		<sampling frequency> (10 bytes, IEEE 80-bit extended
#			floating point)
#		in AIFF-C files only:
#		<compression type> (4 bytes)
#		<human-readable version of compression type> ("pstring")
#	SSND
#		<offset> (4 bytes, not used by this program)
#		<blocksize> (4 bytes, not used by this program)
#		<sound data>
#
# A pstring consists of 1 byte length, a string of characters, and 0 or 1
# byte pad to make the total length even.
#
# Usage.
#
# Reading AIFF files:
#	f = aifc.open(file, 'r')
# where file is either the name of a file or an open file pointer.
# The open file pointer must have methods read(), seek(), and close().
# In some types of audio files, if the setpos() method is not used,
# the seek() method is not necessary.
#
# This returns an instance of a class with the following public methods:
#	getnchannels()	-- returns number of audio channels (1 for
#			   mono, 2 for stereo)
#	getsampwidth()	-- returns sample width in bytes
#	getframerate()	-- returns sampling frequency
#	getnframes()	-- returns number of audio frames
#	getcomptype()	-- returns compression type ('NONE' for AIFF files)
#	getcompname()	-- returns human-readable version of
#			   compression type ('not compressed' for AIFF files)
#	getparams()	-- returns a tuple consisting of all of the
#			   above in the above order
#	getmarkers()	-- get the list of marks in the audio file or None
#			   if there are no marks
#	getmark(id)	-- get mark with the specified id (raises an error
#			   if the mark does not exist)
#	readframes(n)	-- returns at most n frames of audio
#	rewind()	-- rewind to the beginning of the audio stream
#	setpos(pos)	-- seek to the specified position
#	tell()		-- return the current position
#	close()		-- close the instance (make it unusable)
# The position returned by tell(), the position given to setpos() and
# the position of marks are all compatible and have nothing to do with
# the actual postion in the file.
# The close() method is called automatically when the class instance
# is destroyed.
#
# Writing AIFF files:
#	f = aifc.open(file, 'w')
# where file is either the name of a file or an open file pointer.
# The open file pointer must have methods write(), tell(), seek(), and
# close().
#
# This returns an instance of a class with the following public methods:
#	aiff()		-- create an AIFF file (AIFF-C default)
#	aifc()		-- create an AIFF-C file
#	setnchannels(n)	-- set the number of channels
#	setsampwidth(n)	-- set the sample width
#	setframerate(n)	-- set the frame rate
#	setnframes(n)	-- set the number of frames
#	setcomptype(type, name)
#			-- set the compression type and the
#			   human-readable compression type
#	setparams(tuple)
#			-- set all parameters at once
#	setmark(id, pos, name)
#			-- add specified mark to the list of marks
#	tell()		-- return current position in output file (useful
#			   in combination with setmark())
#	writeframesraw(data)
#			-- write audio frames without pathing up the
#			   file header
#	writeframes(data)
#			-- write audio frames and patch up the file header
#	close()		-- patch up the file header and close the
#			   output file
# You should set the parameters before the first writeframesraw or
# writeframes.  The total number of frames does not need to be set,
# but when it is set to the correct value, the header does not have to
# be patched up.
# It is best to first set all parameters, perhaps possibly the
# compression type, and then write audio frames using writeframesraw.
# When all frames have been written, either call writeframes('') or
# close() to patch up the sizes in the header.
# Marks can be added anytime.  If there are any marks, ypu must call
# close() after all frames have been written.
# The close() method is called automatically when the class instance
# is destroyed.
#
# When a file is opened with the extension '.aiff', an AIFF file is
# written, otherwise an AIFF-C file is written.  This default can be
# changed by calling aiff() or aifc() before the first writeframes or
# writeframesraw.

import struct
import __builtin__

Error = 'aifc.Error'

_AIFC_version = 0xA2805140		# Version 1 of AIFF-C

_skiplist = 'COMT', 'INST', 'MIDI', 'AESD', \
	  'APPL', 'NAME', 'AUTH', '(c) ', 'ANNO'

def _read_long(file):
	try:
		return struct.unpack('>l', file.read(4))[0]
	except struct.error:
		raise EOFError

def _read_ulong(file):
	try:
		return struct.unpack('>L', file.read(4))[0]
	except struct.error:
		raise EOFError

def _read_short(file):
	try:
		return struct.unpack('>h', file.read(2))[0]
	except struct.error:
		raise EOFError

def _read_string(file):
	length = ord(file.read(1))
	if length == 0:
		data = ''
	else:
		data = file.read(length)
	if length & 1 == 0:
		dummy = file.read(1)
	return data

_HUGE_VAL = 1.79769313486231e+308 # See <limits.h>

def _read_float(f): # 10 bytes
	import math
	expon = _read_short(f) # 2 bytes
	sign = 1
	if expon < 0:
		sign = -1
		expon = expon + 0x8000
	himant = _read_ulong(f) # 4 bytes
	lomant = _read_ulong(f) # 4 bytes
	if expon == himant == lomant == 0:
		f = 0.0
	elif expon == 0x7FFF:
		f = _HUGE_VAL
	else:
		expon = expon - 16383
		f = (himant * 0x100000000L + lomant) * pow(2.0, expon - 63)
	return sign * f

def _write_short(f, x):
	f.write(struct.pack('>h', x))

def _write_long(f, x):
	f.write(struct.pack('>L', x))

def _write_string(f, s):
	f.write(chr(len(s)))
	f.write(s)
	if len(s) & 1 == 0:
		f.write(chr(0))

def _write_float(f, x):
	import math
	if x < 0:
		sign = 0x8000
		x = x * -1
	else:
		sign = 0
	if x == 0:
		expon = 0
		himant = 0
		lomant = 0
	else:
		fmant, expon = math.frexp(x)
		if expon > 16384 or fmant >= 1:		# Infinity or NaN
			expon = sign|0x7FFF
			himant = 0
			lomant = 0
		else:					# Finite
			expon = expon + 16382
			if expon < 0:			# denormalized
				fmant = math.ldexp(fmant, expon)
				expon = 0
			expon = expon | sign
			fmant = math.ldexp(fmant, 32)
			fsmant = math.floor(fmant)
			himant = long(fsmant)
			fmant = math.ldexp(fmant - fsmant, 32)
			fsmant = math.floor(fmant)
			lomant = long(fsmant)
	_write_short(f, expon)
	_write_long(f, himant)
	_write_long(f, lomant)

from chunk import Chunk

class Aifc_read:
	# Variables used in this class:
	#
	# These variables are available to the user though appropriate
	# methods of this class:
	# _file -- the open file with methods read(), close(), and seek()
	#		set through the __init__() method
	# _nchannels -- the number of audio channels
	#		available through the getnchannels() method
	# _nframes -- the number of audio frames
	#		available through the getnframes() method
	# _sampwidth -- the number of bytes per audio sample
	#		available through the getsampwidth() method
	# _framerate -- the sampling frequency
	#		available through the getframerate() method
	# _comptype -- the AIFF-C compression type ('NONE' if AIFF)
	#		available through the getcomptype() method
	# _compname -- the human-readable AIFF-C compression type
	#		available through the getcomptype() method
	# _markers -- the marks in the audio file
	#		available through the getmarkers() and getmark()
	#		methods
	# _soundpos -- the position in the audio stream
	#		available through the tell() method, set through the
	#		setpos() method
	#
	# These variables are used internally only:
	# _version -- the AIFF-C version number
	# _decomp -- the decompressor from builtin module cl
	# _comm_chunk_read -- 1 iff the COMM chunk has been read
	# _aifc -- 1 iff reading an AIFF-C file
	# _ssnd_seek_needed -- 1 iff positioned correctly in audio
	#		file for readframes()
	# _ssnd_chunk -- instantiation of a chunk class for the SSND chunk
	# _framesize -- size of one frame in the file

	def initfp(self, file):
		self._version = 0
		self._decomp = None
		self._convert = None
		self._markers = []
		self._soundpos = 0
		self._file = Chunk(file)
		if self._file.getname() != 'FORM':
			raise Error, 'file does not start with FORM id'
		formdata = self._file.read(4)
		if formdata == 'AIFF':
			self._aifc = 0
		elif formdata == 'AIFC':
			self._aifc = 1
		else:
			raise Error, 'not an AIFF or AIFF-C file'
		self._comm_chunk_read = 0
		while 1:
			self._ssnd_seek_needed = 1
			#DEBUG: SGI's soundfiler has a bug.  There should
			# be no need to check for EOF here.
			try:
				chunk = Chunk(self._file)
			except EOFError:
				break
			chunkname = chunk.getname()
			if chunkname == 'COMM':
				self._read_comm_chunk(chunk)
				self._comm_chunk_read = 1
			elif chunkname == 'SSND':
				self._ssnd_chunk = chunk
				dummy = chunk.read(8)
				self._ssnd_seek_needed = 0
			elif chunkname == 'FVER':
				self._version = _read_long(chunk)
			elif chunkname == 'MARK':
				self._readmark(chunk)
			elif chunkname in _skiplist:
				pass
			else:
				raise Error, 'unrecognized chunk type '+chunk.chunkname
			chunk.skip()
		if not self._comm_chunk_read or not self._ssnd_chunk:
			raise Error, 'COMM chunk and/or SSND chunk missing'
		if self._aifc and self._decomp:
			import cl
			params = [cl.ORIGINAL_FORMAT, 0,
				  cl.BITS_PER_COMPONENT, self._sampwidth * 8,
				  cl.FRAME_RATE, self._framerate]
			if self._nchannels == 1:
				params[1] = cl.MONO
			elif self._nchannels == 2:
				params[1] = cl.STEREO_INTERLEAVED
			else:
				raise Error, 'cannot compress more than 2 channels'
			self._decomp.SetParams(params)

	def __init__(self, f):
		if type(f) == type(''):
			f = __builtin__.open(f, 'rb')
		# else, assume it is an open file object already
		self.initfp(f)

	def __del__(self):
		if self._file:
			self.close()

	#
	# User visible methods.
	#
	def getfp(self):
		return self._file

	def rewind(self):
		self._ssnd_seek_needed = 1
		self._soundpos = 0

	def close(self):
		if self._decomp:
			self._decomp.CloseDecompressor()
			self._decomp = None
		self._file = None

	def tell(self):
		return self._soundpos

	def getnchannels(self):
		return self._nchannels

	def getnframes(self):
		return self._nframes

	def getsampwidth(self):
		return self._sampwidth

	def getframerate(self):
		return self._framerate

	def getcomptype(self):
		return self._comptype

	def getcompname(self):
		return self._compname

##	def getversion(self):
##		return self._version

	def getparams(self):
		return self.getnchannels(), self.getsampwidth(), \
			  self.getframerate(), self.getnframes(), \
			  self.getcomptype(), self.getcompname()

	def getmarkers(self):
		if len(self._markers) == 0:
			return None
		return self._markers

	def getmark(self, id):
		for marker in self._markers:
			if id == marker[0]:
				return marker
		raise Error, 'marker ' + `id` + ' does not exist'

	def setpos(self, pos):
		if pos < 0 or pos > self._nframes:
			raise Error, 'position not in range'
		self._soundpos = pos
		self._ssnd_seek_needed = 1

	def readframes(self, nframes):
		if self._ssnd_seek_needed:
			self._ssnd_chunk.seek(0)
			dummy = self._ssnd_chunk.read(8)
			pos = self._soundpos * self._framesize
			if pos:
				self._ssnd_chunk.setpos(pos + 8)
			self._ssnd_seek_needed = 0
		if nframes == 0:
			return ''
		data = self._ssnd_chunk.read(nframes * self._framesize)
		if self._convert and data:
			data = self._convert(data)
		self._soundpos = self._soundpos + len(data) / (self._nchannels * self._sampwidth)
		return data

	#
	# Internal methods.
	#

	def _decomp_data(self, data):
		import cl
		dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE,
					      len(data) * 2)
		return self._decomp.Decompress(len(data) / self._nchannels,
					       data)

	def _ulaw2lin(self, data):
		import audioop
		return audioop.ulaw2lin(data, 2)

	def _adpcm2lin(self, data):
		import audioop
		if not hasattr(self, '_adpcmstate'):
			# first time
			self._adpcmstate = None
		data, self._adpcmstate = audioop.adpcm2lin(data, 2,
							   self._adpcmstate)
		return data

	def _read_comm_chunk(self, chunk):
		self._nchannels = _read_short(chunk)
		self._nframes = _read_long(chunk)
		self._sampwidth = (_read_short(chunk) + 7) / 8
		self._framerate = int(_read_float(chunk))
		self._framesize = self._nchannels * self._sampwidth
		if self._aifc:
			#DEBUG: SGI's soundeditor produces a bad size :-(
			kludge = 0
			if chunk.chunksize == 18:
				kludge = 1
				print 'Warning: bad COMM chunk size'
				chunk.chunksize = 23
			#DEBUG end
			self._comptype = chunk.read(4)
			#DEBUG start
			if kludge:
				length = ord(chunk.file.read(1))
				if length & 1 == 0:
					length = length + 1
				chunk.chunksize = chunk.chunksize + length
				chunk.file.seek(-1, 1)
			#DEBUG end
			self._compname = _read_string(chunk)
			if self._comptype != 'NONE':
				if self._comptype == 'G722':
					try:
						import audioop
					except ImportError:
						pass
					else:
						self._convert = self._adpcm2lin
						self._framesize = self._framesize / 4
						return
				# for ULAW and ALAW try Compression Library
				try:
					import cl
				except ImportError:
					if self._comptype == 'ULAW':
						try:
							import audioop
							self._convert = self._ulaw2lin
							self._framesize = self._framesize / 2
							return
						except ImportError:
							pass
					raise Error, 'cannot read compressed AIFF-C files'
				if self._comptype == 'ULAW':
					scheme = cl.G711_ULAW
					self._framesize = self._framesize / 2
				elif self._comptype == 'ALAW':
					scheme = cl.G711_ALAW
					self._framesize = self._framesize / 2
				else:
					raise Error, 'unsupported compression type'
				self._decomp = cl.OpenDecompressor(scheme)
				self._convert = self._decomp_data
		else:
			self._comptype = 'NONE'
			self._compname = 'not compressed'

	def _readmark(self, chunk):
		nmarkers = _read_short(chunk)
		# Some files appear to contain invalid counts.
		# Cope with this by testing for EOF.
		try:
			for i in range(nmarkers):
				id = _read_short(chunk)
				pos = _read_long(chunk)
				name = _read_string(chunk)
				if pos or name:
					# some files appear to have
					# dummy markers consisting of
					# a position 0 and name ''
					self._markers.append((id, pos, name))
		except EOFError:
			print 'Warning: MARK chunk contains only',
			print len(self._markers),
			if len(self._markers) == 1: print 'marker',
			else: print 'markers',
			print 'instead of', nmarkers

class Aifc_write:
	# Variables used in this class:
	#
	# These variables are user settable through appropriate methods
	# of this class:
	# _file -- the open file with methods write(), close(), tell(), seek()
	#		set through the __init__() method
	# _comptype -- the AIFF-C compression type ('NONE' in AIFF)
	#		set through the setcomptype() or setparams() method
	# _compname -- the human-readable AIFF-C compression type
	#		set through the setcomptype() or setparams() method
	# _nchannels -- the number of audio channels
	#		set through the setnchannels() or setparams() method
	# _sampwidth -- the number of bytes per audio sample
	#		set through the setsampwidth() or setparams() method
	# _framerate -- the sampling frequency
	#		set through the setframerate() or setparams() method
	# _nframes -- the number of audio frames written to the header
	#		set through the setnframes() or setparams() method
	# _aifc -- whether we're writing an AIFF-C file or an AIFF file
	#		set through the aifc() method, reset through the
	#		aiff() method
	#
	# These variables are used internally only:
	# _version -- the AIFF-C version number
	# _comp -- the compressor from builtin module cl
	# _nframeswritten -- the number of audio frames actually written
	# _datalength -- the size of the audio samples written to the header
	# _datawritten -- the size of the audio samples actually written

	def __init__(self, f):
		if type(f) == type(''):
			filename = f
			f = __builtin__.open(f, 'wb')
		else:
			# else, assume it is an open file object already
			filename = '???'
		self.initfp(f)
		if filename[-5:] == '.aiff':
			self._aifc = 0
		else:
			self._aifc = 1

	def initfp(self, file):
		self._file = file
		self._version = _AIFC_version
		self._comptype = 'NONE'
		self._compname = 'not compressed'
		self._comp = None
		self._convert = None
		self._nchannels = 0
		self._sampwidth = 0
		self._framerate = 0
		self._nframes = 0
		self._nframeswritten = 0
		self._datawritten = 0
		self._datalength = 0
		self._markers = []
		self._marklength = 0
		self._aifc = 1		# AIFF-C is default

	def __del__(self):
		if self._file:
			self.close()

	#
	# User visible methods.
	#
	def aiff(self):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		self._aifc = 0

	def aifc(self):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		self._aifc = 1

	def setnchannels(self, nchannels):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		if nchannels < 1:
			raise Error, 'bad # of channels'
		self._nchannels = nchannels

	def getnchannels(self):
		if not self._nchannels:
			raise Error, 'number of channels not set'
		return self._nchannels

	def setsampwidth(self, sampwidth):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		if sampwidth < 1 or sampwidth > 4:
			raise Error, 'bad sample width'
		self._sampwidth = sampwidth

	def getsampwidth(self):
		if not self._sampwidth:
			raise Error, 'sample width not set'
		return self._sampwidth

	def setframerate(self, framerate):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		if framerate <= 0:
			raise Error, 'bad frame rate'
		self._framerate = framerate

	def getframerate(self):
		if not self._framerate:
			raise Error, 'frame rate not set'
		return self._framerate

	def setnframes(self, nframes):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		self._nframes = nframes

	def getnframes(self):
		return self._nframeswritten

	def setcomptype(self, comptype, compname):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
			raise Error, 'unsupported compression type'
		self._comptype = comptype
		self._compname = compname

	def getcomptype(self):
		return self._comptype

	def getcompname(self):
		return self._compname

##	def setversion(self, version):
##		if self._nframeswritten:
##			raise Error, 'cannot change parameters after starting to write'
##		self._version = version

	def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
			raise Error, 'unsupported compression type'
		self.setnchannels(nchannels)
		self.setsampwidth(sampwidth)
		self.setframerate(framerate)
		self.setnframes(nframes)
		self.setcomptype(comptype, compname)

	def getparams(self):
		if not self._nchannels or not self._sampwidth or not self._framerate:
			raise Error, 'not all parameters set'
		return self._nchannels, self._sampwidth, self._framerate, \
			  self._nframes, self._comptype, self._compname

	def setmark(self, id, pos, name):
		if id <= 0:
			raise Error, 'marker ID must be > 0'
		if pos < 0:
			raise Error, 'marker position must be >= 0'
		if type(name) != type(''):
			raise Error, 'marker name must be a string'
		for i in range(len(self._markers)):
			if id == self._markers[i][0]:
				self._markers[i] = id, pos, name
				return
		self._markers.append((id, pos, name))

	def getmark(self, id):
		for marker in self._markers:
			if id == marker[0]:
				return marker
		raise Error, 'marker ' + `id` + ' does not exist'

	def getmarkers(self):
		if len(self._markers) == 0:
			return None
		return self._markers
				
	def tell(self):
		return self._nframeswritten

	def writeframesraw(self, data):
		self._ensure_header_written(len(data))
		nframes = len(data) / (self._sampwidth * self._nchannels)
		if self._convert:
			data = self._convert(data)
		self._file.write(data)
		self._nframeswritten = self._nframeswritten + nframes
		self._datawritten = self._datawritten + len(data)

	def writeframes(self, data):
		self.writeframesraw(data)
		if self._nframeswritten != self._nframes or \
			  self._datalength != self._datawritten:
			self._patchheader()

	def close(self):
		self._ensure_header_written(0)
		if self._datawritten & 1:
			# quick pad to even size
			self._file.write(chr(0))
			self._datawritten = self._datawritten + 1
		self._writemarkers()
		if self._nframeswritten != self._nframes or \
			  self._datalength != self._datawritten or \
			  self._marklength:
			self._patchheader()
		if self._comp:
			self._comp.CloseCompressor()
			self._comp = None
		self._file.flush()
		self._file = None

	#
	# Internal methods.
	#

	def _comp_data(self, data):
		import cl
		dum = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data))
		dum = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data))
		return self._comp.Compress(self._nframes, data)

	def _lin2ulaw(self, data):
		import audioop
		return audioop.lin2ulaw(data, 2)

	def _lin2adpcm(self, data):
		import audioop
		if not hasattr(self, '_adpcmstate'):
			self._adpcmstate = None
		data, self._adpcmstate = audioop.lin2adpcm(data, 2,
							   self._adpcmstate)
		return data

	def _ensure_header_written(self, datasize):
		if not self._nframeswritten:
			if self._comptype in ('ULAW', 'ALAW'):
				if not self._sampwidth:
					self._sampwidth = 2
				if self._sampwidth != 2:
					raise Error, 'sample width must be 2 when compressing with ULAW or ALAW'
			if self._comptype == 'G722':
				if not self._sampwidth:
					self._sampwidth = 2
				if self._sampwidth != 2:
					raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)'
			if not self._nchannels:
				raise Error, '# channels not specified'
			if not self._sampwidth:
				raise Error, 'sample width not specified'
			if not self._framerate:
				raise Error, 'sampling rate not specified'
			self._write_header(datasize)

	def _init_compression(self):
		if self._comptype == 'G722':
			import audioop
			self._convert = self._lin2adpcm
			return
		try:
			import cl
		except ImportError:
			if self._comptype == 'ULAW':
				try:
					import audioop
					self._convert = self._lin2ulaw
					return
				except ImportError:
					pass
			raise Error, 'cannot write compressed AIFF-C files'
		if self._comptype == 'ULAW':
			scheme = cl.G711_ULAW
		elif self._comptype == 'ALAW':
			scheme = cl.G711_ALAW
		else:
			raise Error, 'unsupported compression type'
		self._comp = cl.OpenCompressor(scheme)
		params = [cl.ORIGINAL_FORMAT, 0,
			  cl.BITS_PER_COMPONENT, self._sampwidth * 8,
			  cl.FRAME_RATE, self._framerate,
			  cl.FRAME_BUFFER_SIZE, 100,
			  cl.COMPRESSED_BUFFER_SIZE, 100]
		if self._nchannels == 1:
			params[1] = cl.MONO
		elif self._nchannels == 2:
			params[1] = cl.STEREO_INTERLEAVED
		else:
			raise Error, 'cannot compress more than 2 channels'
		self._comp.SetParams(params)
		# the compressor produces a header which we ignore
		dummy = self._comp.Compress(0, '')
		self._convert = self._comp_data

	def _write_header(self, initlength):
		if self._aifc and self._comptype != 'NONE':
			self._init_compression()
		self._file.write('FORM')
		if not self._nframes:
			self._nframes = initlength / (self._nchannels * self._sampwidth)
		self._datalength = self._nframes * self._nchannels * self._sampwidth
		if self._datalength & 1:
			self._datalength = self._datalength + 1
		if self._aifc:
			if self._comptype in ('ULAW', 'ALAW'):
				self._datalength = self._datalength / 2
				if self._datalength & 1:
					self._datalength = self._datalength + 1
			elif self._comptype == 'G722':
				self._datalength = (self._datalength + 3) / 4
				if self._datalength & 1:
					self._datalength = self._datalength + 1
		self._form_length_pos = self._file.tell()
		commlength = self._write_form_length(self._datalength)
		if self._aifc:
			self._file.write('AIFC')
			self._file.write('FVER')
			_write_long(self._file, 4)
			_write_long(self._file, self._version)
		else:
			self._file.write('AIFF')
		self._file.write('COMM')
		_write_long(self._file, commlength)
		_write_short(self._file, self._nchannels)
		self._nframes_pos = self._file.tell()
		_write_long(self._file, self._nframes)
		_write_short(self._file, self._sampwidth * 8)
		_write_float(self._file, self._framerate)
		if self._aifc:
			self._file.write(self._comptype)
			_write_string(self._file, self._compname)
		self._file.write('SSND')
		self._ssnd_length_pos = self._file.tell()
		_write_long(self._file, self._datalength + 8)
		_write_long(self._file, 0)
		_write_long(self._file, 0)

	def _write_form_length(self, datalength):
		if self._aifc:
			commlength = 18 + 5 + len(self._compname)
			if commlength & 1:
				commlength = commlength + 1
			verslength = 12
		else:
			commlength = 18
			verslength = 0
		_write_long(self._file, 4 + verslength + self._marklength + \
					8 + commlength + 16 + datalength)
		return commlength

	def _patchheader(self):
		curpos = self._file.tell()
		if self._datawritten & 1:
			datalength = self._datawritten + 1
			self._file.write(chr(0))
		else:
			datalength = self._datawritten
		if datalength == self._datalength and \
			  self._nframes == self._nframeswritten and \
			  self._marklength == 0:
			self._file.seek(curpos, 0)
			return
		self._file.seek(self._form_length_pos, 0)
		dummy = self._write_form_length(datalength)
		self._file.seek(self._nframes_pos, 0)
		_write_long(self._file, self._nframeswritten)
		self._file.seek(self._ssnd_length_pos, 0)
		_write_long(self._file, datalength + 8)
		self._file.seek(curpos, 0)
		self._nframes = self._nframeswritten
		self._datalength = datalength

	def _writemarkers(self):
		if len(self._markers) == 0:
			return
		self._file.write('MARK')
		length = 2
		for marker in self._markers:
			id, pos, name = marker
			length = length + len(name) + 1 + 6
			if len(name) & 1 == 0:
				length = length + 1
		_write_long(self._file, length)
		self._marklength = length + 8
		_write_short(self._file, len(self._markers))
		for marker in self._markers:
			id, pos, name = marker
			_write_short(self._file, id)
			_write_long(self._file, pos)
			_write_string(self._file, name)

def open(f, mode=None):
	if mode is None:
		if hasattr(f, 'mode'):
			mode = f.mode
		else:
			mode = 'rb'
	if mode in ('r', 'rb'):
		return Aifc_read(f)
	elif mode in ('w', 'wb'):
		return Aifc_write(f)
	else:
		raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"

openfp = open # B/W compatibility

if __name__ == '__main__':
	import sys
	if not sys.argv[1:]:
		sys.argv.append('/usr/demos/data/audio/bach.aiff')
	fn = sys.argv[1]
	f = open(fn, 'r')
	print "Reading", fn
	print "nchannels =", f.getnchannels()
	print "nframes   =", f.getnframes()
	print "sampwidth =", f.getsampwidth()
	print "framerate =", f.getframerate()
	print "comptype  =", f.getcomptype()
	print "compname  =", f.getcompname()
	if sys.argv[2:]:
		gn = sys.argv[2]
		print "Writing", gn
		g = open(gn, 'w')
		g.setparams(f.getparams())
		while 1:
			data = f.readframes(1024)
			if not data:
				break
			g.writeframes(data)
		g.close()
		f.close()
		print "Done."
