* 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.
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2009-04-12 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* 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 <thomas at apestaart dot org>
|
||||
|
||||
* 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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user