From f30b8b598f7b626ca11677cf8cb74afb47657e20 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 3 Mar 2013 19:39:35 +0100 Subject: [PATCH 01/29] add more asserts on the current code for strokes this shows that some of the logic may be wrong; track 1 index 1 should have relative 0 as it draws from the file, not silence --- morituri/test/test_image_toc.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 24e9345..2ffebec 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -335,8 +335,23 @@ class StrokesTestCase(common.TestCase): def testIndexes(self): t = self.toc.table.tracks[0] - self.assertEquals(t.getIndex(0).relative, 0) - self.assertEquals(t.getIndex(1).relative, 1) + i0 = t.getIndex(0) + self.assertEquals(i0.relative, 0) + self.assertEquals(i0.absolute, 0) + # FIXME: this is what we should have + # self.assertEquals(i0.counter, 0) + # self.assertEquals(i0.path, None) + # FIXME: this is what it is right now + self.assertEquals(i0.counter, 1) + self.assertEquals(i0.path, u'data.wav') + + i1 = t.getIndex(1) + # FIXME: relative should be 0, as it should point to the start + # of data.wav + self.assertEquals(i1.relative, 1) + self.assertEquals(i1.absolute, 1) + self.assertEquals(i1.counter, 1) + self.assertEquals(i1.path, u'data.wav') # Surfer Rosa has From a8fe47f1bd1eb6604c744a9fd5b29e6d6dac9347 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 3 Mar 2013 23:11:11 +0100 Subject: [PATCH 02/29] compare output .cue with EAC one we add The EAC one clearly marks the HTOA of one frame as pre-gap, while we don't yet do that. --- morituri/test/strokes-someday.eac.cue | 13 +++++++++++ morituri/test/test_image_toc.py | 31 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 morituri/test/strokes-someday.eac.cue diff --git a/morituri/test/strokes-someday.eac.cue b/morituri/test/strokes-someday.eac.cue new file mode 100644 index 0000000..0180794 --- /dev/null +++ b/morituri/test/strokes-someday.eac.cue @@ -0,0 +1,13 @@ +REM GENRE "Alternative Rock" +REM DATE 2001 +REM DISCID 0200BA01 +REM COMMENT "ExactAudioCopy v0.99pb4" +PERFORMER "The Strokes" +TITLE "Someday" +FILE "The Strokes - Someday\01 - The Strokes - Someday.wav" WAVE + TRACK 01 AUDIO + TITLE "Someday" + PERFORMER "The Strokes" + FLAGS DCP + PREGAP 00:00:01 + INDEX 01 00:00:00 diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 2ffebec..e41bc73 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -353,6 +353,37 @@ class StrokesTestCase(common.TestCase): self.assertEquals(i1.counter, 1) self.assertEquals(i1.path, u'data.wav') + cue = self._filterCue(self.toc.table.cue()) + ref = self._filterCue(open(os.path.join(os.path.dirname(__file__), + 'strokes-someday.eac.cue')).read()) + # FIXME: this diff should match + # common.diffStrings(cue, ref) + self.assertRaises(AssertionError, common.diffStrings, cue, ref) + + def _filterCue(self, output): + # helper to be able to compare our generated .cue with the + # EAC-extracted one + discard = [ 'TITLE', 'PERFORMER', 'FLAGS', 'REM' ] + lines = output.split('\n') + + res = [] + + for line in lines: + found = False + for needle in discard: + if line.find(needle) > -1: + found = True + + if line.find('FILE') > -1: + line = 'FILE "data.wav" WAVE' + + if not found: + res.append(line) + + return '\n'.join(res) + + + # Surfer Rosa has # track 00 consisting of 32 frames of SILENCE From 879dd7f946f78143195d7a24fe90d4a3d704cc11 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 3 Mar 2013 23:14:39 +0100 Subject: [PATCH 03/29] reset relative offset on SILENCE/ZERO --- morituri/image/toc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index b43ee41..7e19775 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -209,6 +209,7 @@ class TocFile(object, log.Loggable): if currentFile is not None: self.debug('SILENCE after FILE, increasing counter') counter += 1 + relativeOffset = 0 currentFile = None currentLength += common.msfToFrames(length) @@ -218,6 +219,7 @@ class TocFile(object, log.Loggable): if currentFile is not None: self.debug('ZERO after FILE, increasing counter') counter += 1 + relativeOffset = 0 currentFile = None length = m.group('length') currentLength += common.msfToFrames(length) From 1271ccea18c63088e79f32cd1f52b30105a675e5 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 3 Mar 2013 23:15:44 +0100 Subject: [PATCH 04/29] Set start and length properly on File --- morituri/image/toc.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 7e19775..4190324 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -239,7 +239,8 @@ class TocFile(object, log.Loggable): self.debug('track %d, switched to new FILE, ' 'increased counter to %d', trackNumber, counter) - currentFile = File(filePath, start, length) + currentFile = File(filePath, common.msfToFrames(start), + common.msfToFrames(length)) #absoluteOffset += common.msfToFrames(start) currentLength += common.msfToFrames(length) @@ -258,7 +259,7 @@ class TocFile(object, log.Loggable): 'increased counter to %d', trackNumber, counter) # FIXME: assume that a MODE2_FORM_MIX track always starts at 0 - currentFile = File(filePath, 0, length) + currentFile = File(filePath, 0, common.msfToFrames(length)) #absoluteOffset += common.msfToFrames(start) currentLength += common.msfToFrames(length) @@ -353,13 +354,16 @@ class File: def __init__(self, path, start, length): """ - @type path: unicode + @type path: C{unicode} + @type start: C{int} + @param start: starting point for the track in this file, in frames + @param length: length for the track in this file, in frames """ assert type(path) is unicode, "%r is not unicode" % path self.path = path - #self.start = start - #self.length = length + self.start = start + self.length = length def __repr__(self): return '' % (self.path, ) From 16bdaac89edd52401a77c61468ffb84628a90ca0 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Mon, 19 Aug 2013 00:21:27 +0200 Subject: [PATCH 05/29] add all EAC cue files for surfer rosa --- morituri/test/surferrosa.eac.corrected.cue | 136 ++++++++++++++++++ morituri/test/surferrosa.eac.currentgap.cue | 136 ++++++++++++++++++ morituri/test/surferrosa.eac.leftout.cue | 136 ++++++++++++++++++ morituri/test/surferrosa.eac.noncompliant.cue | 136 ++++++++++++++++++ morituri/test/surferrosa.eac.single.cue | 116 +++++++++++++++ 5 files changed, 660 insertions(+) create mode 100644 morituri/test/surferrosa.eac.corrected.cue create mode 100644 morituri/test/surferrosa.eac.currentgap.cue create mode 100644 morituri/test/surferrosa.eac.leftout.cue create mode 100644 morituri/test/surferrosa.eac.noncompliant.cue create mode 100644 morituri/test/surferrosa.eac.single.cue diff --git a/morituri/test/surferrosa.eac.corrected.cue b/morituri/test/surferrosa.eac.corrected.cue new file mode 100644 index 0000000..bf764b3 --- /dev/null +++ b/morituri/test/surferrosa.eac.corrected.cue @@ -0,0 +1,136 @@ +REM GENRE Alternative +REM DATE 1987 +REM DISCID 350CAA15 +REM COMMENT "ExactAudioCopy v0.99pb4" +CATALOG 0000000000000 +PERFORMER "Pixies" +TITLE "Surfer Rosa & Come on Pilgrim" +FILE "Pixies - Surfer Rosa & Come on Pilgrim\01 - Pixies - Bone Machine.wav" WAVE + TRACK 01 AUDIO + TITLE "Bone Machine" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 00 00:00:00 + INDEX 01 00:00:32 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\02 - Pixies - Break My Body.wav" WAVE + TRACK 02 AUDIO + TITLE "Break My Body" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\03 - Pixies - Something Against You.wav" WAVE + TRACK 03 AUDIO + TITLE "Something Against You" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 00 00:00:00 + INDEX 01 00:00:45 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\04 - Pixies - Broken Face.wav" WAVE + TRACK 04 AUDIO + TITLE "Broken Face" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\05 - Pixies - Gigantic.wav" WAVE + TRACK 05 AUDIO + TITLE "Gigantic" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\06 - Pixies - River Euphrates.wav" WAVE + TRACK 06 AUDIO + TITLE "River Euphrates" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\07 - Pixies - Where Is My Mind .wav" WAVE + TRACK 07 AUDIO + TITLE "Where Is My Mind?" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\08 - Pixies - Cactus.wav" WAVE + TRACK 08 AUDIO + TITLE "Cactus" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\09 - Pixies - Tony's Theme.wav" WAVE + TRACK 09 AUDIO + TITLE "Tony's Theme" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\10 - Pixies - Oh My Golly!.wav" WAVE + TRACK 10 AUDIO + TITLE "Oh My Golly!" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\11 - Pixies - Vamos.wav" WAVE + TRACK 11 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 + INDEX 02 00:44:70 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\12 - Pixies - I'm Amazed.wav" WAVE + TRACK 12 AUDIO + TITLE "I'm Amazed" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\13 - Pixies - Brick is Red.wav" WAVE + TRACK 13 AUDIO + TITLE "Brick is Red" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\14 - Pixies - Caribou.wav" WAVE + TRACK 14 AUDIO + TITLE "Caribou" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\15 - Pixies - Vamos.wav" WAVE + TRACK 15 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\16 - Pixies - Isla de Encanta.wav" WAVE + TRACK 16 AUDIO + TITLE "Isla de Encanta" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\17 - Pixies - Ed is Dead.wav" WAVE + TRACK 17 AUDIO + TITLE "Ed is Dead" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\18 - Pixies - The Holyday Song.wav" WAVE + TRACK 18 AUDIO + TITLE "The Holyday Song" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\19 - Pixies - Nimrod's Son.wav" WAVE + TRACK 19 AUDIO + TITLE "Nimrod's Son" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\20 - Pixies - I've Been Tired.wav" WAVE + TRACK 20 AUDIO + TITLE "I've Been Tired" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\21 - Pixies - Levitate Me.wav" WAVE + TRACK 21 AUDIO + TITLE "Levitate Me" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 diff --git a/morituri/test/surferrosa.eac.currentgap.cue b/morituri/test/surferrosa.eac.currentgap.cue new file mode 100644 index 0000000..9e7f189 --- /dev/null +++ b/morituri/test/surferrosa.eac.currentgap.cue @@ -0,0 +1,136 @@ +REM GENRE Alternative +REM DATE 1987 +REM DISCID 350CAA15 +REM COMMENT "ExactAudioCopy v0.99pb4" +CATALOG 0000000000000 +PERFORMER "Pixies" +TITLE "Surfer Rosa & Come on Pilgrim" +FILE "Pixies - Surfer Rosa & Come on Pilgrim\01 - Pixies - Bone Machine.wav" WAVE + TRACK 01 AUDIO + TITLE "Bone Machine" + PERFORMER "Pixies" + ISRC 000000000000 + PREGAP 00:00:32 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\02 - Pixies - Break My Body.wav" WAVE + TRACK 02 AUDIO + TITLE "Break My Body" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 + TRACK 03 AUDIO + TITLE "Something Against You" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 00 02:05:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\03 - Pixies - Something Against You.wav" WAVE + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\04 - Pixies - Broken Face.wav" WAVE + TRACK 04 AUDIO + TITLE "Broken Face" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\05 - Pixies - Gigantic.wav" WAVE + TRACK 05 AUDIO + TITLE "Gigantic" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\06 - Pixies - River Euphrates.wav" WAVE + TRACK 06 AUDIO + TITLE "River Euphrates" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\07 - Pixies - Where Is My Mind .wav" WAVE + TRACK 07 AUDIO + TITLE "Where Is My Mind?" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\08 - Pixies - Cactus.wav" WAVE + TRACK 08 AUDIO + TITLE "Cactus" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\09 - Pixies - Tony's Theme.wav" WAVE + TRACK 09 AUDIO + TITLE "Tony's Theme" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\10 - Pixies - Oh My Golly!.wav" WAVE + TRACK 10 AUDIO + TITLE "Oh My Golly!" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\11 - Pixies - Vamos.wav" WAVE + TRACK 11 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 + INDEX 02 00:44:70 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\12 - Pixies - I'm Amazed.wav" WAVE + TRACK 12 AUDIO + TITLE "I'm Amazed" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\13 - Pixies - Brick is Red.wav" WAVE + TRACK 13 AUDIO + TITLE "Brick is Red" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\14 - Pixies - Caribou.wav" WAVE + TRACK 14 AUDIO + TITLE "Caribou" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\15 - Pixies - Vamos.wav" WAVE + TRACK 15 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\16 - Pixies - Isla de Encanta.wav" WAVE + TRACK 16 AUDIO + TITLE "Isla de Encanta" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\17 - Pixies - Ed is Dead.wav" WAVE + TRACK 17 AUDIO + TITLE "Ed is Dead" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\18 - Pixies - The Holyday Song.wav" WAVE + TRACK 18 AUDIO + TITLE "The Holyday Song" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\19 - Pixies - Nimrod's Son.wav" WAVE + TRACK 19 AUDIO + TITLE "Nimrod's Son" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\20 - Pixies - I've Been Tired.wav" WAVE + TRACK 20 AUDIO + TITLE "I've Been Tired" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\21 - Pixies - Levitate Me.wav" WAVE + TRACK 21 AUDIO + TITLE "Levitate Me" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 diff --git a/morituri/test/surferrosa.eac.leftout.cue b/morituri/test/surferrosa.eac.leftout.cue new file mode 100644 index 0000000..b32adb4 --- /dev/null +++ b/morituri/test/surferrosa.eac.leftout.cue @@ -0,0 +1,136 @@ +REM GENRE Alternative +REM DATE 1987 +REM DISCID 350CAA15 +REM COMMENT "ExactAudioCopy v0.99pb4" +CATALOG 0000000000000 +PERFORMER "Pixies" +TITLE "Surfer Rosa & Come on Pilgrim" +FILE "Pixies - Surfer Rosa & Come on Pilgrim\01 - Pixies - Bone Machine.wav" WAVE + TRACK 01 AUDIO + TITLE "Bone Machine" + PERFORMER "Pixies" + ISRC 000000000000 + PREGAP 00:00:32 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\02 - Pixies - Break My Body.wav" WAVE + TRACK 02 AUDIO + TITLE "Break My Body" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\03 - Pixies - Something Against You.wav" WAVE + TRACK 03 AUDIO + TITLE "Something Against You" + PERFORMER "Pixies" + ISRC 000000000000 + PREGAP 00:00:45 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\04 - Pixies - Broken Face.wav" WAVE + TRACK 04 AUDIO + TITLE "Broken Face" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\05 - Pixies - Gigantic.wav" WAVE + TRACK 05 AUDIO + TITLE "Gigantic" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\06 - Pixies - River Euphrates.wav" WAVE + TRACK 06 AUDIO + TITLE "River Euphrates" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\07 - Pixies - Where Is My Mind .wav" WAVE + TRACK 07 AUDIO + TITLE "Where Is My Mind?" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\08 - Pixies - Cactus.wav" WAVE + TRACK 08 AUDIO + TITLE "Cactus" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\09 - Pixies - Tony's Theme.wav" WAVE + TRACK 09 AUDIO + TITLE "Tony's Theme" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\10 - Pixies - Oh My Golly!.wav" WAVE + TRACK 10 AUDIO + TITLE "Oh My Golly!" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\11 - Pixies - Vamos.wav" WAVE + TRACK 11 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 + INDEX 02 00:44:70 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\12 - Pixies - I'm Amazed.wav" WAVE + TRACK 12 AUDIO + TITLE "I'm Amazed" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\13 - Pixies - Brick is Red.wav" WAVE + TRACK 13 AUDIO + TITLE "Brick is Red" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\14 - Pixies - Caribou.wav" WAVE + TRACK 14 AUDIO + TITLE "Caribou" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\15 - Pixies - Vamos.wav" WAVE + TRACK 15 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\16 - Pixies - Isla de Encanta.wav" WAVE + TRACK 16 AUDIO + TITLE "Isla de Encanta" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\17 - Pixies - Ed is Dead.wav" WAVE + TRACK 17 AUDIO + TITLE "Ed is Dead" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\18 - Pixies - The Holyday Song.wav" WAVE + TRACK 18 AUDIO + TITLE "The Holyday Song" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\19 - Pixies - Nimrod's Son.wav" WAVE + TRACK 19 AUDIO + TITLE "Nimrod's Son" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\20 - Pixies - I've Been Tired.wav" WAVE + TRACK 20 AUDIO + TITLE "I've Been Tired" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\21 - Pixies - Levitate Me.wav" WAVE + TRACK 21 AUDIO + TITLE "Levitate Me" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 diff --git a/morituri/test/surferrosa.eac.noncompliant.cue b/morituri/test/surferrosa.eac.noncompliant.cue new file mode 100644 index 0000000..9e7f189 --- /dev/null +++ b/morituri/test/surferrosa.eac.noncompliant.cue @@ -0,0 +1,136 @@ +REM GENRE Alternative +REM DATE 1987 +REM DISCID 350CAA15 +REM COMMENT "ExactAudioCopy v0.99pb4" +CATALOG 0000000000000 +PERFORMER "Pixies" +TITLE "Surfer Rosa & Come on Pilgrim" +FILE "Pixies - Surfer Rosa & Come on Pilgrim\01 - Pixies - Bone Machine.wav" WAVE + TRACK 01 AUDIO + TITLE "Bone Machine" + PERFORMER "Pixies" + ISRC 000000000000 + PREGAP 00:00:32 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\02 - Pixies - Break My Body.wav" WAVE + TRACK 02 AUDIO + TITLE "Break My Body" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 + TRACK 03 AUDIO + TITLE "Something Against You" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 00 02:05:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\03 - Pixies - Something Against You.wav" WAVE + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\04 - Pixies - Broken Face.wav" WAVE + TRACK 04 AUDIO + TITLE "Broken Face" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\05 - Pixies - Gigantic.wav" WAVE + TRACK 05 AUDIO + TITLE "Gigantic" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\06 - Pixies - River Euphrates.wav" WAVE + TRACK 06 AUDIO + TITLE "River Euphrates" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\07 - Pixies - Where Is My Mind .wav" WAVE + TRACK 07 AUDIO + TITLE "Where Is My Mind?" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\08 - Pixies - Cactus.wav" WAVE + TRACK 08 AUDIO + TITLE "Cactus" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\09 - Pixies - Tony's Theme.wav" WAVE + TRACK 09 AUDIO + TITLE "Tony's Theme" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\10 - Pixies - Oh My Golly!.wav" WAVE + TRACK 10 AUDIO + TITLE "Oh My Golly!" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\11 - Pixies - Vamos.wav" WAVE + TRACK 11 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 + INDEX 02 00:44:70 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\12 - Pixies - I'm Amazed.wav" WAVE + TRACK 12 AUDIO + TITLE "I'm Amazed" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\13 - Pixies - Brick is Red.wav" WAVE + TRACK 13 AUDIO + TITLE "Brick is Red" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\14 - Pixies - Caribou.wav" WAVE + TRACK 14 AUDIO + TITLE "Caribou" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\15 - Pixies - Vamos.wav" WAVE + TRACK 15 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\16 - Pixies - Isla de Encanta.wav" WAVE + TRACK 16 AUDIO + TITLE "Isla de Encanta" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\17 - Pixies - Ed is Dead.wav" WAVE + TRACK 17 AUDIO + TITLE "Ed is Dead" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\18 - Pixies - The Holyday Song.wav" WAVE + TRACK 18 AUDIO + TITLE "The Holyday Song" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\19 - Pixies - Nimrod's Son.wav" WAVE + TRACK 19 AUDIO + TITLE "Nimrod's Son" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\20 - Pixies - I've Been Tired.wav" WAVE + TRACK 20 AUDIO + TITLE "I've Been Tired" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 +FILE "Pixies - Surfer Rosa & Come on Pilgrim\21 - Pixies - Levitate Me.wav" WAVE + TRACK 21 AUDIO + TITLE "Levitate Me" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 00:00:00 diff --git a/morituri/test/surferrosa.eac.single.cue b/morituri/test/surferrosa.eac.single.cue new file mode 100644 index 0000000..702eb48 --- /dev/null +++ b/morituri/test/surferrosa.eac.single.cue @@ -0,0 +1,116 @@ +REM GENRE Alternative +REM DATE 1987 +REM DISCID 350CAA15 +REM COMMENT "ExactAudioCopy v0.99pb4" +CATALOG 0000000000000 +PERFORMER "Pixies" +TITLE "Surfer Rosa & Come on Pilgrim" +FILE "Range.wav" WAVE + TRACK 01 AUDIO + TITLE "Bone Machine" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 00 00:00:00 + INDEX 01 00:00:32 + TRACK 02 AUDIO + TITLE "Break My Body" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 03:03:42 + TRACK 03 AUDIO + TITLE "Something Against You" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 00 05:08:42 + INDEX 01 05:09:12 + TRACK 04 AUDIO + TITLE "Broken Face" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 06:56:67 + TRACK 05 AUDIO + TITLE "Gigantic" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 08:27:00 + TRACK 06 AUDIO + TITLE "River Euphrates" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 12:21:70 + TRACK 07 AUDIO + TITLE "Where Is My Mind?" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 14:53:60 + TRACK 08 AUDIO + TITLE "Cactus" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 18:47:15 + TRACK 09 AUDIO + TITLE "Tony's Theme" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 21:03:70 + TRACK 10 AUDIO + TITLE "Oh My Golly!" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 22:56:15 + TRACK 11 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 24:43:32 + INDEX 02 25:28:27 + TRACK 12 AUDIO + TITLE "I'm Amazed" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 29:49:20 + TRACK 13 AUDIO + TITLE "Brick is Red" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 31:31:27 + TRACK 14 AUDIO + TITLE "Caribou" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 33:32:20 + TRACK 15 AUDIO + TITLE "Vamos" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 36:46:45 + TRACK 16 AUDIO + TITLE "Isla de Encanta" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 39:40:22 + TRACK 17 AUDIO + TITLE "Ed is Dead" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 41:21:47 + TRACK 18 AUDIO + TITLE "The Holyday Song" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 43:51:47 + TRACK 19 AUDIO + TITLE "Nimrod's Son" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 46:06:10 + TRACK 20 AUDIO + TITLE "I've Been Tired" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 48:23:25 + TRACK 21 AUDIO + TITLE "Levitate Me" + PERFORMER "Pixies" + ISRC 000000000000 + INDEX 01 51:24:07 From 7118555a7f000918e168d6ee835f2edcff9fc9b0 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 21:44:36 +0200 Subject: [PATCH 06/29] add doc --- morituri/image/toc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 4190324..22649ad 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -319,6 +319,10 @@ class TocFile(object, log.Loggable): self._messages.append((number + 1, message)) def getTrackLength(self, track): + """ + Returns the length of the given track, from its INDEX 01 to the next + track's INDEX 01 + """ # returns track length in frames, or -1 if can't be determined and # complete file should be assumed # FIXME: this assumes a track can only be in one file; is this true ? From f11672fd3de1df52cf37f77281d1645e07e76bfa Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 21:53:32 +0200 Subject: [PATCH 07/29] add a Source object, but don't use it yet --- morituri/image/toc.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 22649ad..1b7d29f 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -88,6 +88,38 @@ _INDEX_RE = re.compile(r""" """, re.VERBOSE) +class Sources(log.Loggable): + """ + I represent the list of sources used in the .toc file. + Each SILENCE and each FILE is a source. + If the filename for FILE doesn't change, the counter is not increased. + """ + + def __init__(self): + self._sources = [] + + def append(self, counter, offset, source): + """ + @param counter: the source counter; updates for each different + data source (silence or different file path) + @type counter: int + @param offset: the absolute disc offset where this source starts + """ + self.debug('Appending source, counter %d, offset %d, source %r' % ( + counter, offset, source)) + self._sources.append((counter, offset, source)) + + def get(self, offset): + """ + Retrieve the source used at the given offset. + """ + for i, (c, o, s) in enumerate(self._sources): + if offset < o: + return self._sources[i - 1] + + return self._sources[-1] + + class TocFile(object, log.Loggable): def __init__(self, path): @@ -119,6 +151,7 @@ class TocFile(object, log.Loggable): totalLength = 0 # accrued during TRACK record parsing, total disc pregapLength = 0 # length of the pre-gap, current track in for loop + sources = Sources() # 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 @@ -206,6 +239,7 @@ class TocFile(object, log.Loggable): if m: length = m.group('length') self.debug('SILENCE of %r', length) + sources.append(counter, absoluteOffset, None) if currentFile is not None: self.debug('SILENCE after FILE, increasing counter') counter += 1 @@ -241,6 +275,8 @@ class TocFile(object, log.Loggable): trackNumber, counter) currentFile = File(filePath, common.msfToFrames(start), common.msfToFrames(length)) + sources.append(counter, absoluteOffset + currentLength, + currentFile) #absoluteOffset += common.msfToFrames(start) currentLength += common.msfToFrames(length) From 73a7056d85f8458791b9644570babfae60ccf948 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 21:58:17 +0200 Subject: [PATCH 08/29] handle index 00 of track 1 specially --- morituri/image/table.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/morituri/image/table.py b/morituri/image/table.py index 9ea055c..79d1422 100644 --- a/morituri/image/table.py +++ b/morituri/image/table.py @@ -547,11 +547,19 @@ class Table(object, log.Loggable): if key in self.cdtext: lines.append('%s "%s"' % (key, self.cdtext[key])) - # add the first FILE line - path = self.tracks[0].getFirstIndex().path - counter = self.tracks[0].getFirstIndex().counter + # add the first FILE line; EAC always puts the first FILE + # statement before TRACK 01 + firstTrack = self.tracks[0] + indexOne = firstTrack.getIndex(1) + + firstIndex = firstTrack.getFirstIndex() + path = indexOne.path + counter = indexOne.counter + + assert path, "No path on TRACK 01 INDEX 01" writeFile(path) + for i, track in enumerate(self.tracks): # FIXME: skip data tracks for now if not track.audio: @@ -577,6 +585,14 @@ class Table(object, log.Loggable): for number in indexes: index = track.indexes[number] + # handle TRACK 01 INDEX 00 specially + if i == 0 and number == 0: + # if we have a silent pre-gap, output it + if not index.path: + length = indexOne.absolute - index.absolute + lines.append(" PREGAP %s" % common.framesToMSF(length)) + continue + if index.counter != counter: writeFile(index.path) counter = index.counter From 1ac8d43f88d62b918aea8443f085914f90396e3b Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 23:16:03 +0200 Subject: [PATCH 09/29] use diffStrings --- morituri/test/test_image_toc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index e41bc73..0ae3e90 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -139,7 +139,7 @@ class BlocTestCase(common.TestCase): cue = self.toc.table.cue() ref = open(os.path.join(os.path.dirname(__file__), 'bloc.cue')).read() - self.assertEquals(cue, ref) + common.diffStrings(cue, ref) def testCDDBId(self): self.toc.table.absolutize() From 142fa9e33eb0589205e7280ef862dd7bf2797211 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 21:59:43 +0200 Subject: [PATCH 10/29] create index with the correct path by using sources --- morituri/image/toc.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 1b7d29f..e0b4656 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -309,10 +309,11 @@ class TocFile(object, log.Loggable): continue length = common.msfToFrames(m.group('length')) - currentTrack.index(0, path=currentFile.path, + c, o, s = sources.get(absoluteOffset) + currentTrack.index(0, path=s and s.path or None, absolute=absoluteOffset, - relative=relativeOffset, counter=counter) - self.debug('track %d, added index %r', + relative=relativeOffset, counter=c) + self.debug('[track %2d index 00] added %r', currentTrack.number, currentTrack.getIndex(0)) # store the pregapLength to add it when we index 1 for this # track on the next iteration From d1940b639f10352cc08bb09185101c9449dfcef5 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 21:58:45 +0200 Subject: [PATCH 11/29] update tests --- morituri/test/test_image_toc.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 0ae3e90..a5bd4de 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -23,7 +23,10 @@ class CureTestCase(common.TestCase): def testGetTrackLength(self): t = self.toc.table.tracks[0] # first track has known length because the .toc is a single file - self.assertEquals(self.toc.getTrackLength(t), 28324) + # its length is all of track 1 from .toc, plus the INDEX 00 length + # of track 2 + self.assertEquals(self.toc.getTrackLength(t), + (((6 * 60) + 16) * 75 + 45) + ((1 * 75) + 4)) # last track has unknown length t = self.toc.table.tracks[-1] self.assertEquals(self.toc.getTrackLength(t), -1) @@ -403,10 +406,18 @@ class SurferRosaTestCase(common.TestCase): # HTOA t = self.toc.table.tracks[0] self.assertEquals(len(t.indexes), 2) - self.assertEquals(t.getIndex(0).relative, 0) - self.assertEquals(t.getIndex(0).absolute, 0) - self.assertEquals(t.getIndex(1).relative, 32) - self.assertEquals(t.getIndex(1).absolute, 32) + + i0 = t.getIndex(0) + self.assertEquals(i0.relative, 0) + self.assertEquals(i0.absolute, 0) + self.assertEquals(i0.path, None) + self.assertEquals(i0.counter, 0) + + i1 = t.getIndex(1) + self.assertEquals(i1.relative, 32) + self.assertEquals(i1.absolute, 32) + self.assertEquals(i1.path, 'data.wav') + self.assertEquals(i1.counter, 1) # track 11, Vamos From 2c234184904d22a9cc23fe6426a97f963e3a16ed Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 21:59:13 +0200 Subject: [PATCH 12/29] now take relative from currentFile --- morituri/image/toc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index e0b4656..9cc0c89 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -200,7 +200,7 @@ class TocFile(object, log.Loggable): # FIXME: why not set absolute offsets too ? currentTrack.index(1, path=currentFile.path, absolute=absoluteOffset + pregapLength, - relative=relativeOffset + pregapLength, + relative=currentFile.start + pregapLength, counter=counter) self.debug( '[track %02d index 01] pregapLength %r, added %r', @@ -339,7 +339,7 @@ class TocFile(object, log.Loggable): if currentTrack: currentTrack.index(1, path=currentFile.path, absolute=absoluteOffset + pregapLength, - relative=relativeOffset + pregapLength, counter=counter) + relative=currentFile.start, counter=counter) self.debug('[track %02d index 01] last track, added %r', currentTrack.number, currentTrack.getIndex(1)) From e3e3a87547f6617bc0877d7302d57d39a95b6ad1 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Mon, 19 Aug 2013 00:18:53 +0200 Subject: [PATCH 13/29] WIP: try to set relative offset correctly based on sources --- morituri/image/toc.py | 16 +++++++++++++++- morituri/test/test_image_toc.py | 13 ++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 9cc0c89..189de75 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -119,6 +119,16 @@ class Sources(log.Loggable): return self._sources[-1] + def getCounterStart(self, counter): + """ + Retrieve the absolute offset of the first source for this counter + """ + for i, (c, o, s) in enumerate(self._sources): + if c == counter: + return self._sources[i][1] + + return self._sources[-1][1] + class TocFile(object, log.Loggable): @@ -197,7 +207,6 @@ 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, absolute=absoluteOffset + pregapLength, relative=currentFile.start + pregapLength, @@ -310,6 +319,11 @@ class TocFile(object, log.Loggable): length = common.msfToFrames(m.group('length')) c, o, s = sources.get(absoluteOffset) + self.debug('at abs offset %d, we are in source %r' % ( + absoluteOffset, s)) + counterStart = sources.getCounterStart(c) + relativeOffset = absoluteOffset - counterStart + currentTrack.index(0, path=s and s.path or None, absolute=absoluteOffset, relative=relativeOffset, counter=c) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index a5bd4de..2a451e6 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -130,9 +130,16 @@ class BlocTestCase(common.TestCase): self.assertEquals(self.toc.getTrackLength(t), -1) def testIndexes(self): - t = self.toc.table.tracks[0] - self.assertEquals(t.getIndex(0).relative, 0) - self.assertEquals(t.getIndex(1).relative, 15220) + firstTrack = self.toc.table.tracks[0] + index0 = firstTrack.getIndex(0) + self.assertEquals(index0.absolute, 0) + self.assertEquals(index0.relative, 0) + self.assertEquals(index0.counter, 0) + + index1 = firstTrack.getIndex(1) + self.assertEquals(index1.absolute, 15220) + self.assertEquals(index1.relative, 0) + self.assertEquals(index1.counter, 1) # This disc has a pre-gap, so is a good test for .CUE writing From 1ef45c2b2a1f52617530c3bb4f388c9c8c60a828 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 18 Aug 2013 21:45:18 +0200 Subject: [PATCH 14/29] stop absolutizing --- morituri/test/test_image_toc.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 2a451e6..45b369b 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -62,7 +62,7 @@ class CureTestCase(common.TestCase): self._assertAbsolute(2, 1, 28324) self._assertPath(1, 1, "data.wav") - self.toc.table.absolutize() + # self.toc.table.absolutize() self.toc.table.clearFiles() self._assertAbsolute(1, 1, 0) @@ -86,7 +86,7 @@ class CureTestCase(common.TestCase): self._assertRelative(2, 1, None) def testConvertCue(self): - self.toc.table.absolutize() + # self.toc.table.absolutize() cue = self.toc.table.cue() ref = open(os.path.join(os.path.dirname(__file__), 'cure.cue')).read( ).decode('utf-8') @@ -152,7 +152,7 @@ class BlocTestCase(common.TestCase): common.diffStrings(cue, ref) def testCDDBId(self): - self.toc.table.absolutize() + # self.toc.table.absolutize() # cd-discid output: # ad0be00d 13 15370 35019 51532 69190 84292 96826 112527 132448 # 148595 168072 185539 203331 222103 3244 @@ -161,7 +161,7 @@ class BlocTestCase(common.TestCase): def testAccurateRip(self): # we verify it because it has failed in readdisc in the past - self.toc.table.absolutize() + # self.toc.table.absolutize() self.assertEquals(self.toc.table.getAccurateRipURL(), 'http://www.accuraterip.com/accuraterip/' 'e/d/2/dBAR-013-001af2de-0105994e-ad0be00d.bin') @@ -189,7 +189,7 @@ class BreedersTestCase(common.TestCase): self.assertEquals(cdt['TITLE'], 'OVERGLAZED') def testConvertCue(self): - 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__), @@ -211,7 +211,7 @@ class LadyhawkeTestCase(common.TestCase): self.failIf(self.toc.table.tracks[-1].audio) def testCDDBId(self): - self.toc.table.absolutize() + #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 @@ -260,7 +260,7 @@ class CapitalMergeTestCase(common.TestCase): self.table.merge(self.toc2.table) def testCDDBId(self): - self.table.absolutize() + #self.table.absolutize() self.assertEquals(self.table.getCDDBDiscId(), 'b910140c') # output from cd-discid: # b910140c 12 24320 44855 64090 77885 88095 104020 118245 129255 141765 @@ -327,7 +327,7 @@ class TOTBLTestCase(common.TestCase): self.assertEquals(len(self.toc.table.tracks), 11) def testCDDBId(self): - self.toc.table.absolutize() + #self.toc.table.absolutize() self.assertEquals(self.toc.table.getCDDBDiscId(), '810b7b0b') @@ -437,7 +437,7 @@ class SurferRosaTestCase(common.TestCase): self.assertEquals(t.getIndex(2).relative, 3370) self.assertEquals(t.getIndex(2).absolute, None) - self.toc.table.absolutize() + # self.toc.table.absolutize() self.assertEquals(t.getIndex(2).absolute, 3370) # print self.toc.table.cue() From 2200776b30c94ab68f04166c1e94799a62da9e8b Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:07:49 +0200 Subject: [PATCH 15/29] update debug --- morituri/image/toc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 189de75..2363dd8 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -105,7 +105,7 @@ class Sources(log.Loggable): @type counter: int @param offset: the absolute disc offset where this source starts """ - self.debug('Appending source, counter %d, offset %d, source %r' % ( + self.debug('Appending source, counter %d, abs offset %d, source %r' % ( counter, offset, source)) self._sources.append((counter, offset, source)) From 38193c7f0ca4000accb210ab1ccc91c949c87753 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:08:09 +0200 Subject: [PATCH 16/29] add/fix debug --- morituri/image/toc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 2363dd8..04ac542 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -327,7 +327,7 @@ class TocFile(object, log.Loggable): currentTrack.index(0, path=s and s.path or None, absolute=absoluteOffset, relative=relativeOffset, counter=c) - self.debug('[track %2d index 00] added %r', + self.debug('[track %02d index 00] added %r', currentTrack.number, currentTrack.getIndex(0)) # store the pregapLength to add it when we index 1 for this # track on the next iteration From a1e787648e42929c5ea56674c276da98fc49b083 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:08:42 +0200 Subject: [PATCH 17/29] add more tests, after calculating expected values for this disc --- morituri/test/test_image_toc.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 45b369b..f5241f8 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -130,16 +130,28 @@ class BlocTestCase(common.TestCase): self.assertEquals(self.toc.getTrackLength(t), -1) def testIndexes(self): - firstTrack = self.toc.table.tracks[0] - index0 = firstTrack.getIndex(0) - self.assertEquals(index0.absolute, 0) - self.assertEquals(index0.relative, 0) - self.assertEquals(index0.counter, 0) + track01 = self.toc.table.tracks[0] + index00 = track01.getIndex(0) + self.assertEquals(index00.absolute, 0) + self.assertEquals(index00.relative, 0) + self.assertEquals(index00.counter, 0) - index1 = firstTrack.getIndex(1) - self.assertEquals(index1.absolute, 15220) - self.assertEquals(index1.relative, 0) - self.assertEquals(index1.counter, 1) + index01 = track01.getIndex(1) + self.assertEquals(index01.absolute, 15220) + self.assertEquals(index01.relative, 0) + self.assertEquals(index01.counter, 1) + + track05 = self.toc.table.tracks[4] + + index00 = track05.getIndex(0) + self.assertEquals(index00.absolute, 84070) + self.assertEquals(index00.relative, 68850) + self.assertEquals(index00.counter, 1) + + index01 = track05.getIndex(1) + self.assertEquals(index01.absolute, 84142) + self.assertEquals(index01.relative, 68922) + self.assertEquals(index01.counter, 1) # This disc has a pre-gap, so is a good test for .CUE writing From b59bf8f98a2b68c2349fd939c4e7965eda2de32a Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:10:02 +0200 Subject: [PATCH 18/29] make sources an object property --- morituri/image/toc.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 04ac542..52e5ade 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -142,6 +142,9 @@ class TocFile(object, log.Loggable): self.table = table.Table() self.logName = '' % id(self) + self._sources = Sources() + + def parse(self): # these two objects start as None then get set as real objects, # so no need to complain about them here @@ -161,8 +164,6 @@ class TocFile(object, log.Loggable): totalLength = 0 # accrued during TRACK record parsing, total disc pregapLength = 0 # length of the pre-gap, current track in for loop - sources = Sources() - # 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 @@ -248,7 +249,7 @@ class TocFile(object, log.Loggable): if m: length = m.group('length') self.debug('SILENCE of %r', length) - sources.append(counter, absoluteOffset, None) + self._sources.append(counter, absoluteOffset, None) if currentFile is not None: self.debug('SILENCE after FILE, increasing counter') counter += 1 @@ -284,7 +285,7 @@ class TocFile(object, log.Loggable): trackNumber, counter) currentFile = File(filePath, common.msfToFrames(start), common.msfToFrames(length)) - sources.append(counter, absoluteOffset + currentLength, + self._sources.append(counter, absoluteOffset + currentLength, currentFile) #absoluteOffset += common.msfToFrames(start) currentLength += common.msfToFrames(length) @@ -318,10 +319,10 @@ class TocFile(object, log.Loggable): continue length = common.msfToFrames(m.group('length')) - c, o, s = sources.get(absoluteOffset) + c, o, s = self._sources.get(absoluteOffset) self.debug('at abs offset %d, we are in source %r' % ( absoluteOffset, s)) - counterStart = sources.getCounterStart(c) + counterStart = self._sources.getCounterStart(c) relativeOffset = absoluteOffset - counterStart currentTrack.index(0, path=s and s.path or None, From ddea002a8f443a803620614cbc207517c470cfc2 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:32:06 +0200 Subject: [PATCH 19/29] also add source for DATAFILE --- morituri/image/toc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 52e5ade..7d293fc 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -306,6 +306,8 @@ class TocFile(object, log.Loggable): trackNumber, counter) # FIXME: assume that a MODE2_FORM_MIX track always starts at 0 currentFile = File(filePath, 0, common.msfToFrames(length)) + self._sources.append(counter, absoluteOffset + currentLength, + currentFile) #absoluteOffset += common.msfToFrames(start) currentLength += common.msfToFrames(length) From 61fdb2c332067c9b216322b491f6920b28abe747 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:38:19 +0200 Subject: [PATCH 20/29] move some assignments around to be more logical --- morituri/image/toc.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 7d293fc..62c5c52 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -217,24 +217,27 @@ class TocFile(object, log.Loggable): currentTrack.number, pregapLength, currentTrack.getIndex(1)) - # update running totals + # create a new track to be filled by later lines trackNumber += 1 + trackMode = m.group('mode') + audio = trackMode == 'AUDIO' + currentTrack = table.Track(trackNumber, audio=audio) + self.table.tracks.append(currentTrack) + + # update running totals absoluteOffset += currentLength relativeOffset += currentLength totalLength += currentLength - trackMode = m.group('mode') - - # reset counters - currentLength = 0 - indexNumber = 1 - pregapLength = 0 # FIXME: track mode self.debug('found track %d, mode %s, at absoluteOffset %d', trackNumber, trackMode, absoluteOffset) - audio = trackMode == 'AUDIO' - currentTrack = table.Track(trackNumber, audio=audio) - self.table.tracks.append(currentTrack) + + # reset counters relative to a track + currentLength = 0 + indexNumber = 1 + pregapLength = 0 + continue # look for ISRC lines From bcd350f7686a0bf866d98999d1f5c9bacca7471d Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:38:40 +0200 Subject: [PATCH 21/29] use a common _index method for all cases --- morituri/image/toc.py | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 62c5c52..c83e940 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -144,6 +144,24 @@ class TocFile(object, log.Loggable): self._sources = Sources() + def _index(self, currentTrack, i, absoluteOffset, trackOffset): + absolute = absoluteOffset + trackOffset + # this may be in a new source, so calculate relative + c, o, s = self._sources.get(absolute) + self.debug('at abs offset %d, we are in source %r' % ( + absolute, s)) + counterStart = self._sources.getCounterStart(c) + relative = absolute - counterStart + + currentTrack.index(i, path=s.path, + absolute=absolute, + relative=relative, + counter=c) + self.debug( + '[track %02d index %02d] trackOffset %r, added %r', + currentTrack.number, i, trackOffset, + currentTrack.getIndex(i)) + def parse(self): # these two objects start as None then get set as real objects, @@ -208,14 +226,7 @@ class TocFile(object, log.Loggable): # set index 1 of previous track if there was one, using # pregapLength if applicable if currentTrack: - currentTrack.index(1, path=currentFile.path, - absolute=absoluteOffset + pregapLength, - relative=currentFile.start + pregapLength, - counter=counter) - self.debug( - '[track %02d index 01] pregapLength %r, added %r', - currentTrack.number, pregapLength, - currentTrack.getIndex(1)) + self._index(currentTrack, 1, absoluteOffset, pregapLength) # create a new track to be filled by later lines trackNumber += 1 @@ -349,19 +360,11 @@ class TocFile(object, log.Loggable): indexNumber += 1 offset = common.msfToFrames(m.group('offset')) - currentTrack.index(indexNumber, path=currentFile.path, - relative=offset, counter=counter) - self.debug('[track %02d index %02d] added %r', - currentTrack.number, indexNumber, - currentTrack.getIndex(indexNumber)) + self._index(currentTrack, indexNumber, absoluteOffset, offset) # handle index 1 of final track, if any if currentTrack: - currentTrack.index(1, path=currentFile.path, - absolute=absoluteOffset + pregapLength, - relative=currentFile.start, counter=counter) - self.debug('[track %02d index 01] last track, added %r', - currentTrack.number, currentTrack.getIndex(1)) + self._index(currentTrack, 1, absoluteOffset, pregapLength) # totalLength was added up to the penultimate track self.table.leadout = totalLength + currentLength From bf3db822dd0ef6dbbefa6293687eeda0ad9ee4d9 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 00:43:35 +0200 Subject: [PATCH 22/29] strokes test case is now correct --- morituri/test/test_image_toc.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index f5241f8..803040b 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -360,17 +360,11 @@ class StrokesTestCase(common.TestCase): i0 = t.getIndex(0) self.assertEquals(i0.relative, 0) self.assertEquals(i0.absolute, 0) - # FIXME: this is what we should have - # self.assertEquals(i0.counter, 0) - # self.assertEquals(i0.path, None) - # FIXME: this is what it is right now - self.assertEquals(i0.counter, 1) - self.assertEquals(i0.path, u'data.wav') + self.assertEquals(i0.counter, 0) + self.assertEquals(i0.path, None) i1 = t.getIndex(1) - # FIXME: relative should be 0, as it should point to the start - # of data.wav - self.assertEquals(i1.relative, 1) + self.assertEquals(i1.relative, 0) self.assertEquals(i1.absolute, 1) self.assertEquals(i1.counter, 1) self.assertEquals(i1.path, u'data.wav') @@ -378,9 +372,7 @@ class StrokesTestCase(common.TestCase): cue = self._filterCue(self.toc.table.cue()) ref = self._filterCue(open(os.path.join(os.path.dirname(__file__), 'strokes-someday.eac.cue')).read()) - # FIXME: this diff should match - # common.diffStrings(cue, ref) - self.assertRaises(AssertionError, common.diffStrings, cue, ref) + common.diffStrings(cue, ref) def _filterCue(self, output): # helper to be able to compare our generated .cue with the From 9f2ff9ee52e771bd147b11527e97908ade75834a Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 01:05:33 +0200 Subject: [PATCH 23/29] fix expectations on surfer rosa test looks like it was interpreting relative on an index02 relative to the track's index 00, instead of relative to the source --- morituri/test/test_image_toc.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 803040b..49d56b8 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -402,6 +402,9 @@ class StrokesTestCase(common.TestCase): # Surfer Rosa has # track 00 consisting of 32 frames of SILENCE # track 11 Vamos with an INDEX 02 +# compared to an EAC single .cue file, all our offsets are 32 frames off +# because the toc uses silence for track 01 index 00 while EAC puts it in +# Range.wav class SurferRosaTestCase(common.TestCase): @@ -425,7 +428,7 @@ class SurferRosaTestCase(common.TestCase): self.assertEquals(i0.counter, 0) i1 = t.getIndex(1) - self.assertEquals(i1.relative, 32) + self.assertEquals(i1.relative, 0) self.assertEquals(i1.absolute, 32) self.assertEquals(i1.path, 'data.wav') self.assertEquals(i1.counter, 1) @@ -436,13 +439,10 @@ class SurferRosaTestCase(common.TestCase): self.assertEquals(len(t.indexes), 2) # 32 frames of silence, and 1483 seconds of data.wav - self.assertEquals(t.getIndex(1).relative, 111257) + self.assertEquals(t.getIndex(1).relative, 111225) self.assertEquals(t.getIndex(1).absolute, 111257) - self.assertEquals(t.getIndex(2).relative, 3370) - self.assertEquals(t.getIndex(2).absolute, None) - - # self.toc.table.absolutize() - self.assertEquals(t.getIndex(2).absolute, 3370) + self.assertEquals(t.getIndex(2).relative, 111225 + 3370) + self.assertEquals(t.getIndex(2).absolute, 111257 + 3370) # print self.toc.table.cue() From 38554e52246d44f75fb42a2e6a5047c52e4e611d Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 01:12:32 +0200 Subject: [PATCH 24/29] add note --- HACKING | 1 + 1 file changed, 1 insertion(+) diff --git a/HACKING b/HACKING index cc25424..5152f78 100644 --- a/HACKING +++ b/HACKING @@ -44,3 +44,4 @@ PLEXTOR CD-R PX-W8432T Read offset of device is: 355. Test discs ---------- The Strokes - Someday (promo): has 1 frame silence marked as SILENCE +The Pixies - Surfer Rosa/Come on Pilgrim: has pre-gap, and INDEX 02 on TRACK 11 From ea9225a9de6f2b8e04e07da425476c97a98273ef Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 20 Aug 2013 01:16:45 +0200 Subject: [PATCH 25/29] now that we have a literal conversion of the toc, update the toc doesn't notice the real pregap audio data, so marks the HTOA as silence, and puts all following audio data in one file. Update .cue file to reflect this; ie, create a cue file that misses the HTOA --- morituri/test/bloc.cue | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/morituri/test/bloc.cue b/morituri/test/bloc.cue index 2176f26..a6c3295 100644 --- a/morituri/test/bloc.cue +++ b/morituri/test/bloc.cue @@ -2,37 +2,37 @@ REM DISCID AD0BE00D REM COMMENT "Morituri" FILE "data.wav" WAVE TRACK 01 AUDIO - INDEX 00 00:00:00 - INDEX 01 03:22:70 + PREGAP 03:22:70 + INDEX 01 00:00:00 TRACK 02 AUDIO - INDEX 01 07:44:69 + INDEX 01 04:21:74 TRACK 03 AUDIO - INDEX 01 11:25:07 + INDEX 01 08:02:12 TRACK 04 AUDIO - INDEX 01 15:20:40 + INDEX 01 11:57:45 TRACK 05 AUDIO - INDEX 00 18:40:70 - INDEX 01 18:41:67 + INDEX 00 15:18:00 + INDEX 01 15:18:72 TRACK 06 AUDIO - INDEX 00 21:28:35 - INDEX 01 21:29:01 + INDEX 00 18:05:40 + INDEX 01 18:06:06 TRACK 07 AUDIO - INDEX 00 24:58:10 - INDEX 01 24:58:27 + INDEX 00 21:35:15 + INDEX 01 21:35:32 TRACK 08 AUDIO - INDEX 00 29:23:69 - INDEX 01 29:23:73 + INDEX 00 26:00:74 + INDEX 01 26:01:03 TRACK 09 AUDIO - INDEX 00 32:59:09 - INDEX 01 32:59:20 + INDEX 00 29:36:14 + INDEX 01 29:36:25 TRACK 10 AUDIO - INDEX 01 37:18:72 + INDEX 01 33:56:02 TRACK 11 AUDIO - INDEX 00 41:11:21 - INDEX 01 41:11:64 + INDEX 00 37:48:26 + INDEX 01 37:48:69 TRACK 12 AUDIO - INDEX 00 45:07:40 - INDEX 01 45:09:06 + INDEX 00 41:44:45 + INDEX 01 41:46:11 TRACK 13 AUDIO - INDEX 00 49:19:06 - INDEX 01 49:19:28 + INDEX 00 45:56:11 + INDEX 01 45:56:33 From abc03e8e433dc3327c65882b6a3e20b9032c73c8 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sat, 24 Aug 2013 01:25:06 +0200 Subject: [PATCH 26/29] since the cached results have wrong (negative) relative for index > 01, make sure we don't use the cache by upping the version --- morituri/common/cache.py | 17 ++++++++++++----- morituri/image/table.py | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/morituri/common/cache.py b/morituri/common/cache.py index b1cdb06..d2ff9fe 100644 --- a/morituri/common/cache.py +++ b/morituri/common/cache.py @@ -115,7 +115,7 @@ class Persister(log.Loggable): os.unlink(self._path) -class PersistedCache(object): +class PersistedCache(log.Loggable): """ I wrap a directory of persisted objects. """ @@ -138,11 +138,15 @@ class PersistedCache(object): Returns the persister for the given key. """ persister = Persister(self._getPath(key)) + if persister.object: + if hasattr(persister.object, 'instanceVersion'): + o = persister.object + if o.instanceVersion < o.__class__.classVersion: + self.debug( + 'key %r persisted object version %d is outdated', + key, o.instanceVersion) + persister.object = None # FIXME: don't delete old objects atm - # if persister.object: - # if hasattr(persister.object, 'instanceVersion'): - # o = persister.object - # if o.instanceVersion < o.__class__.classVersion: # persister.delete() return persister @@ -230,6 +234,9 @@ class TableCache(log.Loggable): self.debug('cached table is for different mb id %r' % ( ptable.object.getMusicBrainzDiscId())) ptable.object = None + else: + self.debug('no valid cached table found for %r' % + cddbdiscid) if not ptable.object: # get an empty persistable from the writable location diff --git a/morituri/image/table.py b/morituri/image/table.py index 79d1422..56e33c5 100644 --- a/morituri/image/table.py +++ b/morituri/image/table.py @@ -168,7 +168,7 @@ class Table(object, log.Loggable): catalog = None # catalog number; FIXME: is this UPC ? cdtext = None - classVersion = 3 + classVersion = 4 def __init__(self, tracks=None): if not tracks: From 1141f5e27c3b0bb91992a0510645ef8ac9b7ae80 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sat, 24 Aug 2013 01:25:43 +0200 Subject: [PATCH 27/29] add type doc --- morituri/image/table.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/morituri/image/table.py b/morituri/image/table.py index 56e33c5..0386d49 100644 --- a/morituri/image/table.py +++ b/morituri/image/table.py @@ -635,6 +635,9 @@ class Table(object, log.Loggable): to adjust the path. Assumes all indexes have an absolute offset and will raise if not. + + @type track: C{int} + @type index: C{int} """ self.debug('setFile: track %d, index %d, path %r, ' 'length %r, counter %r', track, index, path, length, counter) From 19fa97e23aeb0343fe9fb8481f1428d0553fa11f Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sat, 24 Aug 2013 13:57:56 +0200 Subject: [PATCH 28/29] use more diffstrings; use it from reference to generated --- morituri/test/test_image_cue.py | 6 ++++-- morituri/test/test_image_toc.py | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/morituri/test/test_image_cue.py b/morituri/test/test_image_cue.py index b6e2909..5abfcd7 100644 --- a/morituri/test/test_image_cue.py +++ b/morituri/test/test_image_cue.py @@ -7,6 +7,8 @@ import unittest from morituri.image import table, cue +from morituri.test import common + class KingsSingleTestCase(unittest.TestCase): @@ -73,7 +75,7 @@ class WriteCueFileTestCase(unittest.TestCase): it.absolutize() it.leadout = 3000 - self.assertEquals(it.cue(), """REM DISCID 0C002802 + common.diffStrings(u"""REM DISCID 0C002802 REM COMMENT "Morituri" FILE "track01.wav" WAVE TRACK 01 AUDIO @@ -82,5 +84,5 @@ FILE "track01.wav" WAVE INDEX 00 00:13:25 FILE "track02.wav" WAVE INDEX 01 00:00:00 -""") +""", it.cue()) os.unlink(path) diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 49d56b8..998bc0a 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -90,7 +90,7 @@ class CureTestCase(common.TestCase): cue = self.toc.table.cue() ref = open(os.path.join(os.path.dirname(__file__), 'cure.cue')).read( ).decode('utf-8') - common.diffStrings(cue, ref) + common.diffStrings(ref, cue) # we verify it because it has failed in readdisc in the past self.assertEquals(self.toc.table.getAccurateRipURL(), @@ -160,8 +160,8 @@ class BlocTestCase(common.TestCase): self.failUnless(self.toc.table.hasTOC()) cue = self.toc.table.cue() ref = open(os.path.join(os.path.dirname(__file__), - 'bloc.cue')).read() - common.diffStrings(cue, ref) + 'bloc.cue')).read().decode('utf-8') + common.diffStrings(ref, cue) def testCDDBId(self): # self.toc.table.absolutize() @@ -371,8 +371,8 @@ class StrokesTestCase(common.TestCase): cue = self._filterCue(self.toc.table.cue()) ref = self._filterCue(open(os.path.join(os.path.dirname(__file__), - 'strokes-someday.eac.cue')).read()) - common.diffStrings(cue, ref) + 'strokes-someday.eac.cue')).read()).decode('utf-8') + common.diffStrings(ref, cue) def _filterCue(self, output): # helper to be able to compare our generated .cue with the From 354bd7744f7dee547133499555b70d677656a9ad Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sat, 24 Aug 2013 13:58:21 +0200 Subject: [PATCH 29/29] fix so first FILE goes before TRACK 01 and possible PREGAP --- morituri/image/table.py | 106 +++++++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 34 deletions(-) diff --git a/morituri/image/table.py b/morituri/image/table.py index 0386d49..c3cd570 100644 --- a/morituri/image/table.py +++ b/morituri/image/table.py @@ -523,11 +523,15 @@ class Table(object, log.Loggable): @rtype: C{unicode} """ + self.debug('generating .cue for cuePath %r', cuePath) + lines = [] def writeFile(path): targetPath = common.getRelativePath(path, cuePath) - lines.append('FILE "%s" WAVE' % targetPath) + line = 'FILE "%s" WAVE' % targetPath + lines.append(line) + self.debug('writeFile: %r' % line) # header main = ['PERFORMER', 'TITLE'] @@ -547,57 +551,91 @@ class Table(object, log.Loggable): if key in self.cdtext: lines.append('%s "%s"' % (key, self.cdtext[key])) + # FIXME: + # - the first FILE statement goes before the first TRACK, even if + # there is a non-file-using PREGAP + # - the following FILE statements come after the last INDEX that + # use that FILE; so before a next TRACK, PREGAP silence, ... + # add the first FILE line; EAC always puts the first FILE - # statement before TRACK 01 + # statement before TRACK 01 and any possible PRE-GAP firstTrack = self.tracks[0] + index = firstTrack.getFirstIndex() indexOne = firstTrack.getIndex(1) + counter = index.counter + track = firstTrack - firstIndex = firstTrack.getFirstIndex() - path = indexOne.path - counter = indexOne.counter - - assert path, "No path on TRACK 01 INDEX 01" - writeFile(path) + while not index.path: + t, i = self.getNextTrackIndex(track.number, index.number) + track = self.tracks[t - 1] + index = track.getIndex(i) + counter = index.counter + if index.path: + self.debug('counter %d, writeFile' % counter) + writeFile(index.path) for i, track in enumerate(self.tracks): + self.debug('track i %r, track %r' % (i, track)) # FIXME: skip data tracks for now if not track.audio: continue - # if there is no index 0, but there is a new file, advance - # FILE line here - if not 0 in track.indexes: - index = track.indexes[1] - if index.counter != counter: - writeFile(index.path) - counter = index.counter - lines.append(" TRACK %02d %s" % (i + 1, 'AUDIO')) - for key in CDTEXT_FIELDS: - if key in track.cdtext: - lines.append(' %s "%s"' % (key, track.cdtext[key])) - - if track.isrc is not None: - lines.append(" ISRC %s" % track.isrc) - indexes = track.indexes.keys() indexes.sort() + wroteTrack = False + for number in indexes: index = track.indexes[number] - # handle TRACK 01 INDEX 00 specially - if i == 0 and number == 0: - # if we have a silent pre-gap, output it - if not index.path: - length = indexOne.absolute - index.absolute - lines.append(" PREGAP %s" % common.framesToMSF(length)) - continue + self.debug('index %r, %r' % (number, index)) - if index.counter != counter: - writeFile(index.path) + # any time the source counter changes to a higher value, + # write a FILE statement + # it has to be higher, because we can run into the HTOA + # at counter 0 here + if index.counter > counter: + if index.path: + self.debug('counter %d, writeFile' % counter) + writeFile(index.path) + self.debug('setting counter to index.counter %r' % + index.counter) counter = index.counter - lines.append(" INDEX %02d %s" % (number, - common.framesToMSF(index.relative))) + + # any time we hit the first index, write a TRACK statement + if not wroteTrack: + wroteTrack = True + line = " TRACK %02d %s" % (i + 1, 'AUDIO') + lines.append(line) + self.debug('%r' % line) + + for key in CDTEXT_FIELDS: + if key in track.cdtext: + lines.append(' %s "%s"' % ( + key, track.cdtext[key])) + + if track.isrc is not None: + lines.append(" ISRC %s" % track.isrc) + + # handle TRACK 01 INDEX 00 specially + if 0 in indexes: + index00 = track.indexes[0] + if i == 0: + # if we have a silent pre-gap, output it + if not index00.path: + length = indexOne.absolute - index00.absolute + lines.append(" PREGAP %s" % + common.framesToMSF(length)) + continue + + # handle any other INDEX 00 after its TRACK + lines.append(" INDEX %02d %s" % (0, + common.framesToMSF(index00.relative))) + + if number > 0: + # index 00 is output after TRACK up above + lines.append(" INDEX %02d %s" % (number, + common.framesToMSF(index.relative))) lines.append("")