mirror of
https://github.com/python/cpython.git
synced 2024-11-30 13:24:13 +08:00
4acc25bd39
1. Comments at the beginning of the module, before functions, and before classes have been turned into docstrings. 2. Tabs are normalized to four spaces. Also, removed the "remove" function from dircmp.py, which reimplements list.remove() (it must have been very old).
254 lines
5.7 KiB
Python
254 lines
5.7 KiB
Python
"""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()
|