Another batch of updates...
[python/dscho.git] / Mac / Lib / Audio_mac.py
blob450cdf12f3a98c9d788bd4fd9b4c7c4e68138c62
1 QSIZE = 100000
2 error='Audio_mac.error'
4 class Play_Audio_mac:
6 def __init__(self, qsize=QSIZE):
7 self._chan = None
8 self._qsize = qsize
9 self._outrate = 22254
10 self._sampwidth = 1
11 self._nchannels = 1
12 self._gc = []
13 self._usercallback = None
15 def __del__(self):
16 self.stop()
17 self._usercallback = None
19 def wait(self):
20 import time
21 while self.getfilled():
22 time.sleep(0.1)
23 self._chan = None
24 self._gc = []
26 def stop(self, quietNow = 1):
27 ##chan = self._chan
28 self._chan = None
29 ##chan.SndDisposeChannel(1)
30 self._gc = []
32 def setoutrate(self, outrate):
33 self._outrate = outrate
35 def setsampwidth(self, sampwidth):
36 self._sampwidth = sampwidth
38 def setnchannels(self, nchannels):
39 self._nchannels = nchannels
41 def writeframes(self, data):
42 import time
43 from Sound import *
44 import struct
45 if not self._chan:
46 import Snd
47 self._chan = Snd.SndNewChannel(5, 0, self._callback)
48 nframes = len(data) / self._nchannels / self._sampwidth
49 if len(data) != nframes * self._nchannels * self._sampwidth:
50 raise error, 'data is not a whole number of frames'
51 while self._gc and \
52 self.getfilled() + nframes > \
53 self._qsize / self._nchannels / self._sampwidth:
54 time.sleep(0.1)
55 if self._sampwidth == 1:
56 import audioop
57 data = audioop.add(data, '\x80'*len(data), 1)
58 h1 = struct.pack('llhhllbbl',
59 id(data)+12,
60 self._nchannels,
61 self._outrate, 0,
64 extSH,
65 60,
66 nframes)
67 h2 = 22*'\0'
68 h3 = struct.pack('hhlll',
69 self._sampwidth*8,
74 header = h1+h2+h3
75 self._gc.append((header, data))
76 self._chan.SndDoCommand((bufferCmd, 0, header), 0)
77 self._chan.SndDoCommand((callBackCmd, 0, 0), 0)
79 def _callback(self, *args):
80 del self._gc[0]
81 if self._usercallback:
82 self._usercallback()
84 def setcallback(self, callback):
85 self._usercallback = callback
87 def getfilled(self):
88 filled = 0
89 for header, data in self._gc:
90 filled = filled + len(data)
91 return filled / self._nchannels / self._sampwidth
93 def getfillable(self):
94 return (self._qsize / self._nchannels / self._sampwidth) - self.getfilled()
96 def ulaw2lin(self, data):
97 import audioop
98 return audioop.ulaw2lin(data, 2)
100 def test():
101 import aifc
102 import macfs
103 fss, ok = macfs.PromptGetFile("Select an AIFF soundfile", "AIFF")
104 if not ok: return
105 fn = fss.as_pathname()
106 af = aifc.open(fn, 'r')
107 print af.getparams()
108 p = Play_Audio_mac()
109 p.setoutrate(af.getframerate())
110 p.setsampwidth(af.getsampwidth())
111 p.setnchannels(af.getnchannels())
112 BUFSIZ = 10000
113 while 1:
114 data = af.readframes(BUFSIZ)
115 if not data: break
116 p.writeframes(data)
117 print 'wrote', len(data), 'space', p.getfillable()
118 p.wait()
120 if __name__ == '__main__':
121 test()