* morituri/image/image.py:

Refactor to use TOC class.
	* morituri/image/toc.py:
	  Fully document.
This commit is contained in:
Thomas Vander Stichele
2009-04-15 12:45:22 +00:00
parent 02edffa629
commit 065754d5d1
3 changed files with 81 additions and 52 deletions

View File

@@ -1,3 +1,10 @@
2009-04-15 Thomas Vander Stichele <thomas at apestaart dot org>
* morituri/image/image.py:
Refactor to use TOC class.
* morituri/image/toc.py:
Fully document.
2009-04-15 Thomas Vander Stichele <thomas at apestaart dot org>
* morituri/test/test_image_toc.py (added):

View File

@@ -30,7 +30,7 @@ import struct
import gst
from morituri.common import task, crc
from morituri.image import cue
from morituri.image import cue, toc
class Image:
def __init__(self, path):
@@ -87,70 +87,32 @@ class Image:
# checksums that use it should add it there
offset = self.cue.tracks[0].getIndex(1)[0]
tracks = []
for i in range(len(self.cue.tracks)):
self._offsets.append(offset)
length = self.cue.getTrackLength(self.cue.tracks[i])
if length == -1:
length = verify.lengths[i + 1]
self._lengths.append(length)
tracks.append(toc.Track(i + 1, offset, offset + length - 1))
offset += length
self.toc = toc.TOC(tracks)
def getTrackOffset(self, track):
return self._offsets[self.cue.tracks.index(track)]
def getTrackLength(self, track):
return self._lengths[self.cue.tracks.index(track)]
def _cddbSum(self, i):
ret = 0
while i > 0:
ret += (i % 10)
i /= 10
return ret
return self.toc.getTrackLength(self.cue.tracks.index(track) + 1)
def getCDDBDiscId(self):
n = 0
for track in self.cue.tracks:
# CD's have a standard lead-in time of 2 seconds
# which gets added for CDDB disc id's
offset = self.getTrackOffset(track) + 2 * crc.DISC_FRAMES_PER_SECOND
seconds = offset / crc.DISC_FRAMES_PER_SECOND
n += self._cddbSum(seconds)
last = self.cue.tracks[-1]
leadout = self.getTrackOffset(last) + self.getTrackLength(last)
frameLength = leadout - self.getTrackOffset(self.cue.tracks[0])
t = frameLength / crc.DISC_FRAMES_PER_SECOND
value = (n % 0xff) << 24 | t << 8 | len(self.cue.tracks)
return "%08x" % value
return self.toc.getCDDBDiscId()
def getAccurateRipIds(self):
"""
@rtype: two-tuple of (str, str)
"""
discId1 = 0
discId2 = 0
for i, track in enumerate(self.cue.tracks):
offset = self.getTrackOffset(track)
discId1 += offset
discId2 += (offset or 1) * (i + 1)
# also add end offsets
last = self.cue.tracks[-1]
leadout = self.getTrackOffset(last) + self.getTrackLength(last)
discId1 += leadout
discId2 += leadout * (len(self.cue.tracks) + 1)
discId1 &= 0xffffffff
discId2 &= 0xffffffff
return ("%08x" % discId1, "%08x" % discId2)
return self.toc.getAccurateRipIds()
def getAccurateRipURL(self):
discId1, discId2 = self.getAccurateRipIds()

View File

@@ -33,9 +33,22 @@ from morituri.common import task, crc
from morituri.image import cue
class Track:
number = None # track number, 1-based
start = None # start of track in CD frames, 0-based
end = None # end of track in CD frames, 0-based
"""
I represent a track entry in a Table of Contents.
@ivar number: track number (1-based)
@type number: int
@ivar start: start of track, in CD frames (0-based)
@type start: int
@ivar end: end of track, in CD frames (0-based)
@type end: int
@ivar audio: whether the track is audio
@type audio: bool
"""
number = None
start = None
end = None
audio = True
def __init__(self, number, start, end, audio=True):
@@ -45,6 +58,12 @@ class Track:
self.audio = audio
class TOC:
"""
I represent the Table of Contents of a CD.
@ivar tracks: tracks on this CD
@type tracks: list of L{Track}
"""
tracks = None # list of Track
@@ -55,16 +74,41 @@ class TOC:
self.tracks = tracks
def getTrackStart(self, number):
"""
@param number: the track number, 1-based
@type number: int
@returns: the start of the given track number, in CD frames
@rtype: int
"""
return self.tracks[number - 1].start
def getTrackEnd(self, number):
"""
@param number: the track number, 1-based
@type number: int
@returns: the end of the given track number, in CD frames
@rtype: int
"""
return self.tracks[number - 1].end
def getTrackLength(self, number):
"""
@param number: the track number, 1-based
@type number: int
@returns: the length of the given track number, in CD frames
@rtype: int
"""
track = self.tracks[number - 1]
return track.end - track.start + 1
def getAudioTracks(self):
"""
@returns: the number of audio tracks on the CD
@rtype: int
"""
return len([t for t in self.tracks if t.audio])
def _cddbSum(self, i):
@@ -76,6 +120,12 @@ class TOC:
return ret
def getCDDBDiscId(self):
"""
Calculate the CDDB disc ID.
@rtype: str
@returns: the 8-character hexadecimal disc ID
"""
# cddb disc id takes into account data tracks
# last byte is the number of tracks on the CD
n = 0
@@ -99,8 +149,13 @@ class TOC:
def getAccurateRipIds(self):
"""
@rtype: two-tuple of (str, str)
Calculate the two AccurateRip ID's.
@returns: the two 8-character hexadecimal disc ID's
@rtype: tuple of (str, str)
"""
# AccurateRip does not take into account data tracks,
# but does count the data track to determine the leadout offset
discId1 = 0
discId2 = 0
@@ -124,7 +179,12 @@ class TOC:
return ("%08x" % discId1, "%08x" % discId2)
def getAccurateRipURL(self):
# does not count data tracks
"""
Return the full AccurateRip URL.
@returns: the AccurateRip URL
@rtype: str
"""
discId1, discId2 = self.getAccurateRipIds()
return "http://www.accuraterip.com/accuraterip/" \