1f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum# Class interface to the CD module.
2cd2de082571042f0cf95e06f66c4cc727e82b541Brett Cannonfrom warnings import warnpy3k
3cd2de082571042f0cf95e06f66c4cc727e82b541Brett Cannonwarnpy3k("the readcd module has been removed in Python 3.0", stacklevel=2)
4cd2de082571042f0cf95e06f66c4cc727e82b541Brett Cannondel warnpy3k
5f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum
6f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossumimport cd, CD
7f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum
8def003845b687b785f70d655a5372906f7e042d2Fred Drakeclass Error(Exception):
9182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    pass
10def003845b687b785f70d655a5372906f7e042d2Fred Drakeclass _Stop(Exception):
11182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    pass
12f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum
1304321d1e472ac2ffd06776f117a5ec14e76b7bb7Sjoerd Mullenderdef _doatime(self, cb_type, data):
14182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    if ((data[0] * 60) + data[1]) * 75 + data[2] > self.end:
15182b5aca27d376b08a2904bed42b751496f932f3Tim Peters##              print 'done with list entry', repr(self.listindex)
16182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        raise _Stop
17182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    func, arg = self.callbacks[cb_type]
18182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    if func:
19182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        func(arg, cb_type, data)
20f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum
2104321d1e472ac2ffd06776f117a5ec14e76b7bb7Sjoerd Mullenderdef _dopnum(self, cb_type, data):
22182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    if data > self.end:
23182b5aca27d376b08a2904bed42b751496f932f3Tim Peters##              print 'done with list entry', repr(self.listindex)
24182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        raise _Stop
25182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    func, arg = self.callbacks[cb_type]
26182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    if func:
27182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        func(arg, cb_type, data)
28f94e30932163851ca8375c373e07e6b68e416bc0Guido van Rossum
29d316607732aa70361d5793f6b301b70fab7ca367Guido van Rossumclass Readcd:
30182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def __init__(self, *arg):
31182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if len(arg) == 0:
32182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.player = cd.open()
33182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        elif len(arg) == 1:
34182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.player = cd.open(arg[0])
35182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        elif len(arg) == 2:
36182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.player = cd.open(arg[0], arg[1])
37182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        else:
38182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            raise Error, 'bad __init__ call'
39182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.list = []
40182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.callbacks = [(None, None)] * 8
41182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.parser = cd.createparser()
42182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.playing = 0
43182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.end = 0
44182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.status = None
45182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.trackinfo = None
46182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
47182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def eject(self):
48182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.player.eject()
49182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.list = []
50182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.end = 0
51182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.listindex = 0
52182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.status = None
53182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.trackinfo = None
54182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if self.playing:
55182b5aca27d376b08a2904bed42b751496f932f3Tim Peters##                      print 'stop playing from eject'
56182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            raise _Stop
57182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
58182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def pmsf2msf(self, track, min, sec, frame):
59182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not self.status:
60182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.cachestatus()
61182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if track < self.status[5] or track > self.status[6]:
62182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            raise Error, 'track number out of range'
63182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not self.trackinfo:
64182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.cacheinfo()
65182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        start, total = self.trackinfo[track]
66182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        start = ((start[0] * 60) + start[1]) * 75 + start[2]
67182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        total = ((total[0] * 60) + total[1]) * 75 + total[2]
68182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        block = ((min * 60) + sec) * 75 + frame
69182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if block > total:
70182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            raise Error, 'out of range'
71182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        block = start + block
72182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        min, block = divmod(block, 75*60)
73182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        sec, frame = divmod(block, 75)
74182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        return min, sec, frame
75182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
76182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def reset(self):
77182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.list = []
78182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
79182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def appendtrack(self, track):
80182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.appendstretch(track, track)
81182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
82182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def appendstretch(self, start, end):
83182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not self.status:
84182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.cachestatus()
85182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not start:
86182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            start = 1
87182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not end:
88182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            end = self.status[6]
89182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if type(end) == type(0):
90182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if end < self.status[5] or end > self.status[6]:
91182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                raise Error, 'range error'
92182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        else:
93182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            l = len(end)
94182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if l == 4:
95182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                prog, min, sec, frame = end
96182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if prog < self.status[5] or prog > self.status[6]:
97182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    raise Error, 'range error'
98182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                end = self.pmsf2msf(prog, min, sec, frame)
99182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            elif l != 3:
100182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                raise Error, 'syntax error'
101182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if type(start) == type(0):
102182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if start < self.status[5] or start > self.status[6]:
103182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                raise Error, 'range error'
104182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if len(self.list) > 0:
105182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                s, e = self.list[-1]
106182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if type(e) == type(0):
107182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    if start == e+1:
108182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        start = s
109182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        del self.list[-1]
110182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        else:
111182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            l = len(start)
112182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if l == 4:
113182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                prog, min, sec, frame = start
114182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if prog < self.status[5] or prog > self.status[6]:
115182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    raise Error, 'range error'
116182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                start = self.pmsf2msf(prog, min, sec, frame)
117182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            elif l != 3:
118182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                raise Error, 'syntax error'
119182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.list.append((start, end))
120182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
121182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def settracks(self, list):
122182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.list = []
123182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        for track in list:
124182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.appendtrack(track)
125182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
126182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def setcallback(self, cb_type, func, arg):
127182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if cb_type < 0 or cb_type >= 8:
128182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            raise Error, 'type out of range'
129182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.callbacks[cb_type] = (func, arg)
130182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if self.playing:
131182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            start, end = self.list[self.listindex]
132182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if type(end) == type(0):
133182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if cb_type != CD.PNUM:
134182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.parser.setcallback(cb_type, func, arg)
135182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            else:
136182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if cb_type != CD.ATIME:
137182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.parser.setcallback(cb_type, func, arg)
138182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
139182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def removecallback(self, cb_type):
140182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if cb_type < 0 or cb_type >= 8:
141182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            raise Error, 'type out of range'
142182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.callbacks[cb_type] = (None, None)
143182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if self.playing:
144182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            start, end = self.list[self.listindex]
145182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if type(end) == type(0):
146182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if cb_type != CD.PNUM:
147182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.parser.removecallback(cb_type)
148182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            else:
149182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if cb_type != CD.ATIME:
150182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.parser.removecallback(cb_type)
151182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
152182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def gettrackinfo(self, *arg):
153182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not self.status:
154182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.cachestatus()
155182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not self.trackinfo:
156182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.cacheinfo()
157182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if len(arg) == 0:
158182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            return self.trackinfo[self.status[5]:self.status[6]+1]
159182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        result = []
160182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        for i in arg:
161182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if i < self.status[5] or i > self.status[6]:
162182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                raise Error, 'range error'
163182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            result.append(self.trackinfo[i])
164182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        return result
165182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
166182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def cacheinfo(self):
167182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not self.status:
168182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.cachestatus()
169182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.trackinfo = []
170182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        for i in range(self.status[5]):
171182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.trackinfo.append(None)
172182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        for i in range(self.status[5], self.status[6]+1):
173182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.trackinfo.append(self.player.gettrackinfo(i))
174182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
175182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def cachestatus(self):
176182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.status = self.player.getstatus()
177182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if self.status[0] == CD.NODISC:
178182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.status = None
179182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            raise Error, 'no disc in player'
180182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
181182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def getstatus(self):
182182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        return self.player.getstatus()
183182b5aca27d376b08a2904bed42b751496f932f3Tim Peters
184182b5aca27d376b08a2904bed42b751496f932f3Tim Peters    def play(self):
185182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if not self.status:
186182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.cachestatus()
187182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        size = self.player.bestreadsize()
188182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.listindex = 0
189182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        self.playing = 0
190182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        for i in range(8):
191182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            func, arg = self.callbacks[i]
192182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            if func:
193182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                self.parser.setcallback(i, func, arg)
194182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            else:
195182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                self.parser.removecallback(i)
196182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        if len(self.list) == 0:
197182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            for i in range(self.status[5], self.status[6]+1):
198182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                self.appendtrack(i)
199182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        try:
200182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            while 1:
201182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if not self.playing:
202182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    if self.listindex >= len(self.list):
203182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        return
204182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    start, end = self.list[self.listindex]
205182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    if type(start) == type(0):
206182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        dummy = self.player.seektrack(
207182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                                start)
208182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    else:
209182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        min, sec, frame = start
210182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        dummy = self.player.seek(
211182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                                min, sec, frame)
212182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    if type(end) == type(0):
213182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        self.parser.setcallback(
214182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                                CD.PNUM, _dopnum, self)
215182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        self.end = end
216182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        func, arg = \
217182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                              self.callbacks[CD.ATIME]
218182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        if func:
219182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                            self.parser.setcallback(CD.ATIME, func, arg)
220182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        else:
221182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                            self.parser.removecallback(CD.ATIME)
222182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    else:
223182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        min, sec, frame = end
224182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        self.parser.setcallback(
225182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                                CD.ATIME, _doatime,
226182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                                self)
227182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        self.end = (min * 60 + sec) * \
228182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                                   75 + frame
229182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        func, arg = \
230182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                              self.callbacks[CD.PNUM]
231182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        if func:
232182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                            self.parser.setcallback(CD.PNUM, func, arg)
233182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                        else:
234182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                            self.parser.removecallback(CD.PNUM)
235182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.playing = 1
236182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                data = self.player.readda(size)
237182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                if data == '':
238182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.playing = 0
239182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.listindex = self.listindex + 1
240182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    continue
241182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                try:
242182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.parser.parseframe(data)
243182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                except _Stop:
244182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.playing = 0
245182b5aca27d376b08a2904bed42b751496f932f3Tim Peters                    self.listindex = self.listindex + 1
246182b5aca27d376b08a2904bed42b751496f932f3Tim Peters        finally:
247182b5aca27d376b08a2904bed42b751496f932f3Tim Peters            self.playing = 0
248