fix .ogg info update
[soepkiptng.git] / soepkiptng_update_gain
blobe81d4584be564ade7006104d61ed081c25691ca8
1 #!/usr/bin/perl
2 ############################################################################
3 # soepkiptng (c) copyright 2000 Eric Lammerts <eric@lammerts.org>.
4 # $Id$
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, version 2, as
8 # published by the Free Software Foundation.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # A copy of the GNU General Public License is available on the World Wide Web
16 # at `http://www.gnu.org/copyleft/gpl.html'. You can also obtain it by
17 # writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 # Boston, MA 02111-1307, USA.
19 ############################################################################
21 use Cwd 'abs_path';
22 use DBI;
23 use Getopt::Std;
26 # try with att==0
27 # try with att=1, double att until clipping=0
28 # successive approximation
30 sub clip($) {
31 my ($gain) = @_;
33 sysseek STDIN, 0, 0;
34 my $clipped = undef;
35 open M, "madplay --ignore-crc -a $gain -owav:/dev/null - 2>&1 |";
36 while(<M>) {
37 /(\d+) clipped sample/ and $clipped = $1;
39 close M;
40 $? and die "madplay failed, skipping file\n";
41 warn "trying $gain -> $clipped\n";
42 return $clipped;
45 sub doit($) {
46 my ($f) = @_;
48 warn "testing $f\n";
49 my $gain_min = -1;
50 my $gain_max = 1;
51 while(clip($gain_max) == 0) {
52 $gain_min = $gain_max;
53 $gain_max *= 2;
54 if($gain_max > 35) {
55 $dbh->do("UPDATE song SET gain=18000 WHERE filename=?", undef, $f);
56 return;
57 } elsif($gain_max > 18) {
58 $gain_max = 18;
61 if($gain_min < 0) {
62 while(clip($gain_min) > 0) {
63 if($gain_min < -175) {
64 return;
66 $gain_min *= 2;
70 while(($gain_max - $gain_min) > 0.05) {
71 $gain = ($gain_min + $gain_max) / 2;
72 if(clip($gain)) {
73 $gain_max = $gain;
74 } else {
75 $gain_min = $gain;
78 printf "%f %s\n", $gain_min, $f;
79 my $g = int($gain_min * 1000 + 0.5);
80 if($g < -32768) { $g = 32768; }
81 elsif($g > 32767) { $g = 32767; }
82 $dbh->do("UPDATE song SET gain=? WHERE filename=?", undef, $g, $f);
86 # find program directory
87 $_ = $0;
88 while(-l) {
89 my $l = readlink or die "readlink $_: $!\n";
90 if($l =~ m|^/|) { $_ = $l; } else { s|[^/]*$|/$l|; }
92 m|(.*)/|;
93 my $progdir = abs_path($1);
95 require "$progdir/soepkiptng.lib";
97 getopts('c:');
99 read_configfile(\%conf, $opt_c);
101 $| = 1;
103 $dbh = DBI->connect("DBI:$conf{db_type}:$conf{db_name}:$conf{db_host}",
104 $conf{db_user}, $conf{db_pass}) or die "can't connect to database";
106 $sth = $dbh->prepare(
107 "SELECT filename FROM song WHERE present AND gain IS NULL AND filename LIKE '/%'" .
108 "AND (encoding LIKE 'mp3%' OR encoding LIKE 'mpeg%layer%')");
109 $sth->execute();
110 while($_ = $sth->fetchrow_hashref) {
111 -e $_->{filename} or next;
112 open STDIN, $_->{filename} or do {
113 warn "$_->{filename}: $!\n";
114 next;
116 eval { doit($_->{filename}); };
117 warn $@ if $@;
118 close STDIN;