Synthesizing simple chords with sox

SoX can do almost anything with audio files — including synthesize audio from scratch. Unfortunately, SoX’s syntax is more than a bit hard to follow, and the manual page isn’t the most clear. But there is one example in the manual that gives a glimpse of what SoX can do:

play -n synth pl G2 pl B2 pl D3 pl G3 pl D4 pl G4 \ 
     delay 0 .05 .1 .15 .2 .25 remix - fade 0 4 .1 norm -1

While it plays a nice chord, it’s not obvious how to make audio files from this process. I have a project coming up that needs a few simple guitar chords, and with much trial and error I got SoX to spit out audio files. Here’s what I keyed into the shell:

cat guitar.txt | while read chord foo first third fifth
do
  echo "$chord" :
  sox -n \ 
    -r 16000 -b 16 "chord-${chord}.wav" \
    synth pl "$first" pl "$third" pl "$fifth" \
    delay 0 .05 .1 \ 
    remix - \ 
    fade 0 1 .095 \ 
    norm -1
done

with these lines in the file “guitar.txt”

G   :  G2  B2  D3
C   :  C3  E3  G4
D   :  D3  F#4 A3
F   :  F3  A3  C4
A   :  A3  C#4 E4
E   :  E2  G#3 B3
Em  :  E2  G3  B3

How the SoX command line breaks down:

    • -n —use no input file: SoX is going to generate the audio itself
    • -r 16000 -b 16 “chord-${chord}.wav” — with a sample rate of 16 kHz and 16-bits per sample, write to the output file “chord-….wav”
    • synth pl “$first” pl “$third” pl “$fifth” —synthesize three plucked tones read from the file
    • delay 0 .05 .1 —delay the second tone 0.05 s after the first and likewise the third after the second. This simulates the striking of guitar strings very slightly apart.
    • remix – —mix the tones in an internal pipe to the output
    • fade 0 1 .095 —fade the audio smoothly down to nothing in 1 s
    • norm -1 —normalize the volume to -1 dB.

The chords don’t sound great: they’re played on only three strings, so they sound very sparse. As my application will be playing these through a tiny MEMS speaker, I don’t think anyone will notice.

Update: well, now I know how to do it, why not do all 36 autoharp strings and make the “magic ensues” sound of just about every TV show of my childhood?

Glissando up:

sox -n -r 48000 -b 16 autoharp-up.wav synth pl "F2" pl "G2" pl "C3" pl "D3" pl "E3" pl "F3" pl "F#3" pl "G3" pl "A3" pl "A#3" pl "B3" pl "C4" pl "C#4" pl "D4" pl "D#4" pl "E4" pl "F4" pl "F#4" pl "G4" pl "G#4" pl "A4" pl "A#4" pl "B4" pl "C5" pl "C#5" pl "D5" pl "D#5" pl "E5" pl "F5" pl "F#5" pl "G5" pl "G#5" pl "A5" pl "A#5" pl "B5" pl "C6" delay 0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.25 1.3 1.35 1.4 1.45 1.5 1.55 1.6 1.65 1.7 1.75 remix - fade 0 6 .1 norm -1

Glissando down:

sox -n -r 48000 -b 16 autoharp-down.wav synth pl "C6" pl "B5" pl "A#5" pl "A5" pl "G#5" pl "G5" pl "F#5" pl "F5" pl "E5" pl "D#5" pl "D5" pl "C#5" pl "C5" pl "B4" pl "A#4" pl "A4" pl "G#4" pl "G4" pl "F#4" pl "F4" pl "E4" pl "D#4" pl "D4" pl "C#4" pl "C4" pl "B3" pl "A#3" pl "A3" pl "G3" pl "F#3" pl "F3" pl "E3" pl "D3" pl "C3" pl "G2" pl "F2" delay 0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.25 1.3 1.35 1.4 1.45 1.5 1.55 1.6 1.65 1.7 1.75 remix - fade 0 6 .1 norm -1

Could maybe use some reverb in there for the ultimate nostalgic effect.

 

making an hourly chime with cron

I wanted to have a “Hey, be here now!” ping throughout the working day. Something loud enough to hear, but not irritating.

Doing this with cron was harder than you might expect. It seems that sound is typically part of the X11 display infrastructure, so you need to give the command permission to make a noise on this particular machine’s display. Here’s the crontab line I came up with:

# m h    dom mon dow   command
  0 9-17 *   *   1-5   export DISPLAY=:0 && /usr/bin/play -q /home/scruss/sounds/ting/ting.wav

That translates as: at 0 minutes past the hours of 09:00 to 17:00 on any weekday (day of week = 1-5, and we don’t care about day of month or which month it is), execute the command play (part of the sox package) with no text output (-q). cron needs environment variables like DISPLAY set, and prefers full command paths. It may trigger a second or so after the turn of the hour; this is good enough for me.

As for the alert, I wanted something distinctive — percussive, short, bright — but with a tiny bit of modulation to stop it sounding like a bland computer-generated sine wave. This is what I made; click on the image and the sound should play or download:

ting-audacityIt’s essentially a 2093 Hz (C7) sine wave, mixed with itself frequency-modulated at 7 Hz. Why 7 Hz? Apart from sounding about right, 2093 is exactly divisible by 7, 13 & 23, so I used a factor for neatness.

There was some later messing about in Audacity (mostly fades and length edits; I forget exactly what). The two components were generated using sox:

sox -n ting-plain.wav synth 1 sine C7 fade l 0 1 1
 sox -n ting-vibrato.wav synth 1 sin C7 synth 1 sine fmod 7 fade l 0 1 1

Yes, sox does have pretty horrible syntax, doesn’t it?

The frequency-modulated one seems to be pretty close to the final result. It would be less time spent trying to save time …

how does he do that?

Someone asked how the automatic podcast works. It’s a bit complex, and they probably will be sorry they asked.

I have all my music saved as MP3s on a server running Firefly Media Server. It stores all its information about tracks in a SQLite database, so I can very easily grab a random selection of tracks.

Since I know the name of the track and the artist from the Firefly database, I have a selection of script lines that I can feed to flite, a very simple speech synthesizer. Each of these spoken lines is stored as as wav file, and then each candidate MP3 is converted to wav, and the whole mess is joined together using SoX. SoX also created the nifty (well, I think so) intro and outro sweeps.

The huge wav file of the whole show is converted to MP3 using LAME and uploaded to my webhost with scp. All of this process is done by one Perl script – it also creates the web page, the RSS feed, and even logs the tracks on Last.fm.

Couldn’t be simpler.

clicking like the trilobite

clicks in my H120 recording
Darn it, but my iRiver, with this recent firmware upgrade, now records a click about every minute it records. See the regular peaks? It hasn’t completely ruined my recording of Of Montreal, but it hasn’t helped.

(and apologies for the relatively huge file size of the image; I’m just learning my mac-fu.)

and I thought that it’d hosed the recording of the encore by killing the wav file header. But some digging with sox parameters fixed it:

sox -V -t .raw -s -w -c 2 -r44100  broken.wav fixed.wav