From ac880acdf1e4067972a4a94228222e3ed1af7523 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 12 Apr 2009 19:30:57 +0000 Subject: [PATCH] * examples/ARcue.py: * morituri/common/crc.py: * morituri/image/image.py: * morituri/test/test_image_image.py: Calculate CDDB disc id. Tested on my Kings Of Leon CD. --- ChangeLog | 9 ++++++ examples/ARcue.py | 26 +++++++++------- morituri/common/crc.py | 1 + morituri/image/image.py | 52 ++++++++++++++++++++++++++----- morituri/test/test_image_image.py | 6 ++++ 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index e71f198..2d1d921 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-04-12 Thomas Vander Stichele + + * examples/ARcue.py: + * morituri/common/crc.py: + * morituri/image/image.py: + * morituri/test/test_image_image.py: + Calculate CDDB disc id. + Tested on my Kings Of Leon CD. + 2009-04-12 Thomas Vander Stichele * examples/ARcue.py: diff --git a/examples/ARcue.py b/examples/ARcue.py index c4710c8..955a7dc 100644 --- a/examples/ARcue.py +++ b/examples/ARcue.py @@ -30,21 +30,18 @@ import gtk from morituri.image import image from morituri.common import task, crc -def gtkmain(taskk): - progress = task.GtkProgressRunner() - progress.connect('stop', lambda _: gtk.main_quit()) +def gtkmain(runner, taskk): + runner.connect('stop', lambda _: gtk.main_quit()) window = gtk.Window() window.add(progress) window.show_all() - progress.run(taskk) + runner.run(taskk) gtk.main() -def climain(taskk): - runner = task.SyncRunner() - +def climain(runner, taskk): runner.run(taskk) @@ -71,13 +68,20 @@ def main(argv): cuetask = image.AudioRipCRCTask(cueImage) if options.runner == 'cli': - climain(verifytask) - climain(cuetask) + runner = task.SyncRunner() + cueImage.setup(runner) + print "CDDB disc id", cueImage.cddbDiscId() + climain(runner, verifytask) + climain(runner, cuetask) elif options.runner == 'gtk': - gtkmain(verifytask) - gtkmain(cuetask) + runner = task.GtkProgressRunner() + cueImage.setup(runner) + print "CDDB disc id", cueImage.cddbDiscId() + gtkmain(runner, verifytask) + gtkmain(runner, cuetask) for i, crc in enumerate(cuetask.crcs): print "Track %2d: %08x" % (i + 1, crc) + main(sys.argv) diff --git a/morituri/common/crc.py b/morituri/common/crc.py index 4b6c85a..539b6f9 100644 --- a/morituri/common/crc.py +++ b/morituri/common/crc.py @@ -32,6 +32,7 @@ from morituri.common import task FRAMES_PER_DISC_FRAME = 588 SAMPLES_PER_DISC_FRAME = FRAMES_PER_DISC_FRAME * 4 +DISC_FRAMES_PER_SECOND = 75 class CRCTask(task.Task): # this object needs a main loop to stop diff --git a/morituri/image/image.py b/morituri/image/image.py index 1e86154..f2545c9 100644 --- a/morituri/image/image.py +++ b/morituri/image/image.py @@ -39,7 +39,8 @@ class Image: self._path = path self.cue = cue.Cue(path) self.cue.parse() - self._lengths = [] + self._offsets = [] # 0 .. trackCount - 1 + self._lengths = [] # 0 .. trackCount - 1 def getRealPath(self, path): """ @@ -68,15 +69,52 @@ class Image: """ verify = ImageVerifyTask(self) runner.run(verify) - self._lengths = verify.lengths + + # calculate offset and length for each track + + # CD's have a standard lead-in time of 2 seconds + offset = 2 * crc.DISC_FRAMES_PER_SECOND \ + + self.cue.tracks[0].getIndex(1)[0] + + for i in range(len(self.cue.tracks)): + self._offsets.append(offset) + length = self.cue.getTrackLength(self.cue.tracks[i]) + if length == -1: + length = verify.lengths[i + 1] + self._lengths.append(length) + + offset += length + + def getTrackOffset(self, track): + return self._offsets[self.cue.tracks.index(track)] def getTrackLength(self, track): - length = self.cue.getTrackLength(track) - if length != -1: - return length + return self._lengths[self.cue.tracks.index(track)] - i = self.cue.tracks.index(track) - return self._lengths[i + 1] + def _cddbSum(self, i): + ret = 0 + while i > 0: + ret += (i % 10) + i /= 10 + + return ret + + def cddbDiscId(self): + n = 0 + + for track in self.cue.tracks: + offset = self.getTrackOffset(track) + seconds = offset / crc.DISC_FRAMES_PER_SECOND + n += self._cddbSum(seconds) + + last = self.cue.tracks[-1] + leadout = self.getTrackOffset(last) + self.getTrackLength(last) + frameLength = leadout - self.getTrackOffset(self.cue.tracks[0]) + t = frameLength / crc.DISC_FRAMES_PER_SECOND + + value = (n % 0xff) << 24 | t << 8 | len(self.cue.tracks) + + return "%08x" % value class MultiTask(task.Task): """ diff --git a/morituri/test/test_image_image.py b/morituri/test/test_image_image.py index 5c70246..05a378e 100644 --- a/morituri/test/test_image_image.py +++ b/morituri/test/test_image_image.py @@ -37,6 +37,9 @@ class TrackSingleTestCase(unittest.TestCase): self.assertEquals(self.image.getTrackLength(tracks[2]), 2) self.assertEquals(self.image.getTrackLength(tracks[3]), 4) + def testCDDB(self): + self.assertEquals(self.image.cddbDiscId(), "08000004") + class TracSeparateTestCase(unittest.TestCase): def setUp(self): self.image = image.Image(os.path.join(os.path.dirname(__file__), @@ -61,6 +64,9 @@ class TracSeparateTestCase(unittest.TestCase): self.assertEquals(self.image.getTrackLength(tracks[2]), 10) self.assertEquals(self.image.getTrackLength(tracks[3]), 10) + def testCDDB(self): + self.assertEquals(self.image.cddbDiscId(), "08000004") + class AudioLengthTestCase(unittest.TestCase): def testLength(self): path = os.path.join(os.path.dirname(__file__), 'track.flac')