PageRenderTime 41ms CodeModel.GetById 16ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/plat-irix6/readcd.py

http://unladen-swallow.googlecode.com/
Python | 247 lines | 225 code | 18 blank | 4 comment | 81 complexity | b5f596e4585433ee8c0c5a38e0c677f5 MD5 | raw file
  1# Class interface to the CD module.
  2from warnings import warnpy3k
  3warnpy3k("the readcd module has been removed in Python 3.0", stacklevel=2)
  4del warnpy3k
  5
  6import cd, CD
  7
  8class Error(Exception):
  9    pass
 10class _Stop(Exception):
 11    pass
 12
 13def _doatime(self, cb_type, data):
 14    if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end:
 15##              print 'done with list entry', repr(self.listindex)
 16        raise _Stop
 17    func, arg = self.callbacks[cb_type]
 18    if func:
 19        func(arg, cb_type, data)
 20
 21def _dopnum(self, cb_type, data):
 22    if data > self.end:
 23##              print 'done with list entry', repr(self.listindex)
 24        raise _Stop
 25    func, arg = self.callbacks[cb_type]
 26    if func:
 27        func(arg, cb_type, data)
 28
 29class Readcd:
 30    def __init__(self, *arg):
 31        if len(arg) == 0:
 32            self.player = cd.open()
 33        elif len(arg) == 1:
 34            self.player = cd.open(arg[0])
 35        elif len(arg) == 2:
 36            self.player = cd.open(arg[0], arg[1])
 37        else:
 38            raise Error, 'bad __init__ call'
 39        self.list = []
 40        self.callbacks = [(None, None)] * 8
 41        self.parser = cd.createparser()
 42        self.playing = 0
 43        self.end = 0
 44        self.status = None
 45        self.trackinfo = None
 46
 47    def eject(self):
 48        self.player.eject()
 49        self.list = []
 50        self.end = 0
 51        self.listindex = 0
 52        self.status = None
 53        self.trackinfo = None
 54        if self.playing:
 55##                      print 'stop playing from eject'
 56            raise _Stop
 57
 58    def pmsf2msf(self, track, min, sec, frame):
 59        if not self.status:
 60            self.cachestatus()
 61        if track < self.status[5] or track > self.status[6]:
 62            raise Error, 'track number out of range'
 63        if not self.trackinfo:
 64            self.cacheinfo()
 65        start, total = self.trackinfo[track]
 66        start = ((start[0] * 60) + start[1]) * 75 + start[2]
 67        total = ((total[0] * 60) + total[1]) * 75 + total[2]
 68        block = ((min * 60) + sec) * 75 + frame
 69        if block > total:
 70            raise Error, 'out of range'
 71        block = start + block
 72        min, block = divmod(block, 75*60)
 73        sec, frame = divmod(block, 75)
 74        return min, sec, frame
 75
 76    def reset(self):
 77        self.list = []
 78
 79    def appendtrack(self, track):
 80        self.appendstretch(track, track)
 81
 82    def appendstretch(self, start, end):
 83        if not self.status:
 84            self.cachestatus()
 85        if not start:
 86            start = 1
 87        if not end:
 88            end = self.status[6]
 89        if type(end) == type(0):
 90            if end < self.status[5] or end > self.status[6]:
 91                raise Error, 'range error'
 92        else:
 93            l = len(end)
 94            if l == 4:
 95                prog, min, sec, frame = end
 96                if prog < self.status[5] or prog > self.status[6]:
 97                    raise Error, 'range error'
 98                end = self.pmsf2msf(prog, min, sec, frame)
 99            elif l != 3:
100                raise Error, 'syntax error'
101        if type(start) == type(0):
102            if start < self.status[5] or start > self.status[6]:
103                raise Error, 'range error'
104            if len(self.list) > 0:
105                s, e = self.list[-1]
106                if type(e) == type(0):
107                    if start == e+1:
108                        start = s
109                        del self.list[-1]
110        else:
111            l = len(start)
112            if l == 4:
113                prog, min, sec, frame = start
114                if prog < self.status[5] or prog > self.status[6]:
115                    raise Error, 'range error'
116                start = self.pmsf2msf(prog, min, sec, frame)
117            elif l != 3:
118                raise Error, 'syntax error'
119        self.list.append((start, end))
120
121    def settracks(self, list):
122        self.list = []
123        for track in list:
124            self.appendtrack(track)
125
126    def setcallback(self, cb_type, func, arg):
127        if cb_type < 0 or cb_type >= 8:
128            raise Error, 'type out of range'
129        self.callbacks[cb_type] = (func, arg)
130        if self.playing:
131            start, end = self.list[self.listindex]
132            if type(end) == type(0):
133                if cb_type != CD.PNUM:
134                    self.parser.setcallback(cb_type, func, arg)
135            else:
136                if cb_type != CD.ATIME:
137                    self.parser.setcallback(cb_type, func, arg)
138
139    def removecallback(self, cb_type):
140        if cb_type < 0 or cb_type >= 8:
141            raise Error, 'type out of range'
142        self.callbacks[cb_type] = (None, None)
143        if self.playing:
144            start, end = self.list[self.listindex]
145            if type(end) == type(0):
146                if cb_type != CD.PNUM:
147                    self.parser.removecallback(cb_type)
148            else:
149                if cb_type != CD.ATIME:
150                    self.parser.removecallback(cb_type)
151
152    def gettrackinfo(self, *arg):
153        if not self.status:
154            self.cachestatus()
155        if not self.trackinfo:
156            self.cacheinfo()
157        if len(arg) == 0:
158            return self.trackinfo[self.status[5]:self.status[6]+1]
159        result = []
160        for i in arg:
161            if i < self.status[5] or i > self.status[6]:
162                raise Error, 'range error'
163            result.append(self.trackinfo[i])
164        return result
165
166    def cacheinfo(self):
167        if not self.status:
168            self.cachestatus()
169        self.trackinfo = []
170        for i in range(self.status[5]):
171            self.trackinfo.append(None)
172        for i in range(self.status[5], self.status[6]+1):
173            self.trackinfo.append(self.player.gettrackinfo(i))
174
175    def cachestatus(self):
176        self.status = self.player.getstatus()
177        if self.status[0] == CD.NODISC:
178            self.status = None
179            raise Error, 'no disc in player'
180
181    def getstatus(self):
182        return self.player.getstatus()
183
184    def play(self):
185        if not self.status:
186            self.cachestatus()
187        size = self.player.bestreadsize()
188        self.listindex = 0
189        self.playing = 0
190        for i in range(8):
191            func, arg = self.callbacks[i]
192            if func:
193                self.parser.setcallback(i, func, arg)
194            else:
195                self.parser.removecallback(i)
196        if len(self.list) == 0:
197            for i in range(self.status[5], self.status[6]+1):
198                self.appendtrack(i)
199        try:
200            while 1:
201                if not self.playing:
202                    if self.listindex >= len(self.list):
203                        return
204                    start, end = self.list[self.listindex]
205                    if type(start) == type(0):
206                        dummy = self.player.seektrack(
207                                start)
208                    else:
209                        min, sec, frame = start
210                        dummy = self.player.seek(
211                                min, sec, frame)
212                    if type(end) == type(0):
213                        self.parser.setcallback(
214                                CD.PNUM, _dopnum, self)
215                        self.end = end
216                        func, arg = \
217                              self.callbacks[CD.ATIME]
218                        if func:
219                            self.parser.setcallback(CD.ATIME, func, arg)
220                        else:
221                            self.parser.removecallback(CD.ATIME)
222                    else:
223                        min, sec, frame = end
224                        self.parser.setcallback(
225                                CD.ATIME, _doatime,
226                                self)
227                        self.end = (min * 60 + sec) * \
228                                   75 + frame
229                        func, arg = \
230                              self.callbacks[CD.PNUM]
231                        if func:
232                            self.parser.setcallback(CD.PNUM, func, arg)
233                        else:
234                            self.parser.removecallback(CD.PNUM)
235                    self.playing = 1
236                data = self.player.readda(size)
237                if data == '':
238                    self.playing = 0
239                    self.listindex = self.listindex + 1
240                    continue
241                try:
242                    self.parser.parseframe(data)
243                except _Stop:
244                    self.playing = 0
245                    self.listindex = self.listindex + 1
246        finally:
247            self.playing = 0