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