ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-CD/lib/Convert/CD/Cue.pm
Revision: 1.10
Committed: Thu Mar 3 17:49:58 2005 UTC (21 years, 6 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Convert::CD::Cue - import/export .bin/.cue files.
4
5 =head1 SYNOPSIS
6
7 use Convert::CD::Cue;
8
9 # to be done
10
11 =head1 DESCRIPTION
12
13 Parse/Write .cue files.
14
15 =head2 Convert:CD::Cue METHODS
16
17 This class represents a .bin/.cue file combination.
18
19 =over 4
20
21 =cut
22
23 package Convert::CD::Cue;
24
25 $VERSION = 0.01;
26
27 use Carp;
28
29 use Convert::CD::Track;
30
31 use base Convert::CD::TOCFile;
32
33 =item new param => value...
34
35 Create a new Convert::CD::Cue object.
36
37 Parameters:
38
39 path the base image filename
40 tocpath the (optional) path of the tocfile
41
42 =cut
43
44 sub new {
45 my $class = shift;
46 my $self = bless { @_, }, $class;
47 exists $self->{tocpath} or $self->{tocpath} = $self->find_tocfile ("cue", "CUE", "Cue");
48 $self;
49 }
50
51 sub _read {
52 my ($self, $cd) = @_;
53
54 defined $self->{tocpath}
55 or croak "no tocpath specified and/or no .cue found";
56
57 open my $cue, "<", $self->{tocpath}
58 or croak "$self->{tocpath}: $!";
59
60 my @tracks; # perliminary track data
61 my $file;
62 my $track;
63
64 # assumption #1: these thingies are line-based
65 while (<$cue>) {
66 s/[\015\012]+$//;
67 # assumption #2, leading whitespace don't matter much
68 # assumption #3, case? what case?
69 if (/\S*FILE \"?(.*?)\"? (\S+)$/i) {
70 my ($path, $type) = ($1, $2);
71 if (-e $path) {
72 $file = $path;
73 } else {
74 my $name = $path; $name =~ s/^.*[\/\\]//;
75 if (-e $name) {
76 $file = $name;
77 } elsif (-e lc $name) {
78 $file = lc $name;
79 } else {
80 $file = $self->{path};
81 }
82 warn "\"$path\" not found, using \"$file\" instead\n";
83 }
84
85 } elsif (/\S*TRACK (\d+) (\S+)/i) {
86 my ($idx, $mode) = ($1, $2);
87 my $secsize = 2352;
88
89 $secsize = $1 if $mode =~ s/\/(\d+)$//; # MODE2/1234 => MODE2
90
91 $mode = MODE_AUDIO if $mode eq "AUDIO";
92 $mode = MODE_MODE1 if $mode eq "MODE1";
93 $mode = MODE_MODE2 if $mode eq "MODE2";
94 $mode = MODE_CDI if $mode eq "CDI";
95 $mode = MODE_CDG if $mode eq "CDG";
96
97 if ($mode == 0) {
98 warn "unrecognized mode '$mode', using MODE2 instead\n";
99 $mode = MODE_MODE2;
100 }
101
102 $secsize = 2448 if $mode == MODE_CDG;
103
104 $track = $tracks[$idx - 1] = {};
105
106 $track->{path} = $file;
107 $track->{mode} = $mode;
108 $track->{secsize} = $secsize;
109
110 } elsif (/\S*INDEX (\d+) ([0-9:]+)/i) {
111 my ($idx, $time) = ($1, $self->parse_msf ($2));
112
113 $track->{index}[$idx] = $time;
114 $track->{offset} = $time * $track->{secsize} if $idx == 1;
115
116 } elsif (/\S*TITLE "((?:[^"\\]+|\\.)*)"/i) {
117 $track->{title} = $1;
118
119 } elsif (/\S*PERFORMER "((?:[^"\\]+|\\.)*)"/i) {
120 $track->{performer} = $1;
121
122 } elsif (/\S*PREGAP ([0-9:]+)/i) {
123 $track->{pregap} = $self->parse_msf ($1);
124
125 } elsif (/\S*POSTGAP ([0-9:]+)/i) {
126 $track->{postgap} = $self->parse_msf ($1);
127
128 # need to parse FLAGS
129 } else {
130 warn "unknown .cue directive skipped: $_";
131 }
132 }
133
134 # now go through the tracks array
135 my $prev = undef;
136 for (@tracks) {
137 next unless $_;
138 if ($prev && $prev->{offset} <= $_->{offset}) {
139 $prev->{rawsize} = $_->{offset} - $prev->{offset};
140 }
141 $prev = $_;
142 }
143
144 for (@tracks) {
145 if (defined $_) {
146 $cd->append_track (%$_);
147 } else {
148 # synthesize empty track
149 $cd->append_track (size => 0, mode => "MODE1", secsize => 2048);
150 }
151 }
152 }
153
154 #sub _write {
155 # my ($self, $cd) = @_;
156 #}
157
158 1;
159
160 =back
161
162 =head1 AUTHOR
163
164 Marc Lehmann <schmorp@schmorp.de>
165
166 =cut
167