use -V0 --vbr-new by default; add -O option
[soepkiptng.git] / raw2flac
blob5fb2d3a0e47b70e6652a2a2f0566c40a9f2c6712
1 #!/usr/bin/perl -w
3 ############################################################################
4 # soepkiptng (c) copyright 2000 Eric Lammerts <eric@lammerts.org>.
5 ############################################################################
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # A copy of the GNU General Public License is available on the World Wide Web
17 # at `http://www.gnu.org/copyleft/gpl.html'. You can also obtain it by
18 # writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 # Boston, MA 02111-1307, USA.
20 ############################################################################
22 my $progdir;
23 BEGIN {
24 use Cwd qw'cwd abs_path';
26 # find program directory
27 $_ = $0;
28 while(-l) {
29 my $l = readlink or die "readlink $_: $!\n";
30 if($l =~ m|^/|) { $_ = $l; } else { s|[^/]*$|/$l|; }
32 m|(.*)/| or die;
33 $progdir = abs_path($1);
35 unshift @INC, "$progdir/lib";
37 use DBI;
38 use Digest::MD5;
39 use Getopt::Std;
41 require "$progdir/soepkiptng.lib";
43 our ($opt_d, $opt_v, $opt_c, $opt_h, $opt_s);
44 getopts('dvc:hs');
46 $opt_h and die <<EOF;
47 usage: raw2flac [-dvsh] [-c configfile] file.raw...
49 options:
50 -d : delete original after successful compression
51 -v : verbose operation
52 -c configfile : SoepkipTNG configfile
53 -h : print this help text
54 -s : put output files in current directory
55 EOF
57 my %conf;
58 read_configfile(\%conf, $opt_c);
60 $ENV{PATH} = "$progdir/bin:$ENV{PATH}";
61 $cwd = cwd;
63 @flac_stdin = qw'flac -s -8 --endian=little --channels=2 --bps=16
64 --sample-rate=44100 --sign=signed --force-raw-format';
65 $flacd_stdin = 'flac -sdc --endian=little --sign=signed --force-raw-format -';
67 sub convert_dir($);
68 sub convert_raw($);
70 $dbh = connect_to_db(\%conf);
72 sub cleanup {
73 unlink $tmpfile or warn "$tmpfile: $!\n";
74 exit 1;
77 $SIG{'INT'} = \&cleanup;
78 $SIG{'QUIT'} = \&cleanup;
79 $SIG{'TERM'} = \&cleanup;
82 foreach (@ARGV) {
83 if(-d $_) {
84 convert_dir($_);
85 } else {
86 convert_raw($_);
91 sub convert_dir($) {
92 my ($wdir) = @_;
94 print "Scanning for .raw files in $wdir\n" if $opt_v;
96 opendir WDIR,$wdir or die "Can not open directory $wdir: $!\n";
97 my @files = sort readdir WDIR;
98 closedir WDIR;
100 foreach (@files) {
101 next if $_ eq "." || $_ eq "..";
102 if(/\.raw$/i) {
103 convert_raw("$wdir/$_");
104 # warn "test: $wdir/$_\n";
105 } elsif(-d "$wdir/$_") {
106 convert_dir("$wdir/$_");
111 sub convert_raw($) {
112 my ($rawfile) = @_;
113 my (@t, $t);
115 if($rawfile !~ m|^/|) { $rawfile = "$cwd/$rawfile"; }
116 $rawfile =~ s!(^|/)(\./)+!$1!g;
118 (my $qfile = $rawfile) =~ s/(.*)\.\w+?$/$1.%/;
119 $qfile =~ s~^(.*/)?(.*)~abs_path($1 || ".") . "/$2"~e;
120 my $q = "SELECT title,artist.name,album.name,track" .
121 " FROM song,artist,album" .
122 " WHERE song.artist_id=artist.id AND song.album_id=album.id" .
123 " AND present AND filename LIKE ?";
124 $sth = $dbh->prepare($q);
125 $sth->execute($qfile)
126 or die "can't do sql command: " . $dbh->errstr;
128 my ($ti, $ar, $al, $tr);
129 ($ti, $ar, $al, $tr) = $sth->fetchrow_array or do {
130 $qfile =~ s|.*/|%/|;
131 $sth->execute($qfile)
132 or die "can't do sql command: " . $dbh->errstr;
134 ($ti, $ar, $al, $tr) = $sth->fetchrow_array or do {
135 warn "$rawfile: not found in dbase\n";
139 @t = times;
140 $t = $t[0] + $t[1] + $t[2] + $t[3];
142 print "\nPacking file $rawfile\n" if $opt_v;
143 my $flacfile = $rawfile;
144 $flacfile =~ s/\.raw$/.flac/i;
145 if($opt_s) { $flacfile =~ s|.*/||; }
147 if(-e $flacfile) {
148 warn "$flacfile: file exists\n";
149 return;
151 $tmpfile = "$flacfile.tmp";
153 my @flacargs = ();
154 if($ti) { push @flacargs, "-Ttitle=$ti"; print "* title=$ti\n" if $opt_v; }
155 if($ar) { push @flacargs, "-Tartist=$ar"; print "* artist=$ar\n" if $opt_v; }
156 if($al) { push @flacargs, "-Talbum=$al"; print "* album=$al\n" if $opt_v; }
157 if($tr) { push @flacargs, "-Ttracknumber=$tr"; print "* track=$tr\n" if $opt_v; }
159 open IN, $rawfile or do {
160 warn "$rawfile: $!\n";
161 return;
163 if(open(OUT, "|-") == 0) {
164 exec @flac_stdin, @flacargs, "-o$tmpfile", "-";
165 die join(" ", @flac_stdin, @flacargs) . " -o$tmpfile -: $!\n";
168 my $ctx = Digest::MD5->new;
169 while(read IN, $buf, 4096) {
170 $ctx->add($buf);
171 print OUT $buf or die;
173 close IN;
174 close OUT or die;
175 $digest = $ctx->digest;
177 @t = times;
178 $t = $t[0] + $t[1] + $t[2] + $t[3] - $t;
180 print "checking $tmpfile...\n" if $opt_v;
182 open STDIN, $tmpfile or die "$tmpfile: $!\n";
183 open IN, "$flacd_stdin|";
184 while(read IN, $buf, 4096) {
185 $ctx->add($buf);
187 close IN;
188 $digest2 = $ctx->digest;
190 if($digest eq $digest2) {
191 if(rename $tmpfile, "$flacfile") {
192 printf "$rawfile: compression done (%d%% left; %dm%02ds)\n",
193 100.0 * (-s $flacfile) / (-s $rawfile),
194 $t / 60, $t % 60;
195 if($opt_d) {
196 print "removing $rawfile\n" if $opt_v;
197 unlink "$rawfile" or warn "unlink $rawfile: $!\n";
199 } else {
200 warn "rename $tmpfile -> $flacfile: $!\n";
201 unlink $tmpfile or die "unlink $tmpfile: $!\n";
202 exit 1;
204 } else {
205 warn "$tmpfile: md5 mismatch\n";
206 unlink $tmpfile or die "unlink $tmpfile: $!\n";
207 exit 1;