Vega strike Python Modules doc  0.5.1
Documentation of the " Modules " folder of Vega strike
 All Data Structures Namespaces Files Functions Variables
audiodev.py
Go to the documentation of this file.
1 """Classes for manipulating audio devices (currently only for Sun and SGI)"""
2 
3 __all__ = ["error","AudioDev"]
4 
5 class error(Exception):
6  pass
7 
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
13 
14  classinited = 0
15  frameratelist = nchannelslist = sampwidthlist = None
16 
17  def initclass(self):
18  import AL
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),
27  ]
28  self.nchannelslist = [
29  (1, AL.MONO),
30  (2, AL.STEREO),
31  (4, AL.QUADRO),
32  ]
33  self.sampwidthlist = [
34  (1, AL.SAMPLE_8),
35  (2, AL.SAMPLE_16),
36  (3, AL.SAMPLE_24),
37  ]
38  self.classinited = 1
39 
40  def __init__(self):
41  import al, AL
42  if not self.classinited:
43  self.initclass()
44  self.oldparams = []
45  self.params = [AL.OUTPUT_RATE, 0]
46  self.config = al.newconfig()
47  self.inited_outrate = 0
48  self.inited_width = 0
49  self.inited_nchannels = 0
50  self.converter = None
51  self.port = None
52  return
53 
54  def __del__(self):
55  if self.port:
56  self.stop()
57  if self.oldparams:
58  import al, AL
59  al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
60  self.oldparams = []
61 
62  def wait(self):
63  if not self.port:
64  return
65  import time
66  while self.port.getfilled() > 0:
67  time.sleep(0.1)
68  self.stop()
69 
70  def stop(self):
71  if self.port:
72  self.port.closeport()
73  self.port = None
74  if self.oldparams:
75  import al, AL
76  al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
77  self.oldparams = []
78 
79  def setoutrate(self, rate):
80  for (raw, cooked) in self.frameratelist:
81  if rate == raw:
82  self.params[1] = cooked
83  self.inited_outrate = 1
84  break
85  else:
86  raise error, 'bad output rate'
87 
88  def setsampwidth(self, width):
89  for (raw, cooked) in self.sampwidthlist:
90  if width == raw:
91  self.config.setwidth(cooked)
92  self.inited_width = 1
93  break
94  else:
95  if width == 0:
96  import AL
97  self.inited_width = 0
98  self.config.setwidth(AL.SAMPLE_16)
99  self.converter = self.ulaw2lin
100  else:
101  raise error, 'bad sample width'
102 
103  def setnchannels(self, nchannels):
104  for (raw, cooked) in self.nchannelslist:
105  if nchannels == raw:
106  self.config.setchannels(cooked)
107  self.inited_nchannels = 1
108  break
109  else:
110  raise error, 'bad # of channels'
111 
112  def writeframes(self, data):
113  if not (self.inited_outrate and self.inited_nchannels):
114  raise error, 'params not specified'
115  if not self.port:
116  import al, AL
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)
121  if self.converter:
122  data = self.converter(data)
123  self.port.writesamps(data)
124 
125  def getfilled(self):
126  if self.port:
127  return self.port.getfilled()
128  else:
129  return 0
130 
131  def getfillable(self):
132  if self.port:
133  return self.port.getfillable()
134  else:
135  return self.config.getqueuesize()
136 
137  # private methods
138 ## if 0: access *: private
139 
140  def ulaw2lin(self, data):
141  import audioop
142  return audioop.ulaw2lin(data, 2)
143 
145 ## if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \
146 ## inited_nchannels, converter: private
147 
148  def __init__(self):
149  self.outrate = 0
150  self.sampwidth = 0
151  self.nchannels = 0
152  self.inited_outrate = 0
153  self.inited_width = 0
154  self.inited_nchannels = 0
155  self.converter = None
156  self.port = None
157  return
158 
159  def __del__(self):
160  self.stop()
161 
162  def setoutrate(self, rate):
163  self.outrate = rate
164  self.inited_outrate = 1
165 
166  def setsampwidth(self, width):
167  self.sampwidth = width
168  self.inited_width = 1
169 
170  def setnchannels(self, nchannels):
171  self.nchannels = nchannels
172  self.inited_nchannels = 1
173 
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'
177  if not self.port:
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:
184  info.o_precision = 8
185  self.o_encoding = SUNAUDIODEV.ENCODING_ULAW
186  # XXX Hack, hack -- leave defaults
187  else:
188  info.o_precision = 8 * self.sampwidth
189  info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR
190  self.port.setinfo(info)
191  if self.converter:
192  data = self.converter(data)
193  self.port.write(data)
194 
195  def wait(self):
196  if not self.port:
197  return
198  self.port.drain()
199  self.stop()
200 
201  def stop(self):
202  if self.port:
203  self.port.flush()
204  self.port.close()
205  self.port = None
206 
207  def getfilled(self):
208  if self.port:
209  return self.port.obufcount()
210  else:
211  return 0
212 
213 ## # Nobody remembers what this method does, and it's broken. :-(
214 ## def getfillable(self):
215 ## return BUFFERSIZE - self.getfilled()
216 
217 def AudioDev():
218  # Dynamically try to import and use a platform specific module.
219  try:
220  import al
221  except ImportError:
222  try:
223  import sunaudiodev
224  return Play_Audio_sun()
225  except ImportError:
226  try:
227  import Audio_mac
228  except ImportError:
229  raise error, 'no audio device'
230  else:
231  return Audio_mac.Play_Audio_mac()
232  else:
233  return Play_Audio_sgi()
234 
235 def test(fn = None):
236  import sys
237  if sys.argv[1:]:
238  fn = sys.argv[1]
239  else:
240  fn = 'f:just samples:just.aif'
241  import aifc
242  af = aifc.open(fn, 'r')
243  print fn, af.getparams()
244  p = AudioDev()
245  p.setoutrate(af.getframerate())
246  p.setsampwidth(af.getsampwidth())
247  p.setnchannels(af.getnchannels())
248  BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels()
249  while 1:
250  data = af.readframes(BUFSIZ)
251  if not data: break
252  print len(data)
253  p.writeframes(data)
254  p.wait()
255 
256 if __name__ == '__main__':
257  test()