Archivio dei tag broadcast

Automatic check for unbalanced audio, or bad level

I have a radio show and I’m also one of the people much involved in all the tech-related stuff in the Radio. There are multiple system that automatically, and manually, record the podcast of a show, upload it online and similar stuff.

Sometimes the recorded podcasts have some problems, typically:

  • The audio of the left channel is unbalanced with the respect of the right channel, or viceversa (Unbalanced volume level)
  • The audio is too high
  • The audio is too low

It may happen because the analogic audio system, before the audio card sampler, was misconfigured, or someone move some knobs, or maybe the cable are too long and of bad quality. Anyway, when this happen, there is no way I can understand it other than listen to all the recorded files. 

We are around 40 speakers, we broadcast liver from 8:00 to 24:00… it’s not something that a human want (and can) do. So for this type of problem computer systems is the way. I need

something that automatically can understand if a file is unbalanced, too high or too low in volume

I think that Linux is a super operating system and it’s full of library, tool, script and community that can help you find the right solution, but sometimes it’s not so simple. The siwss-knife I was looking for is called sox. Sox is a command line tool that can do tons of stuff (see here for the documentation). What I used for this is the stats option

sox FILE_NAME.mp3 -n stats

stats returns a lot of info, and what I was looking at was the RMS db level, global and for each channel (left right). To filter out these result we can use a simple grep command:

sox FILE_NAME.mp3 -n stats | grep 'RMS lev dB'

And with some ‘magic’ get the numeric info about TOTAL level, LEFT and RIGHT level:

LINE=$(sox FILE_NAME.mp3 -n stats | grep 'RMS lev dB')

TOTAL=$(echo $LINE | tr -s ' ' | cut -d ' ' -f 4)
LEFT=$(echo $LINE | tr -s ' ' | cut -d ' ' -f 5)
RIGHT=$(echo $LINE | tr -s ' ' | cut -d ' ' -f 6)
BAL_DIFF=$(echo "($LEFT)-($RIGHT)" | bc)

What we have done here? Saved the output of the sox command to the variable LINE:

LINE=$(sox FILE_NAME.mp3 -n stats | grep 'RMS lev dB')

and then we’ve parsed it 3 times:

TOTAL=$(echo $LINE | tr -s ' ' | cut -d ' ' -f 4)
LEFT=$(echo $LINE | tr -s ' ' | cut -d ' ' -f 5)
RIGHT=$(echo $LINE | tr -s ' ' | cut -d ' ' -f 6)

and stored the LEFT/RIGHT difference to a variable BAL_DIFF

BAL_DIFF=$(echo "($LEFT)-($RIGHT)" | bc)

from now on what you need to do with these value is up to you, you can check if values are less then a threshold and send an email, store the value somewhere, push an alert.