1f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum# Class interface to the CD module. 2cd2de082571042f0cf95e06f66c4cc727e82b541Brett Cannonfrom warnings import warnpy3k 3cd2de082571042f0cf95e06f66c4cc727e82b541Brett Cannonwarnpy3k("the readcd module has been removed in Python 3.0", stacklevel=2) 4cd2de082571042f0cf95e06f66c4cc727e82b541Brett Cannondel warnpy3k 5f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum 6f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossumimport cd, CD 7f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum 8def003845b687b785f70d655a5372906f7e042d2Fred Drakeclass Error(Exception): 9182b5aca27d376b08a2904bed42b751496f932f3Tim Peters pass 10def003845b687b785f70d655a5372906f7e042d2Fred Drakeclass _Stop(Exception): 11182b5aca27d376b08a2904bed42b751496f932f3Tim Peters pass 12f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum 1304321d1e472ac2ffd06776f117a5ec14e76b7bb7Sjoerd Mullenderdef _doatime(self, cb_type, data): 14182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end: 15182b5aca27d376b08a2904bed42b751496f932f3Tim Peters## print 'done with list entry', repr(self.listindex) 16182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise _Stop 17182b5aca27d376b08a2904bed42b751496f932f3Tim Peters func, arg = self.callbacks[cb_type] 18182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if func: 19182b5aca27d376b08a2904bed42b751496f932f3Tim Peters func(arg, cb_type, data) 20f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum 2104321d1e472ac2ffd06776f117a5ec14e76b7bb7Sjoerd Mullenderdef _dopnum(self, cb_type, data): 22182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if data > self.end: 23182b5aca27d376b08a2904bed42b751496f932f3Tim Peters## print 'done with list entry', repr(self.listindex) 24182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise _Stop 25182b5aca27d376b08a2904bed42b751496f932f3Tim Peters func, arg = self.callbacks[cb_type] 26182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if func: 27182b5aca27d376b08a2904bed42b751496f932f3Tim Peters func(arg, cb_type, data) 28f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum 29d316607732aa70361d5793f6b301b70fab7ca367Guido van Rossumclass Readcd: 30182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def __init__(self, *arg): 31182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if len(arg) == 0: 32182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.player = cd.open() 33182b5aca27d376b08a2904bed42b751496f932f3Tim Peters elif len(arg) == 1: 34182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.player = cd.open(arg[0]) 35182b5aca27d376b08a2904bed42b751496f932f3Tim Peters elif len(arg) == 2: 36182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.player = cd.open(arg[0], arg[1]) 37182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 38182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'bad __init__ call' 39182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.list = [] 40182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.callbacks = [(None, None)] * 8 41182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser = cd.createparser() 42182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.playing = 0 43182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.end = 0 44182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.status = None 45182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.trackinfo = None 46182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 47182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def eject(self): 48182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.player.eject() 49182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.list = [] 50182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.end = 0 51182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.listindex = 0 52182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.status = None 53182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.trackinfo = None 54182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if self.playing: 55182b5aca27d376b08a2904bed42b751496f932f3Tim Peters## print 'stop playing from eject' 56182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise _Stop 57182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 58182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def pmsf2msf(self, track, min, sec, frame): 59182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.status: 60182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.cachestatus() 61182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if track < self.status[5] or track > self.status[6]: 62182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'track number out of range' 63182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.trackinfo: 64182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.cacheinfo() 65182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start, total = self.trackinfo[track] 66182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start = ((start[0] * 60) + start[1]) * 75 + start[2] 67182b5aca27d376b08a2904bed42b751496f932f3Tim Peters total = ((total[0] * 60) + total[1]) * 75 + total[2] 68182b5aca27d376b08a2904bed42b751496f932f3Tim Peters block = ((min * 60) + sec) * 75 + frame 69182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if block > total: 70182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'out of range' 71182b5aca27d376b08a2904bed42b751496f932f3Tim Peters block = start + block 72182b5aca27d376b08a2904bed42b751496f932f3Tim Peters min, block = divmod(block, 75*60) 73182b5aca27d376b08a2904bed42b751496f932f3Tim Peters sec, frame = divmod(block, 75) 74182b5aca27d376b08a2904bed42b751496f932f3Tim Peters return min, sec, frame 75182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 76182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def reset(self): 77182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.list = [] 78182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 79182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def appendtrack(self, track): 80182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.appendstretch(track, track) 81182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 82182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def appendstretch(self, start, end): 83182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.status: 84182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.cachestatus() 85182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not start: 86182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start = 1 87182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not end: 88182b5aca27d376b08a2904bed42b751496f932f3Tim Peters end = self.status[6] 89182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if type(end) == type(0): 90182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if end < self.status[5] or end > self.status[6]: 91182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'range error' 92182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 93182b5aca27d376b08a2904bed42b751496f932f3Tim Peters l = len(end) 94182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if l == 4: 95182b5aca27d376b08a2904bed42b751496f932f3Tim Peters prog, min, sec, frame = end 96182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if prog < self.status[5] or prog > self.status[6]: 97182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'range error' 98182b5aca27d376b08a2904bed42b751496f932f3Tim Peters end = self.pmsf2msf(prog, min, sec, frame) 99182b5aca27d376b08a2904bed42b751496f932f3Tim Peters elif l != 3: 100182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'syntax error' 101182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if type(start) == type(0): 102182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if start < self.status[5] or start > self.status[6]: 103182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'range error' 104182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if len(self.list) > 0: 105182b5aca27d376b08a2904bed42b751496f932f3Tim Peters s, e = self.list[-1] 106182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if type(e) == type(0): 107182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if start == e+1: 108182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start = s 109182b5aca27d376b08a2904bed42b751496f932f3Tim Peters del self.list[-1] 110182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 111182b5aca27d376b08a2904bed42b751496f932f3Tim Peters l = len(start) 112182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if l == 4: 113182b5aca27d376b08a2904bed42b751496f932f3Tim Peters prog, min, sec, frame = start 114182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if prog < self.status[5] or prog > self.status[6]: 115182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'range error' 116182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start = self.pmsf2msf(prog, min, sec, frame) 117182b5aca27d376b08a2904bed42b751496f932f3Tim Peters elif l != 3: 118182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'syntax error' 119182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.list.append((start, end)) 120182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 121182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def settracks(self, list): 122182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.list = [] 123182b5aca27d376b08a2904bed42b751496f932f3Tim Peters for track in list: 124182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.appendtrack(track) 125182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 126182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def setcallback(self, cb_type, func, arg): 127182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if cb_type < 0 or cb_type >= 8: 128182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'type out of range' 129182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.callbacks[cb_type] = (func, arg) 130182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if self.playing: 131182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start, end = self.list[self.listindex] 132182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if type(end) == type(0): 133182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if cb_type != CD.PNUM: 134182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.setcallback(cb_type, func, arg) 135182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 136182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if cb_type != CD.ATIME: 137182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.setcallback(cb_type, func, arg) 138182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 139182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def removecallback(self, cb_type): 140182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if cb_type < 0 or cb_type >= 8: 141182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'type out of range' 142182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.callbacks[cb_type] = (None, None) 143182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if self.playing: 144182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start, end = self.list[self.listindex] 145182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if type(end) == type(0): 146182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if cb_type != CD.PNUM: 147182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.removecallback(cb_type) 148182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 149182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if cb_type != CD.ATIME: 150182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.removecallback(cb_type) 151182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 152182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def gettrackinfo(self, *arg): 153182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.status: 154182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.cachestatus() 155182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.trackinfo: 156182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.cacheinfo() 157182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if len(arg) == 0: 158182b5aca27d376b08a2904bed42b751496f932f3Tim Peters return self.trackinfo[self.status[5]:self.status[6]+1] 159182b5aca27d376b08a2904bed42b751496f932f3Tim Peters result = [] 160182b5aca27d376b08a2904bed42b751496f932f3Tim Peters for i in arg: 161182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if i < self.status[5] or i > self.status[6]: 162182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'range error' 163182b5aca27d376b08a2904bed42b751496f932f3Tim Peters result.append(self.trackinfo[i]) 164182b5aca27d376b08a2904bed42b751496f932f3Tim Peters return result 165182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 166182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def cacheinfo(self): 167182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.status: 168182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.cachestatus() 169182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.trackinfo = [] 170182b5aca27d376b08a2904bed42b751496f932f3Tim Peters for i in range(self.status[5]): 171182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.trackinfo.append(None) 172182b5aca27d376b08a2904bed42b751496f932f3Tim Peters for i in range(self.status[5], self.status[6]+1): 173182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.trackinfo.append(self.player.gettrackinfo(i)) 174182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 175182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def cachestatus(self): 176182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.status = self.player.getstatus() 177182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if self.status[0] == CD.NODISC: 178182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.status = None 179182b5aca27d376b08a2904bed42b751496f932f3Tim Peters raise Error, 'no disc in player' 180182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 181182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def getstatus(self): 182182b5aca27d376b08a2904bed42b751496f932f3Tim Peters return self.player.getstatus() 183182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 184182b5aca27d376b08a2904bed42b751496f932f3Tim Peters def play(self): 185182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.status: 186182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.cachestatus() 187182b5aca27d376b08a2904bed42b751496f932f3Tim Peters size = self.player.bestreadsize() 188182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.listindex = 0 189182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.playing = 0 190182b5aca27d376b08a2904bed42b751496f932f3Tim Peters for i in range(8): 191182b5aca27d376b08a2904bed42b751496f932f3Tim Peters func, arg = self.callbacks[i] 192182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if func: 193182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.setcallback(i, func, arg) 194182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 195182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.removecallback(i) 196182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if len(self.list) == 0: 197182b5aca27d376b08a2904bed42b751496f932f3Tim Peters for i in range(self.status[5], self.status[6]+1): 198182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.appendtrack(i) 199182b5aca27d376b08a2904bed42b751496f932f3Tim Peters try: 200182b5aca27d376b08a2904bed42b751496f932f3Tim Peters while 1: 201182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if not self.playing: 202182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if self.listindex >= len(self.list): 203182b5aca27d376b08a2904bed42b751496f932f3Tim Peters return 204182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start, end = self.list[self.listindex] 205182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if type(start) == type(0): 206182b5aca27d376b08a2904bed42b751496f932f3Tim Peters dummy = self.player.seektrack( 207182b5aca27d376b08a2904bed42b751496f932f3Tim Peters start) 208182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 209182b5aca27d376b08a2904bed42b751496f932f3Tim Peters min, sec, frame = start 210182b5aca27d376b08a2904bed42b751496f932f3Tim Peters dummy = self.player.seek( 211182b5aca27d376b08a2904bed42b751496f932f3Tim Peters min, sec, frame) 212182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if type(end) == type(0): 213182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.setcallback( 214182b5aca27d376b08a2904bed42b751496f932f3Tim Peters CD.PNUM, _dopnum, self) 215182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.end = end 216182b5aca27d376b08a2904bed42b751496f932f3Tim Peters func, arg = \ 217182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.callbacks[CD.ATIME] 218182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if func: 219182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.setcallback(CD.ATIME, func, arg) 220182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 221182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.removecallback(CD.ATIME) 222182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 223182b5aca27d376b08a2904bed42b751496f932f3Tim Peters min, sec, frame = end 224182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.setcallback( 225182b5aca27d376b08a2904bed42b751496f932f3Tim Peters CD.ATIME, _doatime, 226182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self) 227182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.end = (min * 60 + sec) * \ 228182b5aca27d376b08a2904bed42b751496f932f3Tim Peters 75 + frame 229182b5aca27d376b08a2904bed42b751496f932f3Tim Peters func, arg = \ 230182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.callbacks[CD.PNUM] 231182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if func: 232182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.setcallback(CD.PNUM, func, arg) 233182b5aca27d376b08a2904bed42b751496f932f3Tim Peters else: 234182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.removecallback(CD.PNUM) 235182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.playing = 1 236182b5aca27d376b08a2904bed42b751496f932f3Tim Peters data = self.player.readda(size) 237182b5aca27d376b08a2904bed42b751496f932f3Tim Peters if data == '': 238182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.playing = 0 239182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.listindex = self.listindex + 1 240182b5aca27d376b08a2904bed42b751496f932f3Tim Peters continue 241182b5aca27d376b08a2904bed42b751496f932f3Tim Peters try: 242182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.parser.parseframe(data) 243182b5aca27d376b08a2904bed42b751496f932f3Tim Peters except _Stop: 244182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.playing = 0 245182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.listindex = self.listindex + 1 246182b5aca27d376b08a2904bed42b751496f932f3Tim Peters finally: 247182b5aca27d376b08a2904bed42b751496f932f3Tim Peters self.playing = 0 248