diff options
Diffstat (limited to 'Lib/irix5')
-rwxr-xr-x | Lib/irix5/readcd.doc | 104 | ||||
-rwxr-xr-x | Lib/irix5/readcd.py | 230 |
2 files changed, 334 insertions, 0 deletions
diff --git a/Lib/irix5/readcd.doc b/Lib/irix5/readcd.doc new file mode 100755 index 0000000..b827ccc --- /dev/null +++ b/Lib/irix5/readcd.doc @@ -0,0 +1,104 @@ +Interface to CD-ROM player. + +This module implements an interface to the built-in cd module. The +intention is to provide a more user-friendly interface than the +built-in module. + +The module defines a class Readcd with several methods. The +initialization of the class will try to open the CD player. This +means that initialization will fail if the CD player is already in +use. A RuntimeError will be raised by the cd module in that case. + +The way to work with this module is as follows. The user specifies +the parts of the CD that are to be read and he specifies callback +functions which are to be called by the system. At some point he can +tell the system to play. The specified parts of the CD will then be +read and the callbacks will be called. + +Initialization. +=============== + +r = readcd.Readcd().init([cd-player [, mode]]) + +The optional arguments are the name of the CD device and the mode. +When "mode" is not specified, it defaults to 'r' (which is the only +possible value); when "cd-player" also isn't specified, it defaults +to "None" which indicates the default CD player. + +Methods. +======== + +eject() -- Eject the CD from the player. + +reset() -- Reset the list of data stretches to be played. + +appendtrack(track) -- Append the specified track to the list of music +stretches. + +appendstretch(first, last) -- Append the stretch from "first" to "last" +to the list of music stretches. Both "first" and "last" can be in one +of four forms. "None": for "first", the beginning of the CD, for +"last" the end of the CD; a single integer: a track number--playing +starts at the beginning of the track or ends at the end of the +specified track; a three-tuple: the absolute time from the start of +the CD in minutes, seconds, frames; a four-tuple: track number and +relative time within the track in minutes, seconds, frames. + +settracks(tracklist) -- The argument is a list of integers. The list +of stretches is set to argument list. The old list is discarded. + +setcallback(type, func, arg) -- Set a callback function for "type". +The function will be called as func(arg, type, data) where "arg" is +the third argument of setcallback, "type" is the type of callback, +"data" is type-dependent data. See the CDsetcallback(3) manual page +for more information. The possible "type" arguments are defined in +the CD module. + +removecallback(type) -- Remove the callback for "type". + +gettrackinfo([tracklist]) -- Return a list of tuples. Each tuple +consists of start and length information of a track. The start and +length information consist of three-tuples with minutes, seconds and +frames. The optional tracklist argument gives a list of interesting +track numbers. If no tracklist is specified, information about all +tracks is returned. + +getstatus() -- Return the status information of the CD. + +play() -- Play the preprogrammed stretches of music from the CD. When +nothing was programmed, the whole CD is played. + +Specifying stretches. +===================== + +There are three methods available to specify a stretch of music to be +played. The easiest way is to use "settracklist(tracklist)" with which +a list of tracks can be specified. "settracklist(tracklist)" is +equivalent to the sequence + reset() + for track in tracklist: + appendtrack(track) + +The next method is "appendtrack(track)" with which a whole track can be +added to the list of music to be played. "appendtrack(track)" is +equivalent to "appendstretch(track, track)". + +The most complete method is "appendstretch(first, last)". Using this +method, it is possible to specify any stretch of music. + +When two consecutive tracks are played, it is possible to choose +whether the pause that may be between the tracks is played as well or +whether the pause should be skipped. When the end of a stretch is +specified using a track number and the next stretch starts at the +beginning of the following track and that was also specified using the +track number (that is, both were specified as integers, not as tuples), +the pause is played. When either value was specified using absolute +time or track-relative time (that is, as three-tuple or as +four-tuple), the pause will not be played. + +Errors. +======= + +When an error occurs, an exception will be raised. Depending on where +the error occurs, the exception may either be "readcd.Error" or +"RuntimeError". diff --git a/Lib/irix5/readcd.py b/Lib/irix5/readcd.py new file mode 100755 index 0000000..11ac87b --- /dev/null +++ b/Lib/irix5/readcd.py @@ -0,0 +1,230 @@ +# Class interface to the CD module. + +import cd, CD + +Error = 'Readcd.Error' +_Stop = 'Readcd.Stop' + +def _doatime(self, type, data): + if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end: + print 'done with list entry',`self.listindex` + raise _Stop + func, arg = self.callbacks[type] + if func: + func(arg, type, data) + +def _dopnum(self, type, data): + if data > self.end: + print 'done with list entry',`self.listindex` + raise _Stop + func, arg = self.callbacks[type] + if func: + func(arg, 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 + return self + + 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.status = self.player.getstatus() + if not self.trackinfo: + dummy = self.gettrackinfo() + if track < self.status[5] or track > self.status[6]: + raise Error, 'track number out of range' + 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.status = self.player.getstatus() + if not start: + start = 1 + if not end: + end = self.status[6] + try: + 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' + except TypeError: + if end < self.status[5] or end > self.status[6]: + raise Error, 'range error' + try: + 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' + except TypeError: + if start < self.status[5] or start > self.status[6]: + raise Error, 'range error' + if len(self.list) > 0: + s, e = self.list[-1] + try: + l = len(e) + except TypeError: + if start == e+1: + start = s + del self.list[-1] + self.list.append((start, end)) + + def settracks(self, list): + self.list = [] + for track in list: + self.appendtrack(track) + + def setcallback(self, type, func, arg): + if type < 0 or type >= 8: + raise Error, 'type out of range' + self.callbacks[type] = (func, arg) + if self.playing: + try: + l = len(end) + if type <> CD.ATIME: + self.parser.setcallback(type, func, arg) + except TypeError: + if type <> CD.PNUM: + self.parser.setcallback(type, func, arg) + + def removecallback(self, type): + if type < 0 or type >= 8: + raise Error, 'type out of range' + self.callbacks[type] = (None, None) + if self.playing: + try: + l = len(end) + if type <> CD.ATIME: + self.parser.removecallback(type) + except TypeError: + if type <> CD.PNUM: + self.parser.removecallback(type) + + def gettrackinfo(self, *arg): + if not self.status: + self.status = self.player.getstatus() + if not self.trackinfo: + 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)) + 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 getstatus(self): + if not self.status: + status = self.player.getstatus() + if status[0] <> CD.NODISC: + self.status = status + else: + status = self.status + return status + + def play(self): + if not self.status: + self.status = self.player.getstatus() + 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) + while 1: + if not self.playing: + if self.listindex >= len(self.list): + return + start, end = self.list[self.listindex] + print 'starting with',`(start, end)` + try: + min, sec, frame = start + dummy = self.player.seek(min, sec, frame) + except TypeError: + dummy = self.player.seektrack(start) + try: + 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) + except TypeError: + 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) + 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 |