0001 """Classes for manipulating audio devices (currently only for Sun and SGI)""" 0002 0003 __all__ = ["error","AudioDev"] 0004 0005 class error(Exception): 0006 pass 0007 0008 class Play_Audio_sgi: 0009 # Private instance variables 0010 ## if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \ 0011 ## params, config, inited_outrate, inited_width, \ 0012 ## inited_nchannels, port, converter, classinited: private 0013 0014 classinited = 0 0015 frameratelist = nchannelslist = sampwidthlist = None 0016 0017 def initclass(self): 0018 import AL 0019 self.frameratelist = [ 0020 (48000, AL.RATE_48000), 0021 (44100, AL.RATE_44100), 0022 (32000, AL.RATE_32000), 0023 (22050, AL.RATE_22050), 0024 (16000, AL.RATE_16000), 0025 (11025, AL.RATE_11025), 0026 ( 8000, AL.RATE_8000), 0027 ] 0028 self.nchannelslist = [ 0029 (1, AL.MONO), 0030 (2, AL.STEREO), 0031 (4, AL.QUADRO), 0032 ] 0033 self.sampwidthlist = [ 0034 (1, AL.SAMPLE_8), 0035 (2, AL.SAMPLE_16), 0036 (3, AL.SAMPLE_24), 0037 ] 0038 self.classinited = 1 0039 0040 def __init__(self): 0041 import al, AL 0042 if not self.classinited: 0043 self.initclass() 0044 self.oldparams = [] 0045 self.params = [AL.OUTPUT_RATE, 0] 0046 self.config = al.newconfig() 0047 self.inited_outrate = 0 0048 self.inited_width = 0 0049 self.inited_nchannels = 0 0050 self.converter = None 0051 self.port = None 0052 return 0053 0054 def __del__(self): 0055 if self.port: 0056 self.stop() 0057 if self.oldparams: 0058 import al, AL 0059 al.setparams(AL.DEFAULT_DEVICE, self.oldparams) 0060 self.oldparams = [] 0061 0062 def wait(self): 0063 if not self.port: 0064 return 0065 import time 0066 while self.port.getfilled() > 0: 0067 time.sleep(0.1) 0068 self.stop() 0069 0070 def stop(self): 0071 if self.port: 0072 self.port.closeport() 0073 self.port = None 0074 if self.oldparams: 0075 import al, AL 0076 al.setparams(AL.DEFAULT_DEVICE, self.oldparams) 0077 self.oldparams = [] 0078 0079 def setoutrate(self, rate): 0080 for (raw, cooked) in self.frameratelist: 0081 if rate == raw: 0082 self.params[1] = cooked 0083 self.inited_outrate = 1 0084 break 0085 else: 0086 raise error, 'bad output rate' 0087 0088 def setsampwidth(self, width): 0089 for (raw, cooked) in self.sampwidthlist: 0090 if width == raw: 0091 self.config.setwidth(cooked) 0092 self.inited_width = 1 0093 break 0094 else: 0095 if width == 0: 0096 import AL 0097 self.inited_width = 0 0098 self.config.setwidth(AL.SAMPLE_16) 0099 self.converter = self.ulaw2lin 0100 else: 0101 raise error, 'bad sample width' 0102 0103 def setnchannels(self, nchannels): 0104 for (raw, cooked) in self.nchannelslist: 0105 if nchannels == raw: 0106 self.config.setchannels(cooked) 0107 self.inited_nchannels = 1 0108 break 0109 else: 0110 raise error, 'bad # of channels' 0111 0112 def writeframes(self, data): 0113 if not (self.inited_outrate and self.inited_nchannels): 0114 raise error, 'params not specified' 0115 if not self.port: 0116 import al, AL 0117 self.port = al.openport('Python', 'w', self.config) 0118 self.oldparams = self.params[:] 0119 al.getparams(AL.DEFAULT_DEVICE, self.oldparams) 0120 al.setparams(AL.DEFAULT_DEVICE, self.params) 0121 if self.converter: 0122 data = self.converter(data) 0123 self.port.writesamps(data) 0124 0125 def getfilled(self): 0126 if self.port: 0127 return self.port.getfilled() 0128 else: 0129 return 0 0130 0131 def getfillable(self): 0132 if self.port: 0133 return self.port.getfillable() 0134 else: 0135 return self.config.getqueuesize() 0136 0137 # private methods 0138 ## if 0: access *: private 0139 0140 def ulaw2lin(self, data): 0141 import audioop 0142 return audioop.ulaw2lin(data, 2) 0143 0144 class Play_Audio_sun: 0145 ## if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \ 0146 ## inited_nchannels, converter: private 0147 0148 def __init__(self): 0149 self.outrate = 0 0150 self.sampwidth = 0 0151 self.nchannels = 0 0152 self.inited_outrate = 0 0153 self.inited_width = 0 0154 self.inited_nchannels = 0 0155 self.converter = None 0156 self.port = None 0157 return 0158 0159 def __del__(self): 0160 self.stop() 0161 0162 def setoutrate(self, rate): 0163 self.outrate = rate 0164 self.inited_outrate = 1 0165 0166 def setsampwidth(self, width): 0167 self.sampwidth = width 0168 self.inited_width = 1 0169 0170 def setnchannels(self, nchannels): 0171 self.nchannels = nchannels 0172 self.inited_nchannels = 1 0173 0174 def writeframes(self, data): 0175 if not (self.inited_outrate and self.inited_width and self.inited_nchannels): 0176 raise error, 'params not specified' 0177 if not self.port: 0178 import sunaudiodev, SUNAUDIODEV 0179 self.port = sunaudiodev.open('w') 0180 info = self.port.getinfo() 0181 info.o_sample_rate = self.outrate 0182 info.o_channels = self.nchannels 0183 if self.sampwidth == 0: 0184 info.o_precision = 8 0185 self.o_encoding = SUNAUDIODEV.ENCODING_ULAW 0186 # XXX Hack, hack -- leave defaults 0187 else: 0188 info.o_precision = 8 * self.sampwidth 0189 info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR 0190 self.port.setinfo(info) 0191 if self.converter: 0192 data = self.converter(data) 0193 self.port.write(data) 0194 0195 def wait(self): 0196 if not self.port: 0197 return 0198 self.port.drain() 0199 self.stop() 0200 0201 def stop(self): 0202 if self.port: 0203 self.port.flush() 0204 self.port.close() 0205 self.port = None 0206 0207 def getfilled(self): 0208 if self.port: 0209 return self.port.obufcount() 0210 else: 0211 return 0 0212 0213 ## # Nobody remembers what this method does, and it's broken. :-( 0214 ## def getfillable(self): 0215 ## return BUFFERSIZE - self.getfilled() 0216 0217 def AudioDev(): 0218 # Dynamically try to import and use a platform specific module. 0219 try: 0220 import al 0221 except ImportError: 0222 try: 0223 import sunaudiodev 0224 return Play_Audio_sun() 0225 except ImportError: 0226 try: 0227 import Audio_mac 0228 except ImportError: 0229 raise error, 'no audio device' 0230 else: 0231 return Audio_mac.Play_Audio_mac() 0232 else: 0233 return Play_Audio_sgi() 0234 0235 def test(fn = None): 0236 import sys 0237 if sys.argv[1:]: 0238 fn = sys.argv[1] 0239 else: 0240 fn = 'f:just samples:just.aif' 0241 import aifc 0242 af = aifc.open(fn, 'r') 0243 print fn, af.getparams() 0244 p = AudioDev() 0245 p.setoutrate(af.getframerate()) 0246 p.setsampwidth(af.getsampwidth()) 0247 p.setnchannels(af.getnchannels()) 0248 BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels() 0249 while 1: 0250 data = af.readframes(BUFSIZ) 0251 if not data: break 0252 print len(data) 0253 p.writeframes(data) 0254 p.wait() 0255 0256 if __name__ == '__main__': 0257 test() 0258
Generated by PyXR 0.9.4