I recently needed to process 20+ phone audio recordings. The files are mp3 recordings in stereo, made in an environment with echoes and noise from fans/heaters.
Although I could do it easily with Tenacity I didn’t want to use a manual process, since it would take days. So I tried using FFmpeg filters and Bash scripting.
I found an FFmpeg filter called compand which lets you map an input decibel range to an output decibel range. I also used the anlmdn filter to reduce noise, and the highpass filter to help with clarity.
I ran into a couple gotchas.
-
mpv
does something special for audio playback that prevents audio from clipping.vlc
plays the file as it is. -
Because the compressor has an attack and decay (which is necessary for
things to sound good) it can cause clipping if the volume rises
sharply. Applying a
delay
parameter with half the duration of the attack length fixed this.
Here is the script:
process-audio.sh
#!/bin/bash
if [ "$#" == "0" ]; then
echo "Error: no arguments provided."
echo "Usage: $0 file1 file2 file3 ..."
echo "or $0 *.ext"
exit 1
fi
trap "exit" INT
while [ "$#" != "0" ]; do
path="${1%/*}"
file="${1##*/}"
outfile="./normalized--$file"
if [ ! -f "$outfile" ]; then
echo "Processing $1"
ffmpeg -i "$1" -v warning -ac 1 -af "compand=attacks=0.3:decays=0.3:delay=0.15:points=-80/-300|-45/-25|-27/-15|0/-12|20/-12,anlmdn=s=10,highpass=f=500" -threads 4 "$outfile"
else
echo "Skipping $1, already processed."
fi
shift
done
If this is useful to you please leave a comment or send an email, I would love to hear about it.