244 lines · 8.3 KB · Python
RawDownload
# Class interface to the CD module. import cd, CD class Error(Exception):    passclass _Stop(Exception):    pass def _doatime(self, cb_type, data):    if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end:##              print 'done with list entry', repr(self.listindex)        raise _Stop    func, arg = self.callbacks[cb_type]    if func:        func(arg, cb_type, data) def _dopnum(self, cb_type, data):    if data > self.end:##              print 'done with list entry', repr(self.listindex)        raise _Stop    func, arg = self.callbacks[cb_type]    if func:        func(arg, cb_type, data) class Readcd:    def __init__(self, *arg):        if len(arg) == 0:            self.player = cd.open()        elif len(arg) == 1:            self.player = cd.open(arg[0])        elif len(arg) == 2:            self.player = cd.open(arg[0], arg[1])        else:            raise Error, 'bad __init__ call'        self.list = []        self.callbacks = [(None, None)] * 8        self.parser = cd.createparser()        self.playing = 0        self.end = 0        self.status = None        self.trackinfo = None     def eject(self):        self.player.eject()        self.list = []        self.end = 0        self.listindex = 0        self.status = None        self.trackinfo = None        if self.playing:##                      print 'stop playing from eject'            raise _Stop     def pmsf2msf(self, track, min, sec, frame):        if not self.status:            self.cachestatus()        if track < self.status[5] or track > self.status[6]:            raise Error, 'track number out of range'        if not self.trackinfo:            self.cacheinfo()        start, total = self.trackinfo[track]        start = ((start[0] * 60) + start[1]) * 75 + start[2]        total = ((total[0] * 60) + total[1]) * 75 + total[2]        block = ((min * 60) + sec) * 75 + frame        if block > total:            raise Error, 'out of range'        block = start + block        min, block = divmod(block, 75*60)        sec, frame = divmod(block, 75)        return min, sec, frame     def reset(self):        self.list = []     def appendtrack(self, track):        self.appendstretch(track, track)     def appendstretch(self, start, end):        if not self.status:            self.cachestatus()        if not start:            start = 1        if not end:            end = self.status[6]        if type(end) == type(0):            if end < self.status[5] or end > self.status[6]:                raise Error, 'range error'        else:            l = len(end)            if l == 4:                prog, min, sec, frame = end                if prog < self.status[5] or prog > self.status[6]:                    raise Error, 'range error'                end = self.pmsf2msf(prog, min, sec, frame)            elif l != 3:                raise Error, 'syntax error'        if type(start) == type(0):            if start < self.status[5] or start > self.status[6]:                raise Error, 'range error'            if len(self.list) > 0:                s, e = self.list[-1]                if type(e) == type(0):                    if start == e+1:                        start = s                        del self.list[-1]        else:            l = len(start)            if l == 4:                prog, min, sec, frame = start                if prog < self.status[5] or prog > self.status[6]:                    raise Error, 'range error'                start = self.pmsf2msf(prog, min, sec, frame)            elif l != 3:                raise Error, 'syntax error'        self.list.append((start, end))     def settracks(self, list):        self.list = []        for track in list:            self.appendtrack(track)     def setcallback(self, cb_type, func, arg):        if cb_type < 0 or cb_type >= 8:            raise Error, 'type out of range'        self.callbacks[cb_type] = (func, arg)        if self.playing:            start, end = self.list[self.listindex]            if type(end) == type(0):                if cb_type != CD.PNUM:                    self.parser.setcallback(cb_type, func, arg)            else:                if cb_type != CD.ATIME:                    self.parser.setcallback(cb_type, func, arg)     def removecallback(self, cb_type):        if cb_type < 0 or cb_type >= 8:            raise Error, 'type out of range'        self.callbacks[cb_type] = (None, None)        if self.playing:            start, end = self.list[self.listindex]            if type(end) == type(0):                if cb_type != CD.PNUM:                    self.parser.removecallback(cb_type)            else:                if cb_type != CD.ATIME:                    self.parser.removecallback(cb_type)     def gettrackinfo(self, *arg):        if not self.status:            self.cachestatus()        if not self.trackinfo:            self.cacheinfo()        if len(arg) == 0:            return self.trackinfo[self.status[5]:self.status[6]+1]        result = []        for i in arg:            if i < self.status[5] or i > self.status[6]:                raise Error, 'range error'            result.append(self.trackinfo[i])        return result     def cacheinfo(self):        if not self.status:            self.cachestatus()        self.trackinfo = []        for i in range(self.status[5]):            self.trackinfo.append(None)        for i in range(self.status[5], self.status[6]+1):            self.trackinfo.append(self.player.gettrackinfo(i))     def cachestatus(self):        self.status = self.player.getstatus()        if self.status[0] == CD.NODISC:            self.status = None            raise Error, 'no disc in player'     def getstatus(self):        return self.player.getstatus()     def play(self):        if not self.status:            self.cachestatus()        size = self.player.bestreadsize()        self.listindex = 0        self.playing = 0        for i in range(8):            func, arg = self.callbacks[i]            if func:                self.parser.setcallback(i, func, arg)            else:                self.parser.removecallback(i)        if len(self.list) == 0:            for i in range(self.status[5], self.status[6]+1):                self.appendtrack(i)        try:            while 1:                if not self.playing:                    if self.listindex >= len(self.list):                        return                    start, end = self.list[self.listindex]                    if type(start) == type(0):                        dummy = self.player.seektrack(                                start)                    else:                        min, sec, frame = start                        dummy = self.player.seek(                                min, sec, frame)                    if type(end) == type(0):                        self.parser.setcallback(                                CD.PNUM, _dopnum, self)                        self.end = end                        func, arg = \                              self.callbacks[CD.ATIME]                        if func:                            self.parser.setcallback(CD.ATIME, func, arg)                        else:                            self.parser.removecallback(CD.ATIME)                    else:                        min, sec, frame = end                        self.parser.setcallback(                                CD.ATIME, _doatime,                                self)                        self.end = (min * 60 + sec) * \                                   75 + frame                        func, arg = \                              self.callbacks[CD.PNUM]                        if func:                            self.parser.setcallback(CD.PNUM, func, arg)                        else:                            self.parser.removecallback(CD.PNUM)                    self.playing = 1                data = self.player.readda(size)                if data == '':                    self.playing = 0                    self.listindex = self.listindex + 1                    continue                try:                    self.parser.parseframe(data)                except _Stop:                    self.playing = 0                    self.listindex = self.listindex + 1        finally:            self.playing = 0