03 – Using the command line to process audio

The Command Line

Before going further, have a read of this, it talks you through some starting points to working on the commandline:

Check out the SoX pages: sox.sourceforge.net/

1 Managing the terminal

The terminal or shell can be daunting at first. There is no Graphical User Interface (GUI), rather a series of commands you type into the shell in order to perform actions. Without a GUI, you lose some of the reassuring feedback that things are happening as you need them to, but you get the far more important benefit of a huge increase in speed.

Before you can do much with the shell, you need to know how to get into specific directories in order to work.

To get into a directory with sound, if you know the full path, you can simply type

cd ~/Dropbox/sounds, hit enter.

If you have dropbox installed, then this will take you to your dropbox folder and a directory within that place called sounds.

If you don’t know the path, or can’t be bothered to type the path, you can type

cd with a space after it then drag and drop the folder in question. Press enter and the terminal will now be pointing to this particular place.

To find out which directory you are in, type pwd and hit enter.

To list the contents of a directory ls enter.

To list specific files in a directory type ls *.pdf

To open one of the pdf files type open thepdfname.pdf

Can you think of a way to list all the .wav files in a directory?

1.1 Styling the terminal

You’ll see in my own terminal I use a colour scheme I like. Set this up in Terminal:Preferences:Profiles

2 Converting audio using SoX

SoX is a brilliant command line programme for converting between file types and batch processing audio.

2.1 Converting between file types

Converting files from one file type to another is relatively simple.

sox input.wav output.mp3

Will simply convert the wav file called input.wav to the mp3 file called output.mp3

To write the converted files to another directory, first make a directory for the files to live in:

mkdir aifConversions

You’ll see that the file is placed in the directory you specified.

sox input.wav aifConversions/output.aiff

Will convert a wav file to an aiff file and place it in aifConversions folder you just made.

2.2 Converting sample rate

This again is very simply done. Call SoX, open the sound file, change the rate with -r and name the output file:

sox Blister_pack.wav -r 44.1k Blister_pack.aif

This will convert to a very low sample rate and play that converted file back for you right after:

sox Blister_pack.wav -r 8k Blister_pack_lowfi.aiff; play Blister_pack_lowfi.aiff

2.3 Converting bit depth

It’s rare that you’d want to convert bit depth on a file, but sometimes it’s necessary to scale down from 24bit to 16bit files and to do this for all assets, particularly if you’re trying to save space in a game/mobile project.

sox Blister_pack.wav -r 44.1k -b 8 Blister_pack.aif

The above will do this for an individual file, to do this with loads of files, you need to embrace batch processing.

2.4 Batch converting

Writing out the text for each command can be time consuming if you have to this for all assets, so you can use the shell to batch process your conversion processes. The basic rule for this is to ensure that you’re writing new files, rather than writing over your original, pristine sources, so I always make a new directory to write everything to:

mkdir converted

The above will make a directory called converted next to where you’re working.

Then you can run a batch process:

for all files of a certain type in the directory, do something interesting:

for f in *.wav; do sox "$f" "converted/${f%%.wav}.mp3"; done

The above will make you a bunch of mp3 files from source wav files. The quotes around the string converted/${f%%.wav}.mp3 means that we can cope with spaces in file names, but we really don’t want you to have spaces in file names so this is just an extra catch all. The complex-looking thing in the formula above is the bit attending to the file name extension. Basically, we take the first part of the file name and keep it, but swap out the file extension.

How would you batch convert sample rates? How would you batch convert bit depth? How would you batch convert sample rate, bit depth and to aif in one go?

3 Extracting information about your audio

3.1 Making spectrograms

You can render off a spectrogram of your sound file like this

sox input.wav -n spectrogram -t "top label" -c "corner label" -o inputFileName.png

e.g. sox Blister_pack.wav -n spectrogram -t "Blister Pack" -c "Blister Pack" -o Blister_Pack.png

To batch make spectrograms it’s pretty easy:

for f in *.wav; do sox "$f" -n spectrogram -t "$f" -c "$f" -o "${f%%.wav}.png"; done

3.2 dumping data from a set of files to a database/file

It’s straightforward to dump data about a bunch of audio files in a folder to a text file, this can be done with soxi.  Soxi gives you file information.

Try this to dump all the data that SoxI can get from all the .wav files in a folder:

soxi *.wav > database.csv

The > in the above command writes the data from soxi to a file called database.csv

If you just want a list of files in a folder, you can use the command line to write a list of files to a text file thus:

ls *.wav > fileList.txt

The above will write you a text file called fileList.txt with the name of all .wav files in the directory.

To make a better set out list of files, follow this tutorial by Owen Green.

If you want to dump the history of whay you’ve been typing on the commandline for future reference, you can dump it all to a text file like this:

history > ~/Documents/thingsIdidOnTheCommandLine.txt

4 Extracting short files from longer files

mkdir renders

sox Blister_pack.wav -c 2 renders/output.wav sinc 0.01k silence 1 0.01 1% trim 0 0.05 fade q 100s 0 100s : newfile : restart

The above will extract a new file when the track detects silence at 1%, it will then trim the file to make it 0.05 seconds long and apply a fade of 100 samples to the beginning and end of the file.

Joining files together (contatenation)

SoX will be very happy to add files together to make a new structure:

sox file1.wav file2.wav file3.wav output.wav

This is super useful if you want to quickly string together several files you know the names of into a single sound file.

Joining files together when you can’t be bothered to find out their names

cd into the directory where the files are

run the following to join all the sound files in-order to create a file called output.wav

sox *.wav output.wav

Joining your extracted files together using a random function

For OS X users, you’ll need to go back to brew and install the coreutils. Head to the commandline and type:

brew install coreutils

This gives you access to some useful list wrangling tools. In this case we want to play with gshuf. Use gshuf to look at all the files in a folder, generate a random list of the files which SoX will then contatenate. This is great, given the simplicity of the code used to generate output:

sox $(ls *.wav | gshuf) output.wav

Linux users probably don’t need the g in front of gshuf. Windows users, sorry, I’ve not got as far as testing this on Windows at time of writing.

You’ll notice if you keep doing the above (changing the ‘output.wav’ name each time) that the file count in the directory will keep growing and the size of each file will be bigger because it will keep on adding EVERY file in the folder to the output. It’s best then to export to a sub directory

mkdir exported
sox $(ls *.wav | gshuf) exported/output.wav

DO NOT have spaces in filenames for the above otherwise you won’t be happy.

4.5 If you’re still following me, which I doubt you are, here’s a killer bit of scripting

Ok, so you’ve automatically made a folder of separate sound files and you want to restructure them into something new and you want to do it plenty of times, well there is a way to get the command line to actually do this for you. By using the seq command, you can litterally run a function on the command line several times, and pass an argument across to change what SoX does each time the sequence is run.

Navigate to a folder of short sound files:

cd folder_of_short_sound_files

Make a directory in there called outputs:

mkdir outputs

When you’re in there, run the following line. It will create 20 random structures from the sound files that are there, place them in a folder called outputs and name each file uniquely.

for i in {1..10}; do sox $(ls *.wav | gshuf) outputs/new_$i.wav; done

The above should make you think carefully before opening your DAW, do you really need a DAW at all? Discuss….

The above line’s genius came from attending to answer 97 on this stack exchange post:

5 Joining channels together

This is obviously useful if you’ve been given 6 separate stems and you want to convert and play all stems on your own 5.1 system. The stems may be in SMTPE format (e.g L C R Ls Rs LFE ) and you might wish to add the channels together to conform to ITU film channel ordering (L R C LFE Ls Rs) for example.

sox -m left.wav right.wav centre.wav sub.wav ls.wav rs.wav ITUsurroundOrderedFile.wav

sox -m left.wav right.wav aStereoSoundFile.wav

Some other and repeated features below, continue at will

File Conversion

It’s straightforward when the code is installed. To be able to do loads of file conversion (to ogg, mp3 (via lame) and flac, you’ll need to reinstall sox with these libraries included. The simplest command then is to run this over your current SoX installation. FFMPEG can be used instead of SoX for file conversion, it’s also immensely powerful.

brew reinstall sox --with-lame --with-flac --with-libvorbis

Wav to Aif

sox input.wav output.aif

Wav to MP3

To convert to and from mp3

sox ohYeah_02.wav yes.mp3

With SoX and the lame lib included

sox infile.wav outfile.mp3

Wav to flac

You’ll need ffmpeg or to install flac, or to reinstall SoX with Flac included.

brew install flac

Then run

flac -s sourceFile.wav -o outfile.flac

Or with SoX

sox sourceFile.wav flacFile.flac

Flac to Wav

flac -s sourceFile.flac -o outfile.wav

Or with SoX

sox sourceFile.flac wavFile.wav




Earwax

sox inputfile.wav outputfile-earwaxed.wav earwax

Use with caution, only works with CD audio and stereo files and _will change the sound, worth a try though as it may work well on some material.

Data gathering

sox inputFile.wav -n stat

gives you this kind of data:

Samples read:          29106000
 Length (seconds):    330.000000
 Scaled by:         2147483647.0
 Maximum amplitude:     0.045941
 Minimum amplitude:    -0.042231
 Midline amplitude:     0.001855
 Mean    norm:          0.002434
 Mean    amplitude:    -0.000001
 RMS     amplitude:     0.004545
 Maximum delta:         0.059067
 Minimum delta:         0.000000
 Mean    delta:         0.000821
 RMS     delta:         0.002238
 Rough   frequency:         3456
 Volume adjustment:       21.767

Generating waveforms

This can be done with ffmpeg:

ffmpeg -i inputFile.wav -lavfi showwavespic=split_channels=1:s=1024x800 outputWaveform.png

More information on this feature is here:

Batch processing using FFMPEG or SOX

If you’ve been busy making loads of files with automated processes, you might want to look at all of the waveforms, or indeed do some visual sorting. When there are loads of files and you hate typing in files names, you can use batch processes. To generate waveforms for all wav files in a folder, this should help. Note you’ll need to:

mkdir waveforms

before you run this. The code is expecting a folder called waveforms to write to. Note, we’re also swapping the extension .wav for .png with the “${f/%wav/png}”, the quotes should mean that you can cope with file names with spaces, but I think spaces are best avoided in file names if possible.

for f in *.wav; do ffmpeg -i "$f" -lavfi showwavespic=split_channels=1:s=1024x800 waveforms/"${f/%wav/png}"; done

It’s pretty handy as you can check tht your fades have actually worked as you can see them. What you don’t get here is any data on the waveform however and spectrograms might be more useful to you.

To batch render spectrograms, you can use SoX or FFMPEG.  To show another way of batching, we’ll use SoX.

First

mkdir spectrogram

This will make a folder called spectrgram in the folder you’re currently working in

Now, you can run something like this

for f in *.wav; do sox "$f" -n spectrogram -t "$f" -c "$f" -o  spectrogram/"$f.png"; done

It basically looks for all the files in the folder with a .wav extension, then does the sox command giving title to the image (-t and text at bottom left -c).

It’s good, but better would be to lose the .wav extension from the file names that get rendered. So, try this;

for i in *.wav; do sox $i -n spectrogram -o spectrogram/${i%%.wav}.png; done

Starting with some batch processes using SoX

Batch convert to mp3 when you’ve got the LAME library connected with SoX:

for i in *.WAV; do sox $i exports/${i%%.wav}.mp3; done

How might you batch convert to FLAC or AIFF?

Handy starting point for writing scripts that handle multple files and generate output data

Quick crash course on getting SoX running on your windows or Os X installation;

Thanks UoW:

Here’s a way to get FFMPEG installed on windows 10

Thanks MasimMan