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 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 9ea055c..c3cd570 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: @@ -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,41 +551,91 @@ 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 - writeFile(path) + # 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 and any possible PRE-GAP + firstTrack = self.tracks[0] + index = firstTrack.getFirstIndex() + indexOne = firstTrack.getIndex(1) + counter = index.counter + track = firstTrack + + 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] - if index.counter != counter: - writeFile(index.path) + self.debug('index %r, %r' % (number, index)) + + # 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("") @@ -619,6 +673,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) diff --git a/morituri/image/toc.py b/morituri/image/toc.py index b43ee41..c83e940 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -88,6 +88,48 @@ _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, abs 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] + + 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): def __init__(self, path): @@ -100,6 +142,27 @@ class TocFile(object, log.Loggable): self.table = table.Table() self.logName = '' % id(self) + 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, # so no need to complain about them here @@ -119,7 +182,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 - # 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 @@ -164,34 +226,29 @@ 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=relativeOffset + 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 + trackMode = m.group('mode') + audio = trackMode == 'AUDIO' + currentTrack = table.Track(trackNumber, audio=audio) + self.table.tracks.append(currentTrack) # update running totals - trackNumber += 1 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 @@ -206,9 +263,11 @@ class TocFile(object, log.Loggable): if m: length = m.group('length') self.debug('SILENCE of %r', length) + self._sources.append(counter, absoluteOffset, None) if currentFile is not None: self.debug('SILENCE after FILE, increasing counter') counter += 1 + relativeOffset = 0 currentFile = None currentLength += common.msfToFrames(length) @@ -218,6 +277,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) @@ -237,7 +297,10 @@ 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)) + self._sources.append(counter, absoluteOffset + currentLength, + currentFile) #absoluteOffset += common.msfToFrames(start) currentLength += common.msfToFrames(length) @@ -256,7 +319,9 @@ 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)) + self._sources.append(counter, absoluteOffset + currentLength, + currentFile) #absoluteOffset += common.msfToFrames(start) currentLength += common.msfToFrames(length) @@ -270,10 +335,16 @@ class TocFile(object, log.Loggable): continue length = common.msfToFrames(m.group('length')) - currentTrack.index(0, path=currentFile.path, + c, o, s = self._sources.get(absoluteOffset) + self.debug('at abs offset %d, we are in source %r' % ( + absoluteOffset, s)) + counterStart = self._sources.getCounterStart(c) + relativeOffset = absoluteOffset - counterStart + + 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 %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 @@ -289,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=relativeOffset + pregapLength, 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 @@ -316,6 +379,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 ? @@ -351,13 +418,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, ) 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 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/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 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 24e9345..998bc0a 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) @@ -59,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) @@ -83,11 +86,11 @@ 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') - 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(), @@ -127,9 +130,28 @@ 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) + 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) + + 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 @@ -138,11 +160,11 @@ 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() - self.assertEquals(cue, ref) + 'bloc.cue')).read().decode('utf-8') + common.diffStrings(ref, cue) 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 @@ -151,7 +173,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') @@ -179,7 +201,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__), @@ -201,7 +223,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 @@ -250,7 +272,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 @@ -317,7 +339,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') @@ -335,13 +357,54 @@ 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) + self.assertEquals(i0.counter, 0) + self.assertEquals(i0.path, None) + + i1 = t.getIndex(1) + self.assertEquals(i1.relative, 0) + self.assertEquals(i1.absolute, 1) + 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()).decode('utf-8') + common.diffStrings(ref, cue) + + 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 # 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): @@ -357,10 +420,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, 0) + self.assertEquals(i1.absolute, 32) + self.assertEquals(i1.path, 'data.wav') + self.assertEquals(i1.counter, 1) # track 11, Vamos @@ -368,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()