diff --git a/ChangeLog b/ChangeLog index 4fcff5a..c331b9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2011-08-14 Thomas Vander Stichele + + * TODO: + Add a note about das capital disc. + * morituri/test/release.08397059-86c1-463b-8ed0-cd596dbd174f.xml: + * morituri/test/release.93a6268c-ddf1-4898-bf93-fb862b1c5c5e.xml: + Add musicbrainz ws1 results for Das Capital and Ladyhawke. + * morituri/test/test_common_program.py: + Fix typos. + Add tests for Ladyhawke and Das Capital duration and parsing. + * morituri/test/test_image_table.py: + Fix according to new algorithm. + * morituri/test/test_image_toc.py: + Get frame length for both cd's. + * morituri/image/table.py: + Add getFrameLength method. Fix up duration. + 2011-08-14 Thomas Vander Stichele * morituri/common/program.py: diff --git a/TODO b/TODO index f0c7fed..2d3ff86 100644 --- a/TODO +++ b/TODO @@ -35,3 +35,11 @@ TODO: - use a temp dir, until the whole rip is good don't move it, so we easily find half done rips - primal scream, track 5, it rips/checks/rips/checks/encodes/checks and then complains read and verify failed. why did it encode ? +- Musicbrainz disc id error: + Compare http://www.musicbrainz.org/cdtoc/MAj3xXf6QMy7G.BIFOyHyq4MySE- + with http://www.musicbrainz.org/cdtoc/USC1utCZbTLZy80aHvQzJw4FASk- + Almost same, but second is 2 seconds longer on last track, suggesting it + was calculated wrong (150 frame offset done wrong ?) Can't find it in + edit history though + Write an example document with this cd as an example explaining offsets + and id calculations diff --git a/morituri/image/table.py b/morituri/image/table.py index 725fa7f..1038691 100644 --- a/morituri/image/table.py +++ b/morituri/image/table.py @@ -297,7 +297,7 @@ class Table(object, log.Loggable): - CDDB disc id - number of audio tracks - offset of index 1 of each track - - length of disc in seconds + - length of disc in seconds (including data track) @rtype: list of int """ @@ -323,14 +323,22 @@ class Table(object, log.Loggable): 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 + last = self.tracks[-1] leadout = self.getTrackEnd(last.number) + 1 self.debug('leadout LBA: %d', leadout) + + # FIXME: we can't replace these calculations with the getFrameLength + # call because the start and leadout in the algorithm get rounded + # before making the difference startSeconds = self.getTrackStart(1) / common.FRAMES_PER_SECOND leadoutSeconds = leadout / common.FRAMES_PER_SECOND t = leadoutSeconds - startSeconds + # durationFrames = self.getFrameLength(data=True) + # duration = durationFrames / common.FRAMES_PER_SECOND + # assert t == duration, "%r != %r" % (t, duration) + debug.append(str(leadoutSeconds + 2)) # 2 is the 150 frame cddb offset result.append(leadoutSeconds) @@ -427,14 +435,29 @@ class Table(object, log.Loggable): return urlparse.urlunparse(( 'http', host, '/bare/cdlookup.html', '', query, '')) + def getFrameLength(self, data=False): + """ + Get the length in frames (excluding HTOA) + + @param data: whether to include the data tracks in the length + """ + # the 'real' leadout, not offset by 150 frames + if data: + last = self.tracks[-1] + else: + last = self.tracks[self.getAudioTracks() - 1] + + leadout = self.getTrackEnd(last.number) + 1 + self.debug('leadout LBA: %d', leadout) + durationFrames = leadout - self.getTrackStart(1) + + return durationFrames + def duration(self): """ - Get an estimate of the duration in ms. + Get the duration in ms for all audio tracks (excluding HTOA). """ - values = self._getMusicBrainzValues() - leadout = values[2] - first = values[3] - return ((leadout - first) * 1000) / common.FRAMES_PER_SECOND + return int(self.getFrameLength() * 1000.0 / common.FRAMES_PER_SECOND) def _getMusicBrainzValues(self): """ diff --git a/morituri/test/release.08397059-86c1-463b-8ed0-cd596dbd174f.xml b/morituri/test/release.08397059-86c1-463b-8ed0-cd596dbd174f.xml new file mode 100644 index 0000000..156b33c --- /dev/null +++ b/morituri/test/release.08397059-86c1-463b-8ed0-cd596dbd174f.xml @@ -0,0 +1,49 @@ + + + + + Das Capital: The Songwriting Genius of Luke Haines and The Auteurs + B00009XG2O + + Luke HainesHaines, Luke + + + + How Could I Be Wrong273800 + + + Showgirl256466 + + + Baader Meinhof183933 + + + Lenny Valentino136133 + + + Starstruck212333 + + + Satan Wants Me189666 + + + Unsolved Child Murder146800 + + + Junk Shop Clothes166800 + + + The Mitford Sisters302960 + + + Bugger Bognor230573 + + + Future Generation216266 + + + + + + + diff --git a/morituri/test/release.93a6268c-ddf1-4898-bf93-fb862b1c5c5e.xml b/morituri/test/release.93a6268c-ddf1-4898-bf93-fb862b1c5c5e.xml new file mode 100644 index 0000000..dde1c28 --- /dev/null +++ b/morituri/test/release.93a6268c-ddf1-4898-bf93-fb862b1c5c5e.xml @@ -0,0 +1,50 @@ + + + + Ladyhawke + + LadyhawkeLadyhawke + + + + Magic207000 + + + Manipulating Woman215000 + + + My Delirium255000 + + + Better Than Sunday208000 + + + Another Runaway196000 + + + Love Don't Live Here242000 + + + Back of the Van220000 + + + Paris Is Burning229000 + + + Professional Suicide223000 + + + Dusk Till Dawn156000 + + + Crazy World215000 + + + Morning Dreams240000 + + + + + + + diff --git a/morituri/test/test_common_program.py b/morituri/test/test_common_program.py index 3a5d0b3..94367f2 100644 --- a/morituri/test/test_common_program.py +++ b/morituri/test/test_common_program.py @@ -121,6 +121,35 @@ class MetadataLengthTestCase(unittest.TestCase): reader = wsxml.MbXmlParser() wsMetadata = reader.parse(handle) release = wsMetadata.getRelease() - metadata = progam.getMetadata(release) + metadata = program.getMetadata(release) self.assertEquals(metadata.duration, 2962889) + + def testLadyhawke(self): + from musicbrainz2 import wsxml + + path = os.path.join(os.path.dirname(__file__), + 'release.93a6268c-ddf1-4898-bf93-fb862b1c5c5e.xml') + handle = open(path, "rb") + + reader = wsxml.MbXmlParser() + wsMetadata = reader.parse(handle) + release = wsMetadata.getRelease() + metadata = program.getMetadata(release) + + # self.assertEquals(metadata.duration, 2609413) + + def testDasCapital(self): + from musicbrainz2 import wsxml + + path = os.path.join(os.path.dirname(__file__), + 'release.08397059-86c1-463b-8ed0-cd596dbd174f.xml') + handle = open(path, "rb") + + reader = wsxml.MbXmlParser() + wsMetadata = reader.parse(handle) + release = wsMetadata.getRelease() + metadata = program.getMetadata(release) + + # FIXME: 2 seconds longer than the duration according to table + self.assertEquals(metadata.duration, 2315730) diff --git a/morituri/test/test_image_table.py b/morituri/test/test_image_table.py index 43e59b2..c7c2111 100644 --- a/morituri/test/test_image_table.py +++ b/morituri/test/test_image_table.py @@ -53,7 +53,7 @@ class LadyhawkeTestCase(tcommon.TestCase): "http://www.accuraterip.com/accuraterip/a/5/d/dBAR-012-0013bd5a-00b8d489-c60af50d.bin") def testDuration(self): - self.assertEquals(self.table.duration(), 2609413) + self.assertEquals(self.table.duration(), 2761413) class MusicBrainzTestCase(tcommon.TestCase): # example taken from http://musicbrainz.org/doc/DiscIDCalculation diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 70090bf..be85cad 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -180,6 +180,15 @@ class LadyhawkeTestCase(common.TestCase): # c60af50d 13 150 15687 31841 51016 66616 81352 99559 116070 133243 # 149997 161710 177832 207256 2807 + def testMusicBrainz(self): + # URL to submit: http://mm.musicbrainz.org/bare/cdlookup.html?toc=1+11+197850+24320+44855+64090+77885+88095+104020+118245+129255+141765+164487+181780&tracks=11&id=MAj3xXf6QMy7G.BIFOyHyq4MySE- + self.assertEquals(self.toc.table.getMusicBrainzDiscId(), + "KnpGsLhvH.lPrNc1PBL21lb9Bg4-") + + # FIXME: I don't trust this toc, but I can't find the CD anymore + def testDuration(self): + self.assertEquals(self.toc.table.duration(), 2761413) + class CapitalMergeTestCase(common.TestCase): def setUp(self): self.toc1 = toc.TocFile(os.path.join(os.path.dirname(__file__), @@ -209,6 +218,13 @@ class CapitalMergeTestCase(common.TestCase): self.assertEquals(self.table.getMusicBrainzDiscId(), "MAj3xXf6QMy7G.BIFOyHyq4MySE-") + def testDuration(self): + # this matches track 11 end sector - track 1 start sector on musicbrainz + # compare to 3rd and 4th value in URL above + self.assertEquals(self.table.getFrameLength(), 173530) + self.assertEquals(self.table.duration(), 2313733) + + class UnicodeTestCase(common.TestCase, common.UnicodeTestMixin): def setUp(self): # we copy the normal non-utf8 filename to a utf-8 filename