ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-CD/lib/Convert/CD/Track.pm
Revision: 1.2
Committed: Tue Jun 10 20:47:15 2003 UTC (23 years, 3 months ago) by root
Branch: MAIN
Changes since 1.1: +13 -11 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     Convert::CD::Track - desribe track layout and offer data access methods.
4    
5     =head1 SYNOPSIS
6    
7     use Convert::CD::Track;
8    
9     # to be done
10    
11     =head1 DESCRIPTION
12    
13     Kidding?
14    
15     =head2 EXPORTED CONSTANTS
16    
17     FLAG_DCP digital copy permitted
18     FLAG_FCA four channel audio
19     FLAG_PRE track is pre-emphasized
20     FLAG_SCMS protected by serial copy management system (see DCP)
21     FLAG_DATA disk is data track (automatically set for MODE1)
22    
23     MODE_AUDIO
24     MODE_CDG CD+G (Karaoke)
25 root 1.2 MODE_MODE0 MODE 0 (unused, 2336 bps)
26     MODE_MODE1 MODE 1 (standard yellow book, 2048 bps)
27     MODE_MODE2 MODe 2 (CD/XA, 2336 bps)
28 root 1.1 MODE_CDI CD-i, CD Interactive
29    
30     =cut
31    
32     package Convert::CD::Track;
33    
34     use POSIX qw(ceil);
35     use Carp;
36    
37     use base Exporter;
38    
39     $VERSION = 0.01;
40    
41     @EXPORT = qw(
42     FLAG_DCP FLAG_FCA FLAG_PRE FLAG_SCMS FLAG_DATA
43     MODE_AUDIO MODE_CDG MODE_MODE1 MODE_MODE2 MODE_CDI
44     );
45    
46 root 1.2 sub FLAG_DCP () { 0x0001 }
47     sub FLAG_FCA () { 0x0002 }
48     sub FLAG_PRE () { 0x0004 }
49     sub FLAG_DATA () { 0x0008 }
50     sub FLAG_SCMS () { 0x1000 }
51 root 1.1
52     sub MODE_AUDIO () { 0x0001 }
53 root 1.2 sub MODE_CDG () { 0x0002 }
54     sub MODE_MODE1 () { 0x0004 }
55     sub MODE_MODE2 () { 0x0008 }
56     sub MODE_CDI () { 0x0010 }
57     sub MODE_MODE0 () { 0x1000 }
58 root 1.1
59     =head2 Convert::CD::Track METHODS
60    
61     This class is used to repesent single track objects.
62    
63     =over 4
64    
65     =item new param => value...
66    
67     Create a new track object. Parameters that are not given are usually
68     guess, depending on the mode and other parameters.
69    
70     Parameters:
71    
72     path the file that contains the track
73     offset the offste within the file that contains the first sector
74     (may be negative)
75     rawsize the raw size (in bytes) of the track. (guessed if missing)
76     mode a mode string (MODE1, MODE2, AUDIO, CDI, CDG....)
77     datasize size of the data part of the sector (e.g. 2048).
78     secsize size of a sector in disk image
79     index an array of index times (0 is pregap start, 1 is track start)
80    
81     =cut
82    
83     sub new {
84     my $class = shift;
85     my $self = bless {
86     @_,
87     }, $class;
88    
89     $self->{rawsize} ||= (-s $self->{path}) - $self->{offset};
90    
91     $self->{flags} ||= FLAG_DATA if $self->{mode} == MODE_MODE1;
92     $self->{datasize} ||= $self->{mode} == MODE_MODE1 ? 2048
93     : $self->{mode} == MODE_MODE2 ? 2336
94     : $self->{mode} == MODE_AUDIO ? 2352
95     : $self->{secsize};
96    
97     $self->{datasize} = $self->{secsize}
98     if $self->{secsize} < $self->{datasize};
99    
100     $self;
101     }
102    
103     # create and cache a filehandle of the given mode
104     sub fh {
105     my ($self, $mode) = @_;
106    
107     $self->{fh}{$mode} ||= do {
108     open my $fh, $mode, $self->{path}
109     or croak "$self->{path}: $!";
110     binmode $fh; # *seufz*
111     $fh;
112     };
113     }
114    
115     =item $track->read ($offset, $length)
116    
117     Reads and returns a part of the track. C<$offset> should be a multiple of
118     the datasize.
119    
120     =cut
121    
122     sub read {
123     my ($self, $offset, $length) = @_;
124     my $buf;
125    
126     my $fh = $self->fh ("<");
127    
128     $offset = $offset / $self->{secsize} * $self->{secsize};
129    
130     while ($length > 0) {
131     sysseek $fh, $self->{offset} + $offset, 0
132     or croak "seek($self->{path}): $!";
133     sysread $fh, $buf, ($length < $self->{datasize} ? $length : $self->{datasize}), length $buf
134     or croak "read($self->{path}): $!";
135    
136     $length -= $self->{datasize};
137     $offset += $self->{secsize};
138     }
139    
140     $buf;
141     }
142    
143     =item $track->size
144    
145     Returns the (cooked) size of the track in bytes, i.e. logical size of the
146     track without any ECC etc. information.
147    
148     =cut
149    
150     sub size {
151     my ($self) = @_;
152    
153     ceil ($self->{rawsize} / $self->{secsize}) * $self->{datasize};
154     }
155    
156     =item $track->as_string
157    
158     Returns a single-line, textual description of the track.
159    
160     =cut
161    
162     sub as_string {
163     my ($self) = @_;
164     my %data = %$self;
165    
166     $data{index} = "<" . (join "|", @{$data{index}}) .">";
167    
168     sprintf "%s %08x+%08x %s/%d (%s)",
169     delete @data{qw(path offset rawsize mode secsize)},
170     join " ", %data;
171     }
172    
173     =item $track->to_msf ($offset)
174    
175     Converts the given byte offste into M:S:F format.
176    
177     =cut
178    
179     sub to_msf {
180     my ($self, $offset) = @_;
181    
182     my $frame = $offset / $self->{datasize};
183    
184     sprintf "%02d:%02d:%02d", $frame / (60 * 75),
185     $frame / 75 % 60,
186     $frame % 75;
187     }
188    
189     1;
190    
191     =back
192    
193     =head1 AUTHOR
194    
195     Marc Lehmann <pcg@goof.com>
196    
197     =cut
198