using sox to trim silence from the end of wav files
Well, I've hit a little speedbump here.
I've got a 60 minute wav file, with 20 minutes of silence at the end of it.
What I'd like to do is use sox to trim off the 20 minutes of silence, leaving me with the 40 minutes of sound. This has to require no user input during the operation, as it is part of a script, so I can't use anything like audacity to do this.
So, according to the sox manpage:
Code:
silence above_periods [ duration threshold[ d | % ]
[ below_periods duration
threshold[ d | % ]]
Removes silence from the beginning or end of a
sound file. Silence is anything below a speci_
fied threshold.
When trimming silence from the beginning of a
sound file, you specify a duration of audio that
is above a given silence threshold before audio
data is processed. You can also specify the
count of periods of none-silence you want to
detect before processing audio data. Specify a
period of 0 if you do not want to trim data from
the front of the sound file.
When optionally trimming silence form the end of
a sound file, you specify the duration of audio
that must be below a given threshold before
stopping to process audio data. A count of
periods that occur below the threshold may also
be specified. If this options are not specified
then data is not trimmed from the end of the
audio file. If below_periods is negative, it is
treated as a positive value and is also used to
indicate the effect should restart processing as
specified by the above_periods, making it suit_
able for removing periods of silence in the mid_
dle of a sound file.
Duration counts may be in the format of time,
hh:mm:ss.frac, or in the exact count of samples.
Threshold may be suffixed with d, or % to indi_
cated the value is in decibels or a percentage
of max value of the sample value. A value of
'0%' will look for total silence.
So what I did was:
Code:
sox dump.wav out.wav silence 0 0 2% 2 00:05:00 2%
Which, as I understand it, should remove all periods of silence of at least 5 minutes from the end of dump.wav, while leaving the beginning untouched, and put the remaining data into out.wav. Unfortunately, I must not be understanding the syntax proplerly, because the generated out.wav is a barebones 4 kb wave file...
I've done some serious googling, but no one seems to want to give any good syntax examples for this little operation. I'm starting to pull my hair out on this one :), as I've tried at least 50 different variations of the above command. :o It's getting old....
Can anyone shed light on this for me? Please?
~psi42
SOX, remove silence at the beginning and end of audio file, adjust amplitude
I found some problems with sox while trying to trim silence at the beginning and the end of audio files:
1- If the amplitude is too low, it does not seem to work
2- Trimming the end trims at the first silence
To alleviate these problems I have written and tested a Perl script that:
1- Increases the maximum signal amplitude to -0db before removing silence
2- Reverses the audio to trim the end silence, as the previous poster did
The script also sets the maximum amplitude back to -9db which is comfortable in most situations and especially telephony applications.
The key commands are:
To retrieve the maximum amplitude of the audio
sox filename -e stat 2>&1 | grep "Maximum amplitude"
To amplify (-9db here):
sox filename -v 0.125 filename
To reverse:
sox filename filename reverse
To remove silence (-40db) at the begining:
sox filename filename silence 1 0 -40d
Here is the script:
#!/usr/bin/perl -w
#
# tuneAudio.pl
#
# Adjust maximum audio volume to -9db and trim silences at the beginning and end of audio file.
# Silcences are assumed to be -40db under maximum amplitude of signal.
#
# Requires sox.
#
# Usage:
# tuneAudio.pl file [max amplitude [destination file]]
#
# - max amplitude: for the result file, default is -9db (0.125)
# - destination file: default is same as input file name
#
use strict;
my ( $file, $max, $dst ) = @ARGV;
$max = 0.125 unless defined $max; # Default to -9db ( 1 / 2 ^ 3 )
$dst = $file unless defined $dst; # Default destination file is input file
# Get maximum amplitude for input file
my $maxAmplitude = `sox $file -e stat 2>&1 | grep "^Maximum amplitude"`;
$maxAmplitude =~ s/^[^0]+//; # get the number at the end of the line
chomp( $maxAmplitude );
# Calculate multiplicator to raise amplitude to -0db
my $multiplicator = 1 / $maxAmplitude;
print "$file: max=$maxAmplitude muliplicator=$multiplicator, destination=$dst\n";
# Set maximum amplitude to -0db, this is necessary for sox silence suppression to work more reliably
system( "sox $file -v $multiplicator $dst" );
# Trim silence at the beginning
system( "sox $dst $dst silence 1 0 -40d" );
# Reverse file to trim the end
system( "sox $dst $dst reverse" );
# Trim the end
system( "sox $dst $dst silence 1 0 -40d" );
# Reverse back to original direction
system( "sox $dst $dst reverse" );
# Set to -9db
system( "sox $dst -v $max $dst" );