* morituri/image/image.py:
Refactor to use TOC class. * morituri/image/toc.py: Fully document.
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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/" \
|
||||
|
||||
Reference in New Issue
Block a user