1 """Classes for manipulating audio devices (currently only for Sun and SGI)"""
3 __all__
= ["error","AudioDev"]
5 class error(Exception):
9 # Private instance variables
10 ## if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \
11 ## params, config, inited_outrate, inited_width, \
12 ## inited_nchannels, port, converter, classinited: private
15 frameratelist
= nchannelslist
= sampwidthlist
= None
19 self
.frameratelist
= [
20 (48000, AL
.RATE_48000
),
21 (44100, AL
.RATE_44100
),
22 (32000, AL
.RATE_32000
),
23 (22050, AL
.RATE_22050
),
24 (16000, AL
.RATE_16000
),
25 (11025, AL
.RATE_11025
),
26 ( 8000, AL
.RATE_8000
),
28 self
.nchannelslist
= [
33 self
.sampwidthlist
= [
42 if not self
.classinited
:
45 self
.params
= [AL
.OUTPUT_RATE
, 0]
46 self
.config
= al
.newconfig()
47 self
.inited_outrate
= 0
49 self
.inited_nchannels
= 0
59 al
.setparams(AL
.DEFAULT_DEVICE
, self
.oldparams
)
66 while self
.port
.getfilled() > 0:
76 al
.setparams(AL
.DEFAULT_DEVICE
, self
.oldparams
)
79 def setoutrate(self
, rate
):
80 for (raw
, cooked
) in self
.frameratelist
:
82 self
.params
[1] = cooked
83 self
.inited_outrate
= 1
86 raise error
, 'bad output rate'
88 def setsampwidth(self
, width
):
89 for (raw
, cooked
) in self
.sampwidthlist
:
91 self
.config
.setwidth(cooked
)
98 self
.config
.setwidth(AL
.SAMPLE_16
)
99 self
.converter
= self
.ulaw2lin
101 raise error
, 'bad sample width'
103 def setnchannels(self
, nchannels
):
104 for (raw
, cooked
) in self
.nchannelslist
:
106 self
.config
.setchannels(cooked
)
107 self
.inited_nchannels
= 1
110 raise error
, 'bad # of channels'
112 def writeframes(self
, data
):
113 if not (self
.inited_outrate
and self
.inited_nchannels
):
114 raise error
, 'params not specified'
117 self
.port
= al
.openport('Python', 'w', self
.config
)
118 self
.oldparams
= self
.params
[:]
119 al
.getparams(AL
.DEFAULT_DEVICE
, self
.oldparams
)
120 al
.setparams(AL
.DEFAULT_DEVICE
, self
.params
)
122 data
= self
.converter(data
)
123 self
.port
.writesamps(data
)
127 return self
.port
.getfilled()
131 def getfillable(self
):
133 return self
.port
.getfillable()
135 return self
.config
.getqueuesize()
138 ## if 0: access *: private
140 def ulaw2lin(self
, data
):
142 return audioop
.ulaw2lin(data
, 2)
144 class Play_Audio_sun
:
145 ## if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \
146 ## inited_nchannels, converter: private
152 self
.inited_outrate
= 0
153 self
.inited_width
= 0
154 self
.inited_nchannels
= 0
155 self
.converter
= None
162 def setoutrate(self
, rate
):
164 self
.inited_outrate
= 1
166 def setsampwidth(self
, width
):
167 self
.sampwidth
= width
168 self
.inited_width
= 1
170 def setnchannels(self
, nchannels
):
171 self
.nchannels
= nchannels
172 self
.inited_nchannels
= 1
174 def writeframes(self
, data
):
175 if not (self
.inited_outrate
and self
.inited_width
and self
.inited_nchannels
):
176 raise error
, 'params not specified'
178 import sunaudiodev
, SUNAUDIODEV
179 self
.port
= sunaudiodev
.open('w')
180 info
= self
.port
.getinfo()
181 info
.o_sample_rate
= self
.outrate
182 info
.o_channels
= self
.nchannels
183 if self
.sampwidth
== 0:
185 self
.o_encoding
= SUNAUDIODEV
.ENCODING_ULAW
186 # XXX Hack, hack -- leave defaults
188 info
.o_precision
= 8 * self
.sampwidth
189 info
.o_encoding
= SUNAUDIODEV
.ENCODING_LINEAR
190 self
.port
.setinfo(info
)
192 data
= self
.converter(data
)
193 self
.port
.write(data
)
209 return self
.port
.obufcount()
213 ## # Nobody remembers what this method does, and it's broken. :-(
214 ## def getfillable(self):
215 ## return BUFFERSIZE - self.getfilled()
218 # Dynamically try to import and use a platform specific module.
224 return Play_Audio_sun()
229 raise error
, 'no audio device'
231 return Audio_mac
.Play_Audio_mac()
233 return Play_Audio_sgi()
240 fn
= 'f:just samples:just.aif'
242 af
= aifc
.open(fn
, 'r')
243 print fn
, af
.getparams()
245 p
.setoutrate(af
.getframerate())
246 p
.setsampwidth(af
.getsampwidth())
247 p
.setnchannels(af
.getnchannels())
248 BUFSIZ
= af
.getframerate()/af
.getsampwidth()/af
.getnchannels()
250 data
= af
.readframes(BUFSIZ
)
256 if __name__
== '__main__':