* morituri/image/toc.py:
* morituri/test/test_image_toc.py: * morituri/test/bloc.toc (added): Fix up .toc parsing to correct index 0 behaviour. Add Bloc Party's Silent Alarm .toc file to test HTOA.
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
2009-05-01 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/image/toc.py:
|
||||
* morituri/test/test_image_toc.py:
|
||||
* morituri/test/bloc.toc (added):
|
||||
Fix up .toc parsing to correct index 0 behaviour.
|
||||
Add Bloc Party's Silent Alarm .toc file to test HTOA.
|
||||
|
||||
2009-05-01 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* examples/readtoc.py:
|
||||
|
||||
@@ -36,6 +36,13 @@ _TRACK_RE = re.compile(r"""
|
||||
\s(?P<mode>.+)$ # mode (AUDIO, MODEx/2xxx, ...)
|
||||
""", re.VERBOSE)
|
||||
|
||||
# a HTOA is marked in the cdrdao's TOC as SILENCE
|
||||
_SILENCE_RE = re.compile(r"""
|
||||
^SILENCE # SILENCE
|
||||
\s(?P<length>.*)$ # pre-gap length
|
||||
""", re.VERBOSE)
|
||||
|
||||
|
||||
_FILE_RE = re.compile(r"""
|
||||
^FILE # FILE
|
||||
\s+"(?P<name>.*)" # 'file name' in quotes
|
||||
@@ -67,8 +74,14 @@ class TOC:
|
||||
currentTrack = None
|
||||
trackNumber = 0
|
||||
indexNumber = 0
|
||||
offset = 0 # running count of where each track starts
|
||||
currentOffset = 0 # running absolute offset of where each track starts
|
||||
currentLength = 0 # accrued during TRACK record parsing, current track
|
||||
pregapLength = 0 # length of the pre-gap, current track
|
||||
|
||||
|
||||
# the first track's INDEX 1 can only be gotten from the .toc
|
||||
# file once the first pregap is calculated; so we add INDEX 1
|
||||
# at the end of each parsed TRACK record
|
||||
handle = open(self._path, 'r')
|
||||
|
||||
for number, line in enumerate(handle.readlines()):
|
||||
@@ -82,13 +95,28 @@ class TOC:
|
||||
m = _TRACK_RE.search(line)
|
||||
if m:
|
||||
state = 'TRACK'
|
||||
|
||||
# handle index 1 of previous track, if any
|
||||
if currentTrack:
|
||||
currentTrack.index(1, currentOffset + pregapLength,
|
||||
currentFile)
|
||||
|
||||
trackNumber += 1
|
||||
currentOffset += currentLength
|
||||
currentLength = 0
|
||||
indexNumber = 1
|
||||
trackMode = m.group('mode')
|
||||
|
||||
currentTrack = Track(trackNumber)
|
||||
self.tracks.append(currentTrack)
|
||||
continue
|
||||
|
||||
# look for SILENCE lines
|
||||
m = _SILENCE_RE.search(line)
|
||||
if m:
|
||||
length = m.group('length')
|
||||
currentLength += self._parseMSF(length)
|
||||
|
||||
# look for FILE lines
|
||||
m = _FILE_RE.search(line)
|
||||
if m:
|
||||
@@ -96,9 +124,8 @@ class TOC:
|
||||
start = m.group('start')
|
||||
length = m.group('length')
|
||||
currentFile = File(filePath, start, length)
|
||||
offset = self._parseMSF(start)
|
||||
indexNumber = 1
|
||||
currentTrack.index(1, offset, currentFile)
|
||||
#currentOffset += self._parseMSF(start)
|
||||
currentLength += self._parseMSF(length)
|
||||
|
||||
# look for START lines
|
||||
m = _START_RE.search(line)
|
||||
@@ -109,7 +136,9 @@ class TOC:
|
||||
continue
|
||||
|
||||
length = self._parseMSF(m.group('length'))
|
||||
currentTrack.index(0, offset - length, currentFile)
|
||||
currentTrack.index(0, currentOffset, currentFile)
|
||||
currentLength += length
|
||||
pregapLength = length
|
||||
|
||||
# look for INDEX lines
|
||||
m = _INDEX_RE.search(line)
|
||||
@@ -120,6 +149,10 @@ class TOC:
|
||||
offset = self._parseMSF(m.group('offset'))
|
||||
currentTrack.index(indexNumber, offset, currentFile)
|
||||
|
||||
# handle index 1 of final track, if any
|
||||
if currentTrack:
|
||||
currentTrack.index(1, currentOffset + pregapLength, currentFile)
|
||||
|
||||
def message(self, number, message):
|
||||
"""
|
||||
Add a message about a given line in the cue file.
|
||||
|
||||
116
morituri/test/bloc.toc
Normal file
116
morituri/test/bloc.toc
Normal file
@@ -0,0 +1,116 @@
|
||||
CD_DA
|
||||
|
||||
|
||||
// Track 1
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
SILENCE 03:22:70
|
||||
FILE "data.wav" 0 04:21:74
|
||||
START 03:22:70
|
||||
|
||||
|
||||
// Track 2
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 04:21:74 03:40:13
|
||||
|
||||
|
||||
// Track 3
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 08:02:12 03:55:33
|
||||
|
||||
|
||||
// Track 4
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 11:57:45 03:20:30
|
||||
|
||||
|
||||
// Track 5
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 15:18:00 02:47:40
|
||||
START 00:00:72
|
||||
|
||||
|
||||
// Track 6
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 18:05:40 03:29:50
|
||||
START 00:00:41
|
||||
|
||||
|
||||
// Track 7
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 21:35:15 04:25:59
|
||||
START 00:00:17
|
||||
|
||||
|
||||
// Track 8
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 26:00:74 03:35:15
|
||||
START 00:00:04
|
||||
|
||||
|
||||
// Track 9
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 29:36:14 04:19:63
|
||||
START 00:00:11
|
||||
|
||||
|
||||
// Track 10
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 33:56:02 03:52:24
|
||||
|
||||
|
||||
// Track 11
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 37:48:26 03:56:19
|
||||
START 00:00:43
|
||||
|
||||
|
||||
// Track 12
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 41:44:45 04:11:41
|
||||
START 00:01:41
|
||||
|
||||
|
||||
// Track 13
|
||||
TRACK AUDIO
|
||||
NO COPY
|
||||
NO PRE_EMPHASIS
|
||||
TWO_CHANNEL_AUDIO
|
||||
FILE "data.wav" 45:56:11 04:43:60
|
||||
START 00:00:22
|
||||
|
||||
@@ -21,8 +21,33 @@ class CureTestCase(unittest.TestCase):
|
||||
self.assertEquals(self.toc.getTrackLength(t), -1)
|
||||
|
||||
def testIndexes(self):
|
||||
# track 2, index 0 is at 06:16:45
|
||||
# FIXME: cdrdao seems to get length of FILE 1 frame too many,
|
||||
# and START value one frame less
|
||||
t = self.toc.tracks[1]
|
||||
(offset, file) = t.getIndex(0)
|
||||
self.assertEquals(offset, 28166)
|
||||
(offset, file) = t.getIndex(1)
|
||||
self.assertEquals(offset, 28245)
|
||||
(offset, file) = t.getIndex(1)
|
||||
self.assertEquals(offset, 28324)
|
||||
|
||||
# Bloc Party - Silent Alarm has a Hidden Track One Audio
|
||||
class BlocTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.toc = toc.TOC(os.path.join(os.path.dirname(__file__),
|
||||
'bloc.toc'))
|
||||
self.toc.parse()
|
||||
self.assertEquals(len(self.toc.tracks), 13)
|
||||
|
||||
def testGetTrackLength(self):
|
||||
t = self.toc.tracks[0]
|
||||
self.assertEquals(self.toc.getTrackLength(t), -1)
|
||||
# last track has unknown length
|
||||
t = self.toc.tracks[-1]
|
||||
self.assertEquals(self.toc.getTrackLength(t), -1)
|
||||
|
||||
def testIndexes(self):
|
||||
t = self.toc.tracks[0]
|
||||
(offset, file) = t.getIndex(0)
|
||||
self.assertEquals(offset, 0)
|
||||
(offset, file) = t.getIndex(1)
|
||||
self.assertEquals(offset, 15220)
|
||||
|
||||
Reference in New Issue
Block a user