[SCM] morituri/master: * morituri/program/cdrdao.py: read all sessions by reading session 9. * morituri/image/toc.py: Parse ZERO statements properly. Also set absolute offsets when we know them from the .toc file. Properly set audio flag on tracks. FIXME: probably doesn't work if the .toc does not have lengths. * morituri/image/table.py: Add some debug to cddb disc id calculation. Fix absolutize function, it was going one index too far. raise ValueError when overriding .absolute with a wrong value. * examples/readdisc.py: Show CDDB disc id at the start. Assert when toc and table have different disc id's (to be fixed) * morituri/test/test_image_cue.py: Update for having the table already with absolute values. * morituri/test/test_image_toc.py: Add Ladyhawke CDDB test, it has a data track.
js at users.alioth.debian.org
js at users.alioth.debian.org
Sun Oct 19 20:09:00 UTC 2014
The following commit has been merged in the master branch:
commit 483c7b8a0ca41daf57ec718c6d56052144faa3af
Author: Thomas Vander Stichele <thomas (at) apestaart (dot) org>
Date: Sat May 16 19:09:27 2009 +0000
* morituri/program/cdrdao.py:
read all sessions by reading session 9.
* morituri/image/toc.py:
Parse ZERO statements properly.
Also set absolute offsets when we know them from the .toc file.
Properly set audio flag on tracks.
FIXME: probably doesn't work if the .toc does not have lengths.
* morituri/image/table.py:
Add some debug to cddb disc id calculation.
Fix absolutize function, it was going one index too far.
raise ValueError when overriding .absolute with a wrong value.
* examples/readdisc.py:
Show CDDB disc id at the start.
Assert when toc and table have different disc id's (to be fixed)
* morituri/test/test_image_cue.py:
Update for having the table already with absolute values.
* morituri/test/test_image_toc.py:
Add Ladyhawke CDDB test, it has a data track.
diff --git a/ChangeLog b/ChangeLog
index 90e2367..5513a10 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
2009-05-16 Thomas Vander Stichele <thomas at apestaart dot org>
+ * morituri/program/cdrdao.py:
+ read all sessions by reading session 9.
+ * morituri/image/toc.py:
+ Parse ZERO statements properly.
+ Also set absolute offsets when we know them from the .toc file.
+ Properly set audio flag on tracks.
+ FIXME: probably doesn't work if the .toc does not have lengths.
+ * morituri/image/table.py:
+ Add some debug to cddb disc id calculation.
+ Fix absolutize function, it was going one index too far.
+ raise ValueError when overriding .absolute with a wrong value.
+ * examples/readdisc.py:
+ Show CDDB disc id at the start.
+ Assert when toc and table have different disc id's (to be fixed)
+ * morituri/test/test_image_cue.py:
+ Update for having the table already with absolute values.
+ * morituri/test/test_image_toc.py:
+ Add Ladyhawke CDDB test, it has a data track.
+
+2009-05-16 Thomas Vander Stichele <thomas at apestaart dot org>
+
* examples/readdisc.py:
Move constants to common
diff --git a/examples/readdisc.py b/examples/readdisc.py
index e688cbb..5e92e7f 100644
--- a/examples/readdisc.py
+++ b/examples/readdisc.py
@@ -229,6 +229,7 @@ def main(argv):
assert ittoc.hasTOC()
# already show us some info based on this
+ print "CDDB disc id", ittoc.getCDDBDiscId()
metadata = musicbrainz(ittoc.getMusicBrainzDiscId())
# now, read the complete index table, which is slower
@@ -241,6 +242,11 @@ def main(argv):
assert itable.hasTOC()
+ assert itable.getCDDBDiscId() == ittoc.getCDDBDiscId(), \
+ "full table's id %s differs from toc id %s" % (
+ itable.getCDDBDiscId(), ittoc.getCDDBDiscId())
+ assert itable.getMusicBrainzDiscId() == ittoc.getMusicBrainzDiscId()
+
lastTrackStart = 0
# check for hidden track one audio
diff --git a/morituri/image/table.py b/morituri/image/table.py
index b1ced8d..aa90d39 100644
--- a/morituri/image/table.py
+++ b/morituri/image/table.py
@@ -208,19 +208,28 @@ class Table(object, log.Loggable):
#if self.getTrackStart(1) > 0:
# delta = 0
+ debug = [str(len(self.tracks))]
for track in self.tracks:
offset = self.getTrackStart(track.number) + delta
+ debug.append(str(offset))
seconds = offset / common.FRAMES_PER_SECOND
n += self._cddbSum(seconds)
last = self.tracks[-1]
# the 'real' leadout, not offset by 150 frames
+ # print 'THOMAS: disc leadout', self.leadout
leadout = self.getTrackEnd(last.number) + 1
+ self.debug('leadout LBA: %d', leadout)
startSeconds = self.getTrackStart(1) / common.FRAMES_PER_SECOND
leadoutSeconds = leadout / common.FRAMES_PER_SECOND
t = leadoutSeconds - startSeconds
+ debug.append(str(leadoutSeconds + 2)) # 2 is the 150 frame cddb offset
value = (n % 0xff) << 24 | t << 8 | len(self.tracks)
+
+ # compare this debug line to cd-discid output
+ self.debug('cddb disc id debug: %s',
+ " ".join(["%08x" % value, ] + debug))
return "%08x" % value
@@ -457,20 +466,27 @@ class Table(object, log.Loggable):
# the first cut is the deepest
counter = index.counter
+ #for t in self.tracks: print t, t.indexes
self.debug('absolutizing')
while True:
+ track = self.tracks[t - 1]
+ index = track.getIndex(i)
+ assert track.number == t
+ assert index.number == i
if index.counter is None:
self.debug('Track %d, index %d has no counter', t, i)
break
if index.counter != counter:
self.debug('Track %d, index %d has a different counter', t, i)
break
- track = self.tracks[t - 1]
- index = track.getIndex(i)
- assert track.number == t
- assert index.number == i
self.debug('Setting absolute offset %d on track %d, index %d',
index.relative, t, i)
+ if index.absolute is not None:
+ if index.absolute != index.relative:
+ msg = 'Track %d, index %d had absolute %d,' \
+ ' overriding with %d' % (
+ t, i, index.absolute, index.relative)
+ raise ValueError(msg)
index.absolute = index.relative
try:
t, i = self.getNextTrackIndex(t, i)
diff --git a/morituri/image/toc.py b/morituri/image/toc.py
index c537668..e2c1536 100644
--- a/morituri/image/toc.py
+++ b/morituri/image/toc.py
@@ -39,7 +39,7 @@ _CATALOG_RE = re.compile(r'^CATALOG "(?P<catalog>\d+)"$')
# records
_TRACK_RE = re.compile(r"""
^TRACK # TRACK
- \s(?P<mode>.+)$ # mode (AUDIO, MODEx/2xxx, ...)
+ \s(?P<mode>.+)$ # mode (AUDIO, MODE2_FORM_MIX, MODEx/2xxx, ...)
""", re.VERBOSE)
_ISRC_RE = re.compile(r'^ISRC "(?P<isrc>\w+)"$')
@@ -50,6 +50,13 @@ _SILENCE_RE = re.compile(r"""
\s(?P<length>.*)$ # pre-gap length
""", re.VERBOSE)
+# ZERO is used as pre-gap source when switching mode
+_ZERO_RE = re.compile(r"""
+ ^ZERO # ZERO
+ \s(?P<mode>.+) # mode (AUDIO, MODEx/2xxx, ...)
+ \s(?P<length>.*)$ # zero length
+""", re.VERBOSE)
+
_FILE_RE = re.compile(r"""
^FILE # FILE
@@ -58,6 +65,14 @@ _FILE_RE = re.compile(r"""
\s(?P<length>.+)$ # stop offset
""", re.VERBOSE)
+_DATAFILE_RE = re.compile(r"""
+ ^DATAFILE # DATA FILE
+ \s+"(?P<name>.*)" # 'file name' in quotes
+ \s+(?P<length>\S+) # start offset
+ \s*.* # possible // comment
+""", re.VERBOSE)
+
+
# FIXME: start can be 0
_START_RE = re.compile(r"""
^START # START
@@ -83,7 +98,8 @@ class TocFile(object, log.Loggable):
counter = 0
trackNumber = 0
indexNumber = 0
- currentOffset = 0 # running absolute offset of where each track starts
+ absoluteOffset = 0 # running absolute offset of where each track starts
+ relativeOffset = 0 # running relative offset, relative to counter source
currentLength = 0 # accrued during TRACK record parsing, current track
totalLength = 0 # accrued during TRACK record parsing, total disc
pregapLength = 0 # length of the pre-gap, current track
@@ -128,13 +144,16 @@ class TocFile(object, log.Loggable):
# set index 1 of previous track if there was one, using
# pregapLength if applicable
if currentTrack:
+ # FIXME: why not set absolute offsets too ?
currentTrack.index(1, path=currentFile.path,
- relative=currentOffset + pregapLength, counter=counter)
+ absolute=absoluteOffset + pregapLength,
+ relative=relativeOffset + pregapLength, counter=counter)
self.debug('track %d, added index %r',
currentTrack.number, currentTrack.getIndex(1))
trackNumber += 1
- currentOffset += currentLength
+ absoluteOffset += currentLength
+ relativeOffset += currentLength
totalLength += currentLength
currentLength = 0
indexNumber = 1
@@ -142,7 +161,9 @@ class TocFile(object, log.Loggable):
pregapLength = 0
# FIXME: track mode
- currentTrack = table.Track(trackNumber)
+ self.debug('found track %d, mode %s', trackNumber, trackMode)
+ audio = trackMode == 'AUDIO'
+ currentTrack = table.Track(trackNumber, audio=audio)
self.table.tracks.append(currentTrack)
continue
@@ -163,6 +184,16 @@ class TocFile(object, log.Loggable):
length = m.group('length')
currentLength += common.msfToFrames(length)
+ # look for ZERO lines
+ m = _ZERO_RE.search(line)
+ if m:
+ if currentFile is not None:
+ self.debug('ZERO after FILE, increasing counter')
+ counter += 1
+ currentFile = None
+ length = m.group('length')
+ currentLength += common.msfToFrames(length)
+
# look for FILE lines
m = _FILE_RE.search(line)
if m:
@@ -174,12 +205,32 @@ class TocFile(object, log.Loggable):
common.msfToFrames(length))
if not currentFile or filePath != currentFile.path:
counter += 1
+ relativeOffset = 0
self.debug('track %d, switched to new FILE, increased counter to %d',
trackNumber, counter)
currentFile = File(filePath, start, length)
- #currentOffset += common.msfToFrames(start)
+ #absoluteOffset += common.msfToFrames(start)
currentLength += common.msfToFrames(length)
+ # look for DATAFILE lines
+ m = _DATAFILE_RE.search(line)
+ if m:
+ filePath = m.group('name')
+ length = m.group('length')
+ # print 'THOMAS', length
+ self.debug('FILE %s, length %r',
+ filePath, common.msfToFrames(length))
+ if not currentFile or filePath != currentFile.path:
+ counter += 1
+ relativeOffset = 0
+ self.debug('track %d, switched to new FILE, increased counter to %d',
+ trackNumber, counter)
+ # FIXME: assume that a MODE2_FORM_MIX track always starts at 0
+ currentFile = File(filePath, 0, length)
+ #absoluteOffset += common.msfToFrames(start)
+ currentLength += common.msfToFrames(length)
+
+
# look for START lines
m = _START_RE.search(line)
if m:
@@ -190,7 +241,8 @@ class TocFile(object, log.Loggable):
length = common.msfToFrames(m.group('length'))
currentTrack.index(0, path=currentFile.path,
- relative=currentOffset, counter=counter)
+ absolute=absoluteOffset,
+ relative=relativeOffset, counter=counter)
self.debug('track %d, added index %r',
currentTrack.number, currentTrack.getIndex(0))
# store the pregapLength to add it when we index 1 for this
@@ -215,7 +267,8 @@ class TocFile(object, log.Loggable):
# handle index 1 of final track, if any
if currentTrack:
currentTrack.index(1, path=currentFile.path,
- relative=currentOffset + pregapLength, counter=counter)
+ absolute=absoluteOffset + pregapLength,
+ relative=relativeOffset + pregapLength, counter=counter)
self.debug('track %d, added index %r',
currentTrack.number, currentTrack.getIndex(1))
diff --git a/morituri/program/cdrdao.py b/morituri/program/cdrdao.py
index b7221e0..2ca7520 100644
--- a/morituri/program/cdrdao.py
+++ b/morituri/program/cdrdao.py
@@ -202,7 +202,8 @@ class CDRDAOTask(task.Task):
bufsize=bufsize,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)
- self.debug('Started cdrdao with pid %d', self._popen.pid)
+ self.debug('Started cdrdao with pid %d and options %r',
+ self._popen.pid, self.options)
self.runner.schedule(1.0, self._read, runner)
@@ -269,7 +270,8 @@ class ReadTableTask(CDRDAOTask):
os.close(fd)
os.unlink(self._tocfilepath)
- self.options = ['read-toc', self._tocfilepath]
+ self.options = ['read-toc', '--session', '9',
+ self._tocfilepath, ]
def readbytes(self, bytes):
self.parser.read(bytes)
@@ -318,7 +320,10 @@ class ReadTOCTask(CDRDAOTask):
os.close(fd)
os.unlink(self._toc)
- self.options = ['read-toc', '--fast-toc', self._toc]
+ # Reading a non-existent session gives you output for all sessions
+ # 9 should be a safe number
+ self.options = ['read-toc', '--fast-toc', '--session', '9',
+ self._toc, ]
def readbytes(self, bytes):
self.parser.read(bytes)
diff --git a/morituri/test/test_image_cue.py b/morituri/test/test_image_cue.py
index 1e3d4a8..3fb3096 100644
--- a/morituri/test/test_image_cue.py
+++ b/morituri/test/test_image_cue.py
@@ -55,20 +55,19 @@ class WriteCueFileTestCase(unittest.TestCase):
os.close(fd)
it = table.Table()
-
t = table.Track(1)
- t.index(1, path='track01.wav', relative=0, counter=1)
+ t.index(1, absolute=0, path='track01.wav', relative=0, counter=1)
it.tracks.append(t)
t = table.Track(2)
- t.index(0, path='track01.wav', relative=1000, counter=1)
- t.index(1, path='track02.wav', relative=0, counter=2)
+ t.index(0, absolute=1000, path='track01.wav', relative=1000, counter=1)
+ t.index(1, absolute=2000, path='track02.wav', relative=0, counter=2)
it.tracks.append(t)
it.absolutize()
- it.leadout = 2000
+ it.leadout = 3000
- self.assertEquals(it.cue(), """REM DISCID 04001A02
+ self.assertEquals(it.cue(), """REM DISCID 0C002802
REM COMMENT "Morituri"
FILE "track01.wav" WAVE
TRACK 01 AUDIO
diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py
index 1bac4b0..6c3dc4f 100644
--- a/morituri/test/test_image_toc.py
+++ b/morituri/test/test_image_toc.py
@@ -49,9 +49,9 @@ class CureTestCase(unittest.TestCase):
self.assertEquals(index.relative, value)
def testSetFile(self):
- self._assertAbsolute(1, 1, None)
- self._assertAbsolute(2, 0, None)
- self._assertAbsolute(2, 1, None)
+ self._assertAbsolute(1, 1, 0)
+ self._assertAbsolute(2, 0, 28245)
+ self._assertAbsolute(2, 1, 28324)
self._assertPath(1, 1, "data.wav")
def dump():
@@ -118,8 +118,7 @@ class BlocTestCase(unittest.TestCase):
# This disc has a pre-gap, so is a good test for .CUE writing
def testConvertCue(self):
- self.failIf(self.toc.table.hasTOC())
- self.toc.table.absolutize()
+ #self.toc.table.absolutize()
self.failUnless(self.toc.table.hasTOC())
cue = self.toc.table.cue()
ref = open(os.path.join(os.path.dirname(__file__),
@@ -128,6 +127,10 @@ class BlocTestCase(unittest.TestCase):
def testCDDBId(self):
self.toc.table.absolutize()
+ # cd-discid output:
+ # ad0be00d 13 15370 35019 51532 69190 84292 96826 112527 132448
+ # 148595 168072 185539 203331 222103 3244
+
self.assertEquals(self.toc.table.getCDDBDiscId(), 'ad0be00d')
def testAccurateRip(self):
@@ -156,10 +159,27 @@ class BreedersTestCase(unittest.TestCase):
self.assertEquals(cdt['TITLE'], 'OVERGLAZED')
def testConvertCue(self):
- self.failIf(self.toc.table.hasTOC())
self.toc.table.absolutize()
self.failUnless(self.toc.table.hasTOC())
cue = self.toc.table.cue()
ref = open(os.path.join(os.path.dirname(__file__),
'breeders.cue')).read()
self.assertEquals(cue, ref)
+
+# Ladyhawke has a data track
+class LadyhawkeTestCase(unittest.TestCase):
+ def setUp(self):
+ self.toc = toc.TocFile(os.path.join(os.path.dirname(__file__),
+ 'ladyhawke.toc'))
+ self.toc.parse()
+ self.assertEquals(len(self.toc.table.tracks), 13)
+ #import code; code.interact(local=locals())
+ self.failIf(self.toc.table.tracks[-1].audio)
+
+ def testCDDBId(self):
+ self.toc.table.absolutize()
+ self.assertEquals(self.toc.table.getCDDBDiscId(), 'c60af50d')
+ # output from cd-discid:
+ # c60af50d 13 150 15687 31841 51016 66616 81352 99559 116070 133243
+ # 149997 161710 177832 207256 2807
+
--
morituri packaging
More information about the pkg-multimedia-commits
mailing list