"""Stuff to parse Sun and NeXT audio files.

An audio consists of a header followed by the data.  The structure
of the header is as follows.

        +---------------+
        | magic word    |
        +---------------+
        | header size   |
        +---------------+
        | data size     |
        +---------------+
        | encoding      |
        +---------------+
        | sample rate   |
        +---------------+
        | # of channels |
        +---------------+
        | info          |
        |               |
        +---------------+

The magic word consists of the 4 characters '.snd'.  Apart from the
info field, all header fields are 4 bytes in size.  They are all
32-bit unsigned integers encoded in big-endian byte order.

The header size really gives the start of the data.
The data size is the physical size of the data.  From the other
parameter the number of frames can be calculated.
The encoding gives the way in which audio samples are encoded.
Possible values are listed below.
The info field currently consists of an ASCII string giving a
human-readable description of the audio file.  The info field is
padded with NUL bytes to the header size.

Usage.

Reading audio files:
        f = sunau.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().
When the setpos() and rewind() methods are 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' or 'ULAW')
        getcompname()	-- returns human-readable version of
        		   compression type ('not compressed' matches 'NONE')
        getparams()	-- returns a tuple consisting of all of the
        		   above in the above order
        getmarkers()	-- returns None (for compatibility with the
        		   aifc module)
        getmark(id)	-- raises an error since the mark does not
        		   exist (for compatibility with the aifc module)
        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() and the position given to setpos()
are compatible and have nothing to do with the actual position in the
file.
The close() method is called automatically when the class instance
is destroyed.

Writing audio files:
        f = sunau.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:
        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
        tell()		-- return current position in output file
        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.
The close() method is called automatically when the class instance
is destroyed.
"""

# from <multimedia/audio_filehdr.h>
AUDIO_FILE_MAGIC = 0x2e736e64
AUDIO_FILE_ENCODING_MULAW_8 = 1
AUDIO_FILE_ENCODING_LINEAR_8 = 2
AUDIO_FILE_ENCODING_LINEAR_16 = 3
AUDIO_FILE_ENCODING_LINEAR_24 = 4
AUDIO_FILE_ENCODING_LINEAR_32 = 5
AUDIO_FILE_ENCODING_FLOAT = 6
AUDIO_FILE_ENCODING_DOUBLE = 7
AUDIO_FILE_ENCODING_ADPCM_G721 = 23
AUDIO_FILE_ENCODING_ADPCM_G722 = 24
AUDIO_FILE_ENCODING_ADPCM_G723_3 = 25
AUDIO_FILE_ENCODING_ADPCM_G723_5 = 26
AUDIO_FILE_ENCODING_ALAW_8 = 27

# from <multimedia/audio_hdr.h>
AUDIO_UNKNOWN_SIZE = 0xFFFFFFFFL	# ((unsigned)(~0))

_simple_encodings = [AUDIO_FILE_ENCODING_MULAW_8,
		     AUDIO_FILE_ENCODING_LINEAR_8,
		     AUDIO_FILE_ENCODING_LINEAR_16,
		     AUDIO_FILE_ENCODING_LINEAR_24,
		     AUDIO_FILE_ENCODING_LINEAR_32,
		     AUDIO_FILE_ENCODING_ALAW_8]

class Error(Exception):
	pass

def _read_u32(file):
	x = 0L
	for i in range(4):
		byte = file.read(1)
		if byte == '':
			raise EOFError
		x = x*256 + ord(byte)
	return x

def _write_u32(file, x):
	data = []
	for i in range(4):
		d, m = divmod(x, 256)
		data.insert(0, m)
		x = d
	for i in range(4):
		file.write(chr(int(data[i])))

class Au_read:

	def __init__(self, f):
		if type(f) == type(''):
			import __builtin__
			f = __builtin__.open(f, 'rb')
		self.initfp(f)

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

	def initfp(self, file):
		self._file = file
		self._soundpos = 0
		magic = int(_read_u32(file))
		if magic != AUDIO_FILE_MAGIC:
			raise Error, 'bad magic number'
		self._hdr_size = int(_read_u32(file))
		if self._hdr_size < 24:
			raise Error, 'header size too small'
		if self._hdr_size > 100:
			raise Error, 'header size ridiculously large'
		self._data_size = _read_u32(file)
		if self._data_size != AUDIO_UNKNOWN_SIZE:
			self._data_size = int(self._data_size)
		self._encoding = int(_read_u32(file))
		if self._encoding not in _simple_encodings:
			raise Error, 'encoding not (yet) supported'
		if self._encoding in (AUDIO_FILE_ENCODING_MULAW_8,
			  AUDIO_FILE_ENCODING_ALAW_8):
			self._sampwidth = 2
			self._framesize = 1
		elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_8:
			self._framesize = self._sampwidth = 1
		elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_16:
			self._framesize = self._sampwidth = 2
		elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_24:
			self._framesize = self._sampwidth = 3
		elif self._encoding == AUDIO_FILE_ENCODING_LINEAR_32:
			self._framesize = self._sampwidth = 4
		else:
			raise Error, 'unknown encoding'
		self._framerate = int(_read_u32(file))
		self._nchannels = int(_read_u32(file))
		self._framesize = self._framesize * self._nchannels
		if self._hdr_size > 24:
			self._info = file.read(self._hdr_size - 24)
			for i in range(len(self._info)):
				if self._info[i] == '\0':
					self._info = self._info[:i]
					break
		else:
			self._info = ''

	def getfp(self):
		return self._file

	def getnchannels(self):
		return self._nchannels

	def getsampwidth(self):
		return self._sampwidth

	def getframerate(self):
		return self._framerate

	def getnframes(self):
		if self._data_size == AUDIO_UNKNOWN_SIZE:
			return AUDIO_UNKNOWN_SIZE
		if self._encoding in _simple_encodings:
			return self._data_size / self._framesize
		return 0		# XXX--must do some arithmetic here

	def getcomptype(self):
		if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
			return 'ULAW'
		elif self._encoding == AUDIO_FILE_ENCODING_ALAW_8:
			return 'ALAW'
		else:
			return 'NONE'

	def getcompname(self):
		if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
			return 'CCITT G.711 u-law'
		elif self._encoding == AUDIO_FILE_ENCODING_ALAW_8:
			return 'CCITT G.711 A-law'
		else:
			return 'not compressed'

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

	def getmarkers(self):
		return None

	def getmark(self, id):
		raise Error, 'no marks'

	def readframes(self, nframes):
		if self._encoding in _simple_encodings:
			if nframes == AUDIO_UNKNOWN_SIZE:
				data = self._file.read()
			else:
				data = self._file.read(nframes * self._framesize * self._nchannels)
			if self._encoding == AUDIO_FILE_ENCODING_MULAW_8:
				import audioop
				data = audioop.ulaw2lin(data, self._sampwidth)
			return data
		return None		# XXX--not implemented yet

	def rewind(self):
		self._soundpos = 0
		self._file.seek(self._hdr_size)

	def tell(self):
		return self._soundpos

	def setpos(self, pos):
		if pos < 0 or pos > self.getnframes():
			raise Error, 'position not in range'
		self._file.seek(pos * self._framesize + self._hdr_size)
		self._soundpos = pos

	def close(self):
		self._file = None

class Au_write:

	def __init__(self, f):
		if type(f) == type(''):
			import __builtin__
			f = __builtin__.open(f, 'wb')
		self.initfp(f)

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

	def initfp(self, file):
		self._file = file
		self._framerate = 0
		self._nchannels = 0
		self._sampwidth = 0
		self._framesize = 0
		self._nframes = AUDIO_UNKNOWN_SIZE
		self._nframeswritten = 0
		self._datawritten = 0
		self._datalength = 0
		self._info = ''
		self._comptype = 'ULAW'	# default is U-law

	def setnchannels(self, nchannels):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		if nchannels not in (1, 2, 4):
			raise Error, 'only 1, 2, or 4 channels supported'
		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 not in (1, 2, 4):
			raise Error, 'bad sample width'
		self._sampwidth = sampwidth

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

	def setframerate(self, framerate):
		if self._nframeswritten:
			raise Error, 'cannot change parameters after starting to write'
		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'
		if nframes < 0:
			raise Error, '# of frames cannot be negative'
		self._nframes = nframes

	def getnframes(self):
		return self._nframeswritten

	def setcomptype(self, type, name):
		if type in ('NONE', 'ULAW'):
			self._comptype = type
		else:
			raise Error, 'unknown compression type'

	def getcomptype(self):
		return self._comptype

	def getcompname(self):
		if self._comptype == 'ULAW':
			return 'CCITT G.711 u-law'
		elif self._comptype == 'ALAW':
			return 'CCITT G.711 A-law'
		else:
			return 'not compressed'

	def setparams(self, (nchannels, sampwidth, framerate, nframes, comptype, compname)):
		self.setnchannels(nchannels)
		self.setsampwidth(sampwidth)
		self.setframerate(framerate)
		self.setnframes(nframes)
		self.setcomptype(comptype, compname)

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

	def tell(self):
		return self._nframeswritten

	def writeframesraw(self, data):
		self._ensure_header_written()
		nframes = len(data) / self._framesize
		if self._comptype == 'ULAW':
			import audioop
			data = audioop.lin2ulaw(data, self._sampwidth)
		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()
		if self._nframeswritten != self._nframes or \
			  self._datalength != self._datawritten:
			self._patchheader()
		self._file.flush()
		self._file = None

	#
	# private methods
	#

	def _ensure_header_written(self):
		if not self._nframeswritten:
			if not self._nchannels:
				raise Error, '# of channels not specified'
			if not self._sampwidth:
				raise Error, 'sample width not specified'
			if not self._framerate:
				raise Error, 'frame rate not specified'
			self._write_header()

	def _write_header(self):
		if self._comptype == 'NONE':
			if self._sampwidth == 1:
				encoding = AUDIO_FILE_ENCODING_LINEAR_8
				self._framesize = 1
			elif self._sampwidth == 2:
				encoding = AUDIO_FILE_ENCODING_LINEAR_16
				self._framesize = 2
			elif self._sampwidth == 4:
				encoding = AUDIO_FILE_ENCODING_LINEAR_32
				self._framesize = 4
			else:
				raise Error, 'internal error'
		elif self._comptype == 'ULAW':
			encoding = AUDIO_FILE_ENCODING_MULAW_8
			self._framesize = 1
		else:
			raise Error, 'internal error'
		self._framesize = self._framesize * self._nchannels
		_write_u32(self._file, AUDIO_FILE_MAGIC)
		header_size = 25 + len(self._info)
		header_size = (header_size + 7) & ~7
		_write_u32(self._file, header_size)
		if self._nframes == AUDIO_UNKNOWN_SIZE:
			length = AUDIO_UNKNOWN_SIZE
		else:
			length = self._nframes * self._framesize
		_write_u32(self._file, length)
		self._datalength = length
		_write_u32(self._file, encoding)
		_write_u32(self._file, self._framerate)
		_write_u32(self._file, self._nchannels)
		self._file.write(self._info)
		self._file.write('\0'*(header_size - len(self._info) - 24))

	def _patchheader(self):
		self._file.seek(8)
		_write_u32(self._file, self._datawritten)
		self._datalength = self._datawritten
		self._file.seek(0, 2)

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 Au_read(f)
	elif mode in ('w', 'wb'):
		return Au_write(f)
	else:
		raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"

openfp = open
