# 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' 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()	-- 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 postion 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(nchannels, sampwidth, framerate, nframes, comptype, compname)
#			-- 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]

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:
	access _file, _soundpos, _hdr_size, _data_size, _encoding, \
		  _sampwidth, _framesize, _framerate, _nchannels, \
		  _info: private

	def __init__(self, f):
		if type(f) == type(''):
			import __builtin__
			f = __builtin__.open(f, 'r')
		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 rediculously 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_LINEAR_8,
			  AUDIO_FILE_ENCODING_ALAW_8):
			self._sampwidth = 2
			self._framesize = 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:
	access _file, _framerate, _nchannels, _sampwidth, _framesize, \
		  _nframes, _nframeswritten, _datawritten, _info, \
		  _comptype: private

	def __init__(self, f):
		if type(f) == type(''):
			import __builtin__
			f = __builtin__.open(f, 'w')
		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
	#
	access *: private

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

openfp = open
