mirror of
https://github.com/python/cpython.git
synced 2025-08-02 16:13:13 +00:00
Initial revision
This commit is contained in:
parent
8176258421
commit
f94e309321
4 changed files with 668 additions and 0 deletions
104
Lib/irix5/readcd.doc
Executable file
104
Lib/irix5/readcd.doc
Executable file
|
@ -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".
|
230
Lib/irix5/readcd.py
Executable file
230
Lib/irix5/readcd.py
Executable file
|
@ -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
|
104
Lib/plat-irix5/readcd.doc
Executable file
104
Lib/plat-irix5/readcd.doc
Executable file
|
@ -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".
|
230
Lib/plat-irix5/readcd.py
Executable file
230
Lib/plat-irix5/readcd.py
Executable file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue