1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | Lib/plat-mac/Audio_mac.py
QSIZE = 100000 error='Audio_mac.error' from warnings import warnpy3k warnpy3k("In 3.x, the Play_Audio_mac module is removed.", stacklevel=2) class Play_Audio_mac: def __init__(self, qsize=QSIZE): self._chan = None self._qsize = qsize self._outrate = 22254 self._sampwidth = 1 self._nchannels = 1 self._gc = [] self._usercallback = None def __del__(self): self.stop() self._usercallback = None def wait(self): import time while self.getfilled(): time.sleep(0.1) self._chan = None self._gc = [] def stop(self, quietNow = 1): ##chan = self._chan self._chan = None ##chan.SndDisposeChannel(1) self._gc = [] def setoutrate(self, outrate): self._outrate = outrate def setsampwidth(self, sampwidth): self._sampwidth = sampwidth def setnchannels(self, nchannels): self._nchannels = nchannels def writeframes(self, data): import time from Carbon.Sound import bufferCmd, callBackCmd, extSH import struct import MacOS if not self._chan: from Carbon import Snd self._chan = Snd.SndNewChannel(5, 0, self._callback) nframes = len(data) / self._nchannels / self._sampwidth if len(data) != nframes * self._nchannels * self._sampwidth: raise error, 'data is not a whole number of frames' while self._gc and \ self.getfilled() + nframes > \ self._qsize / self._nchannels / self._sampwidth: time.sleep(0.1) if self._sampwidth == 1: import audioop data = audioop.add(data, '\x80'*len(data), 1) h1 = struct.pack('llHhllbbl', id(data)+MacOS.string_id_to_buffer, self._nchannels, self._outrate, 0, 0, 0, extSH, 60, nframes) h2 = 22*'\0' h3 = struct.pack('hhlll', self._sampwidth*8, 0, 0, 0, 0) header = h1+h2+h3 self._gc.append((header, data)) self._chan.SndDoCommand((bufferCmd, 0, header), 0) self._chan.SndDoCommand((callBackCmd, 0, 0), 0) def _callback(self, *args): del self._gc[0] if self._usercallback: self._usercallback() def setcallback(self, callback): self._usercallback = callback def getfilled(self): filled = 0 for header, data in self._gc: filled = filled + len(data) return filled / self._nchannels / self._sampwidth def getfillable(self): return (self._qsize / self._nchannels / self._sampwidth) - self.getfilled() def ulaw2lin(self, data): import audioop return audioop.ulaw2lin(data, 2) def test(): import aifc import EasyDialogs fn = EasyDialogs.AskFileForOpen(message="Select an AIFF soundfile", typeList=("AIFF",)) if not fn: return af = aifc.open(fn, 'r') print af.getparams() p = Play_Audio_mac() p.setoutrate(af.getframerate()) p.setsampwidth(af.getsampwidth()) p.setnchannels(af.getnchannels()) BUFSIZ = 10000 while 1: data = af.readframes(BUFSIZ) if not data: break p.writeframes(data) print 'wrote', len(data), 'space', p.getfillable() p.wait() if __name__ == '__main__': test() |