version/0.1
[cdimgtools.git] / raw96cdconv
blobda09eff99b694e93ed605a9a0541f290270ad8da
1 #!/usr/bin/perl -w
2 # Copyright © 2012 Géraud Meyer <graud@gmx.com>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License version 2 as
5 # published by the Free Software Foundation.
7 =encoding utf-8
9 =head1 NAME
11 raw96cdconv - converts between different formats of CD raw images
13 =head1 SYNOPSIS
15 B<raw96cdconv> S<[ B<-v> ]> S<[ B<-n> ]> S<[ B<-f> ]> S<[ B<-c> | B<-r> ]> S<[ B<-S> ]> S<[ B<-I<C>> I<ext> ]> S<[ I<files> ]>
17 =cut
19 use strict;
21 use Getopt::Long;
22 Getopt::Long::Configure('bundling', 'no_auto_abbrev', 'auto_version', 'auto_help');
24 $main::VERSION = "1.1";
26 my ($verbose, $no_act, $force, $swab, $subchan, $fullraw);
27 my $raw_sect = 2352;
28 my $raw = '.raw';
29 my $subch = '.subch';
30 my $raw96 = '';
31 die Getopt::Long::HelpMessage(128)
32 unless GetOptions(
33 'v|verbose!' => \$verbose,
34 'quiet' => sub { $verbose = 0 },
35 'n|no-act!' => \$no_act,
36 'f|force!' => \$force,
37 'S|swab!' => \$swab,
38 'sector-size=i' => \$raw_sect,
39 'iso' => sub { $raw_sect = 2048; $raw = ".iso" },
40 'c|subchan!' => \$subchan,
41 'r|fullraw!' => \$fullraw,
42 'D|raw=s' => \$raw,
43 'C|subch=s' => \$subch,
44 'R|raw96=s' => \$raw96,
46 $verbose++ if $no_act;
48 my $subch_sect = 96;
49 my $raw96_sect = $raw_sect + $subch_sect;
51 if (!@ARGV) {
52 print "Reading filenames from STDIN\n" if $verbose;
53 @ARGV = <STDIN>;
54 chomp(@ARGV);
57 my $rc = 0;
58 FILE: for (@ARGV) {
59 my $src = $_ .(($fullraw) ? $raw : $raw96);
60 my $in_sect = ($fullraw) ? $raw_sect : $raw96_sect;
61 my $dst = $_ .(($fullraw) ? $raw96 : (($subchan) ? $subch : $raw));
62 unless ($force or !-e $dst) {
63 warn "Skipping '$_' because '$dst' already exists\n" if $verbose;
64 $rc++; next FILE;
66 unless (open SRC, "<", $src) {
67 warn "ERROR Cannot open file '$src' for reading: $!\n";
68 $rc++; next FILE;
70 binmode SRC;
71 unless ($no_act or open DST, ">", $dst) {
72 warn "ERROR Cannot open file '$dst' for writing: $!\n";
73 $rc++; next FILE;
75 binmode DST unless $no_act;
76 if ($fullraw) {
77 unless (open SUBCH, "<", $_ .$subch) {
78 warn "ERROR Cannot open file '$_$subch' for reading: $!\n";
79 $rc++; next FILE;
81 binmode SUBCH;
83 my $count = 0;
84 my $buf;
85 SECTOR: while (my $n = read SRC, $buf, $in_sect) {
86 unless ($n == $in_sect) {
87 warn "ERROR Partial sector of size $n/$in_sect found in '$src'\n";
88 $rc++; last SECTOR;
90 if ($fullraw) {
91 $buf = pack '(v)*', unpack('(n)*', $buf) if ($swab);
92 print DST $buf unless $no_act;
93 my $m = read SUBCH, $buf, $subch_sect;
94 unless ($m == $subch_sect) {
95 warn "ERROR Partial sub-channel block of size $m/$subch_sect found in '$_$subch'\n";
96 $rc++; last SECTOR;
98 print DST $buf unless $no_act;
99 } elsif ($subchan) {
100 print DST substr($buf, $raw_sect) unless $no_act;
101 } else {
102 $buf = pack '(v)*', unpack('(n)*', substr($buf, 0, $raw_sect)) if ($swab);
103 print DST substr($buf, 0, $raw_sect) unless $no_act;
105 $count++;
107 print "$count sectors from '$src' written in '$dst'\n" if $verbose;
108 } continue {
109 close SRC; close DST; close SUBCH if ($fullraw);
111 print "There was $rc errors.\n" if $verbose and $rc;
112 exit 1 if $rc;
114 __END__
116 =head1 DESCRIPTION
118 C<raw96cdconv> generates a raw file by extracting raw CD sectors (made up either
119 of audio data or of raw data sectors) from a file made up of chunks containing
120 both raw data and sub-channel data (RAW+96). By default F<.raw> is appended to
121 the given file names to obtain the corresponding generated file name. If no
122 filenames are given on the command line, filenames will be read via standard
123 input.
125 It is also possible to generate a file containing only sub-channel data or to
126 re-generate the full RAW+96 file containing both the raw and the sub-channel
127 data. The default extension for sub-channel files is F<.subch>.
129 The sector size of raw data is 2352 bytes; the corresponding sub-channel data
130 is 96 bytes long, so that the full RAW+96 file is made of chunks of 2448 bytes.
132 C<raw96cdconv> also works with images containing only data sectors (2048 bytes
133 long) and sub-channel data.
135 =head1 EXAMPLE
137 For example, to generate both a raw file F<image.raw> and a sub-channel file
138 F<image.subch>:
140 raw96cdconv image
141 raw96cdconv -c image
143 To re-generate F<image> from F<image.raw> and F<image.subch>:
145 raw96cdconv -r image
147 To generate F<image.raw96> instead of F<image>:
149 raw96cdconv -R .raw96 -r image
151 To extract an iso image F<image.iso> from F<image> that contains both (error
152 corrected) data sectors and sub-channel data:
154 raw96cdconv --iso image
156 If F<image> contains the image of a CDDA, it is more appropriate to extract to
157 F<image.cdda>:
159 raw96cdconv -A .cdda image
161 To convert the extracted raw audio to WAV, you may use sox(1):
163 sox -t .cdda image.cdda image.wav
165 To convert the extracted 2352b/s raw data to ISO, you may use ccd2iso(1):
167 ccd2iso <image.raw >image.iso
169 =head1 OPTIONS
171 Options may be negated by prefixing them with "--no-" instead of "--".
173 =over 8
175 =item B<-v>, B<--verbose>
177 Verbose: print the names of the files successfully generated as well as their
178 number of sectors, print the names of the files completely skipped and at the
179 end print the number of files that caused an error.
181 =item B<-n>, B<--no-act>
183 No Action: test the reading of files and show what files would have been
184 generated.
186 =item B<-f>, B<--force>
188 Force: overwrite existing files.
190 =item B<-S>, B<--swab>
192 Swap byte: swap the byte order of the raw data; it works for both normal mode
193 (raw data extraction) and full raw data mode. Use it with readcd(1) images
194 that contain little endian audio data.
196 =item B<--sector-size>
198 By default 2352, which corresponds to audio data (or to a raw sector of any
199 data). Use 2048 for error corrected data sectors.
201 =item B<--iso>
203 Same as `B<--raw> .iso B<--sector-size> 2048'.
205 =item B<-c>, B<--subchan>
207 Sub-channel mode: generate a file containing only sub-channel data from the
208 RAW+96 data file.
210 =item B<-r>, B<--fullraw>
212 Full raw data mode: (re-)generate a RAW+96 file containing both raw and
213 sub-channel data from the raw file and the sub-channel data file.
215 =item B<-D>, B<--raw> I<ext>
217 =item B<-C>, B<--subch> I<ext>
219 =item B<-R>, B<--raw96> I<ext>
221 Extension: file name extensions; the first one is for raw files (default:
222 F<.raw>); the second one is for sub-channel data files (default: F<.subch>);
223 the third one is for RAW+96 data files (default: empty extension).
225 =back
227 =head1 ENVIRONMENT
229 No environment variables are used.
231 =head1 AUTHOR
233 G.raud <graud@gmx.com>
235 =head1 SEE ALSO
237 L<cdrdao(1)>, L<readcd(1)>, L<soxformat(7)>, L<ccd2iso(1)>
239 =cut