-
Notifications
You must be signed in to change notification settings - Fork 7
/
gwcbatch
executable file
·211 lines (145 loc) · 4.76 KB
/
gwcbatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/usr/bin/perl
# for usage instructions see below or run `perldoc gwcbatch`
use File::Basename;
sub time2sec
{
my @tm = split(/:/,shift);
my $sec = 0;
while (@tm)
{
$sec *= 60;
$sec += shift @tm;
}
return $sec;
}
#
#------
# Main
my
(
$file
,$archive
,@keep
,$sens
,@noise
);
while (@ARGV)
{
@keep = @noise = ();
$file = shift;
# test if the input is a writable file, to save the user clicking through multiple error dialogs
# (but they'll still have to do that if it is a writable file that gwc can't handle)
# it might be nice to valid other inputs, or at least check there are the right number
# but since we're making a backup it doesn't matter as much
if (-w -f $file) {
($filename,$dirs,$suffix) = fileparse($file, qr/\.[^.]*/);
($archive = $dirs . $filename . "_orig" . $suffix);
push @keep, (shift, shift);
$sens = shift;
push @noise, (shift,shift);
#convert time to seconds
@keep = map {&time2sec($_)} @keep;
@noise = map {&time2sec($_)} @noise;
# back up the file first.
# check if $archive exists first and don't overwrite it (maybe we are processing $file a second time?)
# would be better to still save a new copy, appending _1 or something
# or skip the file completely?
if (-e $archive) {
print "$archive already exists\n";
} else {
print `cp "$file" "$archive"`;
}
# Now declick and remove noise
print `gtk-wave-cleaner "$file" batch declick $sens $keep[0] $keep[1]`;
# Add extra declicking runs if you want them
#print `gtk-wave-cleaner $file batch declick $sens $keep[0] $keep[1]`;
print `gtk-wave-cleaner "$file" batch denoise $noise[0] $noise[1] $keep[0] $keep[1]`;
# truncate after cleaning in case the noise sample is from the region to truncate
# for some reason, it *sometimes* hangs when truncating
# both front and back, so do back first, then front
print `gtk-wave-cleaner "$file" batch truncate 0 $keep[1]`;
print `gtk-wave-cleaner "$file" batch truncate $keep[0] $keep[1]`;
# normalize last so it isn't affected by anything we are discarding
print `gtk-wave-cleaner "$file" batch normalize`;
}
else {
print "$file does not seem to be a writable file\n";
shift,shift,shift,shift,shift;
}
}
1;
# Documentation follows
=pod
=head1 NAME
gwcbatch - quick & dirty helper script for gwc's quick & dirty batch mode
=head1 SYNOPSIS
Usage is as follows:
gwcbatch wavfile musicStart musicEnd declickSens noiseStart noiseEnd \
[wavfile2 musicStart2 ... \]
[... \]
[wavfileN musicStartN ...]
=over
=item B<wavfile>
sound file to process (wav format)
=item B<musicStart, musicEnd>
portion of the wav file to keep. Time format is hh:mm:ss.xxx or just
ss.xxx if desired.
=item B<declickSens>
sensitivity to use for the declick process.
=item B<noiseStart, noiseEnd>
noise sample to use for the denoise process. Time format is same as
for musicStart & musicEnd
=back
=head1 DESCRIPTION
There's no doubt about it. Ripping vinyl + cleaning the sound is a
time-consuming process. gwc has some facilities for batch processing,
and this perl script helps complete the automation.
I typically record 2-4 album sides, inspect each file with gwc,
then run this script to do the declicking & denoising while I sleep.
That can take tens of minutes to several hours depending on the
condition of the vinyl, length of recordings processed, and the power
of your CPU.
Here's the process:
=over
=item *
record the album side. I do this via ecasound like this:
ecasound -i /dev/dsp -ezf -ev -t 1800 -o sideX.wav
the "-t 1800" means it'll record for 30 minutes and then stop so
there's always something at the end to chop off, and usually something
at the beginning too. But recording in this fashion means I don't
have to babysit the process.
=item *
Set up your denoise preferences
=item *
If you like to iterate for declicking, mark that checkbox in the
declick setup
=item *
load the wav file into gwc. Write down the times (to as many decimal
places as you like) for musicStart, musicEnd, noiseStart, and noiseEnd
=item *
run this script as described above
=back
This script will do the following:
=over
=item *
copy the file for archival purposes
=item *
declick using declickSens for the sensitivity
=item *
denoise using the noise sample specified in noiseStart- noiseEnd
=item *
truncate the wav file, keeping only musicStart - musicEnd
=item *
normalize the audio; amplify as much as possible without
clipping.
=back
Feel free to modify this script for your own purposes. I sometimes
add another declick after the first one just to catch the majority of
the straglers.
=head1 BUGS
It'd be even better if this thing could mark songs and create a
minimal but functional cdrdao toc file. That'll require a bit more
coding in gwc.
=head1 AUTHOR
Bill Jetzer (created July 2003)
=cut