ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/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

# Content
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 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 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 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
52 sub MODE_AUDIO () { 0x0001 }
53 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
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