blob: f278ba4bf0c536808f4c9776d8e75deb77754382 [file] [log] [blame]
Guido van Rossumf94e3091992-04-22 13:24:13 +00001# Class interface to the CD module.
2
3import cd, CD
4
Fred Drakedef00382000-08-18 14:59:33 +00005class Error(Exception):
6 pass
7class _Stop(Exception):
8 pass
Guido van Rossumf94e3091992-04-22 13:24:13 +00009
Sjoerd Mullender04321d11993-03-29 10:50:29 +000010def _doatime(self, cb_type, data):
Guido van Rossumf94e3091992-04-22 13:24:13 +000011 if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end:
Walter Dörwald70a6b492004-02-12 17:35:32 +000012## print 'done with list entry', repr(self.listindex)
Guido van Rossumf94e3091992-04-22 13:24:13 +000013 raise _Stop
Sjoerd Mullender04321d11993-03-29 10:50:29 +000014 func, arg = self.callbacks[cb_type]
Guido van Rossumf94e3091992-04-22 13:24:13 +000015 if func:
Sjoerd Mullender04321d11993-03-29 10:50:29 +000016 func(arg, cb_type, data)
Guido van Rossumf94e3091992-04-22 13:24:13 +000017
Sjoerd Mullender04321d11993-03-29 10:50:29 +000018def _dopnum(self, cb_type, data):
Guido van Rossumf94e3091992-04-22 13:24:13 +000019 if data > self.end:
Walter Dörwald70a6b492004-02-12 17:35:32 +000020## print 'done with list entry', repr(self.listindex)
Guido van Rossumf94e3091992-04-22 13:24:13 +000021 raise _Stop
Sjoerd Mullender04321d11993-03-29 10:50:29 +000022 func, arg = self.callbacks[cb_type]
Guido van Rossumf94e3091992-04-22 13:24:13 +000023 if func:
Sjoerd Mullender04321d11993-03-29 10:50:29 +000024 func(arg, cb_type, data)
Guido van Rossumf94e3091992-04-22 13:24:13 +000025
Guido van Rossumd3166071993-05-24 14:16:22 +000026class Readcd:
Sjoerd Mullenderb2e358d1993-11-08 15:10:43 +000027 def __init__(self, *arg):
Guido van Rossumf94e3091992-04-22 13:24:13 +000028 if len(arg) == 0:
29 self.player = cd.open()
30 elif len(arg) == 1:
31 self.player = cd.open(arg[0])
32 elif len(arg) == 2:
33 self.player = cd.open(arg[0], arg[1])
34 else:
Guido van Rossum7bc817d1993-12-17 15:25:27 +000035 raise Error, 'bad __init__ call'
Guido van Rossumf94e3091992-04-22 13:24:13 +000036 self.list = []
37 self.callbacks = [(None, None)] * 8
38 self.parser = cd.createparser()
39 self.playing = 0
40 self.end = 0
41 self.status = None
42 self.trackinfo = None
Guido van Rossumf94e3091992-04-22 13:24:13 +000043
44 def eject(self):
45 self.player.eject()
46 self.list = []
47 self.end = 0
48 self.listindex = 0
49 self.status = None
50 self.trackinfo = None
51 if self.playing:
Guido van Rossumada67ec1992-06-03 16:47:24 +000052## print 'stop playing from eject'
Guido van Rossumf94e3091992-04-22 13:24:13 +000053 raise _Stop
54
55 def pmsf2msf(self, track, min, sec, frame):
56 if not self.status:
Guido van Rossum58230c31992-04-22 14:33:26 +000057 self.cachestatus()
Guido van Rossumf94e3091992-04-22 13:24:13 +000058 if track < self.status[5] or track > self.status[6]:
59 raise Error, 'track number out of range'
Guido van Rossum58230c31992-04-22 14:33:26 +000060 if not self.trackinfo:
61 self.cacheinfo()
Guido van Rossumf94e3091992-04-22 13:24:13 +000062 start, total = self.trackinfo[track]
63 start = ((start[0] * 60) + start[1]) * 75 + start[2]
64 total = ((total[0] * 60) + total[1]) * 75 + total[2]
65 block = ((min * 60) + sec) * 75 + frame
66 if block > total:
67 raise Error, 'out of range'
68 block = start + block
69 min, block = divmod(block, 75*60)
70 sec, frame = divmod(block, 75)
71 return min, sec, frame
72
73 def reset(self):
74 self.list = []
75
76 def appendtrack(self, track):
77 self.appendstretch(track, track)
78
79 def appendstretch(self, start, end):
80 if not self.status:
Guido van Rossum58230c31992-04-22 14:33:26 +000081 self.cachestatus()
Guido van Rossumf94e3091992-04-22 13:24:13 +000082 if not start:
83 start = 1
84 if not end:
85 end = self.status[6]
Sjoerd Mullender04321d11993-03-29 10:50:29 +000086 if type(end) == type(0):
87 if end < self.status[5] or end > self.status[6]:
88 raise Error, 'range error'
89 else:
Guido van Rossumf94e3091992-04-22 13:24:13 +000090 l = len(end)
91 if l == 4:
92 prog, min, sec, frame = end
93 if prog < self.status[5] or prog > self.status[6]:
94 raise Error, 'range error'
95 end = self.pmsf2msf(prog, min, sec, frame)
Fred Drake132dce22000-12-12 23:11:42 +000096 elif l != 3:
Guido van Rossumf94e3091992-04-22 13:24:13 +000097 raise Error, 'syntax error'
Sjoerd Mullender04321d11993-03-29 10:50:29 +000098 if type(start) == type(0):
99 if start < self.status[5] or start > self.status[6]:
Guido van Rossumf94e3091992-04-22 13:24:13 +0000100 raise Error, 'range error'
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000101 if len(self.list) > 0:
102 s, e = self.list[-1]
103 if type(e) == type(0):
104 if start == e+1:
105 start = s
106 del self.list[-1]
107 else:
Guido van Rossumf94e3091992-04-22 13:24:13 +0000108 l = len(start)
109 if l == 4:
110 prog, min, sec, frame = start
111 if prog < self.status[5] or prog > self.status[6]:
112 raise Error, 'range error'
113 start = self.pmsf2msf(prog, min, sec, frame)
Fred Drake132dce22000-12-12 23:11:42 +0000114 elif l != 3:
Guido van Rossumf94e3091992-04-22 13:24:13 +0000115 raise Error, 'syntax error'
Guido van Rossumf94e3091992-04-22 13:24:13 +0000116 self.list.append((start, end))
117
118 def settracks(self, list):
119 self.list = []
120 for track in list:
121 self.appendtrack(track)
122
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000123 def setcallback(self, cb_type, func, arg):
124 if cb_type < 0 or cb_type >= 8:
Guido van Rossumf94e3091992-04-22 13:24:13 +0000125 raise Error, 'type out of range'
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000126 self.callbacks[cb_type] = (func, arg)
Guido van Rossumf94e3091992-04-22 13:24:13 +0000127 if self.playing:
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000128 start, end = self.list[self.listindex]
129 if type(end) == type(0):
Fred Drake132dce22000-12-12 23:11:42 +0000130 if cb_type != CD.PNUM:
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000131 self.parser.setcallback(cb_type, func, arg)
132 else:
Fred Drake132dce22000-12-12 23:11:42 +0000133 if cb_type != CD.ATIME:
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000134 self.parser.setcallback(cb_type, func, arg)
Guido van Rossumf94e3091992-04-22 13:24:13 +0000135
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000136 def removecallback(self, cb_type):
137 if cb_type < 0 or cb_type >= 8:
Guido van Rossumf94e3091992-04-22 13:24:13 +0000138 raise Error, 'type out of range'
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000139 self.callbacks[cb_type] = (None, None)
Guido van Rossumf94e3091992-04-22 13:24:13 +0000140 if self.playing:
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000141 start, end = self.list[self.listindex]
142 if type(end) == type(0):
Fred Drake132dce22000-12-12 23:11:42 +0000143 if cb_type != CD.PNUM:
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000144 self.parser.removecallback(cb_type)
145 else:
Fred Drake132dce22000-12-12 23:11:42 +0000146 if cb_type != CD.ATIME:
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000147 self.parser.removecallback(cb_type)
Guido van Rossumf94e3091992-04-22 13:24:13 +0000148
149 def gettrackinfo(self, *arg):
150 if not self.status:
Guido van Rossum58230c31992-04-22 14:33:26 +0000151 self.cachestatus()
Guido van Rossumf94e3091992-04-22 13:24:13 +0000152 if not self.trackinfo:
Guido van Rossum58230c31992-04-22 14:33:26 +0000153 self.cacheinfo()
Guido van Rossumf94e3091992-04-22 13:24:13 +0000154 if len(arg) == 0:
155 return self.trackinfo[self.status[5]:self.status[6]+1]
156 result = []
157 for i in arg:
158 if i < self.status[5] or i > self.status[6]:
159 raise Error, 'range error'
160 result.append(self.trackinfo[i])
161 return result
162
Guido van Rossum58230c31992-04-22 14:33:26 +0000163 def cacheinfo(self):
164 if not self.status:
165 self.cachestatus()
166 self.trackinfo = []
167 for i in range(self.status[5]):
168 self.trackinfo.append(None)
169 for i in range(self.status[5], self.status[6]+1):
170 self.trackinfo.append(self.player.gettrackinfo(i))
171
172 def cachestatus(self):
Guido van Rossumdee5d8e1992-04-22 13:44:48 +0000173 self.status = self.player.getstatus()
Guido van Rossuma3cd0711992-04-23 11:34:39 +0000174 if self.status[0] == CD.NODISC:
Guido van Rossum58230c31992-04-22 14:33:26 +0000175 self.status = None
Guido van Rossuma3cd0711992-04-23 11:34:39 +0000176 raise Error, 'no disc in player'
Guido van Rossum58230c31992-04-22 14:33:26 +0000177
178 def getstatus(self):
179 return self.player.getstatus()
Guido van Rossumf94e3091992-04-22 13:24:13 +0000180
181 def play(self):
182 if not self.status:
Guido van Rossum58230c31992-04-22 14:33:26 +0000183 self.cachestatus()
Guido van Rossumf94e3091992-04-22 13:24:13 +0000184 size = self.player.bestreadsize()
185 self.listindex = 0
186 self.playing = 0
187 for i in range(8):
188 func, arg = self.callbacks[i]
189 if func:
190 self.parser.setcallback(i, func, arg)
191 else:
192 self.parser.removecallback(i)
193 if len(self.list) == 0:
194 for i in range(self.status[5], self.status[6]+1):
195 self.appendtrack(i)
Sjoerd Mullender992ff061995-02-01 14:24:32 +0000196 try:
197 while 1:
198 if not self.playing:
199 if self.listindex >= len(self.list):
200 return
201 start, end = self.list[self.listindex]
202 if type(start) == type(0):
203 dummy = self.player.seektrack(
204 start)
Sjoerd Mullender04321d11993-03-29 10:50:29 +0000205 else:
Sjoerd Mullender992ff061995-02-01 14:24:32 +0000206 min, sec, frame = start
207 dummy = self.player.seek(
208 min, sec, frame)
209 if type(end) == type(0):
210 self.parser.setcallback(
211 CD.PNUM, _dopnum, self)
212 self.end = end
213 func, arg = \
214 self.callbacks[CD.ATIME]
215 if func:
216 self.parser.setcallback(CD.ATIME, func, arg)
217 else:
218 self.parser.removecallback(CD.ATIME)
Guido van Rossumf94e3091992-04-22 13:24:13 +0000219 else:
Sjoerd Mullender992ff061995-02-01 14:24:32 +0000220 min, sec, frame = end
221 self.parser.setcallback(
222 CD.ATIME, _doatime,
223 self)
224 self.end = (min * 60 + sec) * \
225 75 + frame
226 func, arg = \
227 self.callbacks[CD.PNUM]
228 if func:
229 self.parser.setcallback(CD.PNUM, func, arg)
230 else:
231 self.parser.removecallback(CD.PNUM)
232 self.playing = 1
233 data = self.player.readda(size)
234 if data == '':
235 self.playing = 0
236 self.listindex = self.listindex + 1
237 continue
238 try:
239 self.parser.parseframe(data)
240 except _Stop:
241 self.playing = 0
242 self.listindex = self.listindex + 1
243 finally:
244 self.playing = 0