blob: 450cdf12f3a98c9d788bd4fd9b4c7c4e68138c62 [file] [log] [blame]
Guido van Rossum17448e21995-01-30 11:53:55 +00001QSIZE = 100000
Jack Jansen52a40ac1996-03-18 13:33:48 +00002error='Audio_mac.error'
Guido van Rossum17448e21995-01-30 11:53:55 +00003
4class Play_Audio_mac:
5
Jack Jansen52a40ac1996-03-18 13:33:48 +00006 def __init__(self, qsize=QSIZE):
Guido van Rossum17448e21995-01-30 11:53:55 +00007 self._chan = None
Jack Jansen52a40ac1996-03-18 13:33:48 +00008 self._qsize = qsize
Guido van Rossum17448e21995-01-30 11:53:55 +00009 self._outrate = 22254
10 self._sampwidth = 1
11 self._nchannels = 1
12 self._gc = []
Jack Jansen195e33e1996-01-09 17:15:57 +000013 self._usercallback = None
Guido van Rossum17448e21995-01-30 11:53:55 +000014
15 def __del__(self):
16 self.stop()
Jack Jansen195e33e1996-01-09 17:15:57 +000017 self._usercallback = None
Guido van Rossum17448e21995-01-30 11:53:55 +000018
19 def wait(self):
20 import time
21 while self.getfilled():
22 time.sleep(0.1)
23 self._chan = None
24 self._gc = []
25
26 def stop(self, quietNow = 1):
27 ##chan = self._chan
28 self._chan = None
29 ##chan.SndDisposeChannel(1)
30 self._gc = []
31
32 def setoutrate(self, outrate):
33 self._outrate = outrate
34
35 def setsampwidth(self, sampwidth):
36 self._sampwidth = sampwidth
37
38 def setnchannels(self, nchannels):
39 self._nchannels = nchannels
40
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:
Jack Jansen52a40ac1996-03-18 13:33:48 +000050 raise error, 'data is not a whole number of frames'
Guido van Rossum17448e21995-01-30 11:53:55 +000051 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,
62 0,
63 0,
64 extSH,
65 60,
66 nframes)
67 h2 = 22*'\0'
68 h3 = struct.pack('hhlll',
69 self._sampwidth*8,
70 0,
71 0,
72 0,
73 0)
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)
78
79 def _callback(self, *args):
80 del self._gc[0]
Jack Jansen195e33e1996-01-09 17:15:57 +000081 if self._usercallback:
82 self._usercallback()
83
84 def setcallback(self, callback):
85 self._usercallback = callback
Guido van Rossum17448e21995-01-30 11:53:55 +000086
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
92
93 def getfillable(self):
Jack Jansen195e33e1996-01-09 17:15:57 +000094 return (self._qsize / self._nchannels / self._sampwidth) - self.getfilled()
Guido van Rossum17448e21995-01-30 11:53:55 +000095
96 def ulaw2lin(self, data):
97 import audioop
98 return audioop.ulaw2lin(data, 2)
99
Jack Jansen66019641996-01-02 12:09:30 +0000100def test():
Guido van Rossum17448e21995-01-30 11:53:55 +0000101 import aifc
Jack Jansen66019641996-01-02 12:09:30 +0000102 import macfs
103 fss, ok = macfs.PromptGetFile("Select an AIFF soundfile", "AIFF")
104 if not ok: return
105 fn = fss.as_pathname()
Guido van Rossum17448e21995-01-30 11:53:55 +0000106 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)
Jack Jansen66019641996-01-02 12:09:30 +0000117 print 'wrote', len(data), 'space', p.getfillable()
Guido van Rossum17448e21995-01-30 11:53:55 +0000118 p.wait()
119
120if __name__ == '__main__':
121 test()