"""Classes for manipulating audio devices (currently only for Sun and SGI)"""

error = 'audiodev.error'

class Play_Audio_sgi:
	# Private instance variables
## 	if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \
## 		  params, config, inited_outrate, inited_width, \
## 		  inited_nchannels, port, converter, classinited: private

	classinited = 0
	frameratelist = nchannelslist = sampwidthlist = None

	def initclass(self):
		import AL
		self.frameratelist = [
			  (48000, AL.RATE_48000),
			  (44100, AL.RATE_44100),
			  (32000, AL.RATE_32000),
			  (22050, AL.RATE_22050),
			  (16000, AL.RATE_16000),
			  (11025, AL.RATE_11025),
			  ( 8000,  AL.RATE_8000),
			  ]
		self.nchannelslist = [
			  (1, AL.MONO),
			  (2, AL.STEREO),
			  (4, AL.QUADRO),
			  ]
		self.sampwidthlist = [
			  (1, AL.SAMPLE_8),
			  (2, AL.SAMPLE_16),
			  (3, AL.SAMPLE_24),
			  ]
		self.classinited = 1

	def __init__(self):
		import al, AL
		if not self.classinited:
			self.initclass()
		self.oldparams = []
		self.params = [AL.OUTPUT_RATE, 0]
		self.config = al.newconfig()
		self.inited_outrate = 0
		self.inited_width = 0
		self.inited_nchannels = 0
		self.converter = None
		self.port = None
		return

	def __del__(self):
		if self.port:
			self.stop()
		if self.oldparams:
			import al, AL
			al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
			self.oldparams = []

	def wait(self):
		if not self.port:
			return
		import time
		while self.port.getfilled() > 0:
			time.sleep(0.1)
		self.stop()

	def stop(self):
		if self.port:
			self.port.closeport()
			self.port = None
		if self.oldparams:
			import al, AL
			al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
			self.oldparams = []

	def setoutrate(self, rate):
		for (raw, cooked) in self.frameratelist:
			if rate == raw:
				self.params[1] = cooked
				self.inited_outrate = 1
				break
		else:
			raise error, 'bad output rate'

	def setsampwidth(self, width):
		for (raw, cooked) in self.sampwidthlist:
			if width == raw:
				self.config.setwidth(cooked)
				self.inited_width = 1
				break
		else:
			if width == 0:
				import AL
				self.inited_width = 0
				self.config.setwidth(AL.SAMPLE_16)
				self.converter = self.ulaw2lin
			else:
				raise error, 'bad sample width'

	def setnchannels(self, nchannels):
		for (raw, cooked) in self.nchannelslist:
			if nchannels == raw:
				self.config.setchannels(cooked)
				self.inited_nchannels = 1
				break
		else:
			raise error, 'bad # of channels'

	def writeframes(self, data):
		if not (self.inited_outrate and self.inited_nchannels):
			raise error, 'params not specified'
		if not self.port:
			import al, AL
			self.port = al.openport('Python', 'w', self.config)
			self.oldparams = self.params[:]
			al.getparams(AL.DEFAULT_DEVICE, self.oldparams)
			al.setparams(AL.DEFAULT_DEVICE, self.params)
		if self.converter:
			data = self.converter(data)
		self.port.writesamps(data)

	def getfilled(self):
		if self.port:
			return self.port.getfilled()
		else:
			return 0

	def getfillable(self):
		if self.port:
			return self.port.getfillable()
		else:
			return self.config.getqueuesize()

	# private methods
## 	if 0: access *: private

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

class Play_Audio_sun:
## 	if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \
## 		  inited_nchannels, converter: private

	def __init__(self):
		self.outrate = 0
		self.sampwidth = 0
		self.nchannels = 0
		self.inited_outrate = 0
		self.inited_width = 0
		self.inited_nchannels = 0
		self.converter = None
		self.port = None
		return

	def __del__(self):
		self.stop()

	def setoutrate(self, rate):
		self.outrate = rate
		self.inited_outrate = 1

	def setsampwidth(self, width):
		self.sampwidth = width
		self.inited_width = 1

	def setnchannels(self, nchannels):
		self.nchannels = nchannels
		self.inited_nchannels = 1

	def writeframes(self, data):
		if not (self.inited_outrate and self.inited_width and self.inited_nchannels):
			raise error, 'params not specified'
		if not self.port:
			import sunaudiodev, SUNAUDIODEV
			self.port = sunaudiodev.open('w')
			info = self.port.getinfo()
			info.o_sample_rate = self.outrate
			info.o_channels = self.nchannels
			if self.sampwidth == 0:
				info.o_precision = 8
				self.o_encoding = SUNAUDIODEV.ENCODING_ULAW
				# XXX Hack, hack -- leave defaults
			else:
				info.o_precision = 8 * self.sampwidth
				info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR
				self.port.setinfo(info)
		if self.converter:
			data = self.converter(data)
		self.port.write(data)

	def wait(self):
		if not self.port:
			return
		self.port.drain()
		self.stop()

	def stop(self):
		if self.port:
			self.port.flush()
			self.port.close()
			self.port = None

	def getfilled(self):
		if self.port:
			return self.port.obufcount()
		else:
			return 0

	def getfillable(self):
		return BUFFERSIZE - self.getfilled()

def AudioDev():
	# Dynamically try to import and use a platform specific module.
	try:
		import al
	except ImportError:
		try:
			import sunaudiodev
			return Play_Audio_sun()
		except ImportError:
			try:
				import Audio_mac
			except ImportError:
				raise error, 'no audio device'
			else:
				return Audio_mac.Play_Audio_mac()
	else:
		return Play_Audio_sgi()

def test(fn = None):
	import sys
	if sys.argv[1:]:
		fn = sys.argv[1]
	else:
		fn = 'f:just samples:just.aif'
	import aifc
	af = aifc.open(fn, 'r')
	print fn, af.getparams()
	p = AudioDev()
	p.setoutrate(af.getframerate())
	p.setsampwidth(af.getsampwidth())
	p.setnchannels(af.getnchannels())
	BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels()
	while 1:
		data = af.readframes(BUFSIZ)
		if not data: break
		print len(data)
		p.writeframes(data)
	p.wait()

if __name__ == '__main__':
	test()
