Hammond Organ - The OG Synthesizer
Human voices are insanely complicated. For instance, here’s a waveform of of JFK saying “mister speaker”.
Your browser doesn't support HTML5 audio
Even ignoring the hilariously extreme Boston accent, there’s a lot going on here. You get a similar sense if you look at waveforms for music: that it’s this completely inscrutable thing and that instruments are magic.
While I agree that instruments are magic, there are actually some instruments that produce reasonably decipherable waveforms. The classic example (and one of my favorite instruments) is the Hammond Organ:
Hammond Organs used a pretty remarkable set of technologies to produce their sound. There were tone generators that were capable of emanating relatively clean sine wave tones, and drawbars, that the organist could flick at will, which combined these sine waves together to achieve different types of sounds. Other conventional instruments, like a flute or a clarinet, produce sound based on a fundamental frequency and a combination of “harmonics”. The Hammond Organ sought to imitate this by having each drawbar represent a different harmonic.
So let’s create a Hammond Organ!
For reference, here’s a waveform from a Hammond Organ with drawbar settings 888000000. This image is from an amazing series of articles about synthesizing audio that I highly recommend.
We can use this waveform to check our work later.
First, we’ll produce one of the most basic sounds using some C++. A4. A4’s frequency is 440hz. So we can produce a pure A4 by creating a sine wave that oscillates 440 times in one second. Let’s do it:
Great! The vector will contain 1 second’s worth of an A4 tone. But how do we listen to it!?!
Luckily, that’s not too hard. We’ll produce a wav file. Wav files are ultra basic, like a bitmap for images. They are simply a sequence of samples, uncompressed. However, they have an annoying header that you need to write, and some of the values in the header are in “little-endian”. I don’t want to get into the bothersome details at this time, but here’s the code to write out a wav file given a vector of -1.0 to 1.0 doubles. Note that there are most certainly libraries that do this and probably have awesome optimizations, but for our purposes, we’ll jerry-rig it:
Once you have that, you can call it in main like so:
And you can run the program and play the resulting file like this:
windows:
g++ .\synth.cpp;.\a.exe;(New-Object Media.Soundplayer "<path_to_file>/a4.wav").Play()
mac:
g++ .\synth.cpp;.\a.out;open "<path_to_file>/a4.wav"
You should be bathed in the glory of the dulcet tone of a pure sine wave. You probably hear some clipping noises. That’s because our waveform ends super abruptly like this:
Let’s add a simple fade in and fade out at the beginning and end of our waveform:
So now we can string notes together and there shouldn’t be any clicking:
Alright, now we’re ready to build our organ. I mentioned before that the Hammond Organ makes sound by combining sine waves which are turned on and off by drawbars. Each of these sine waves are a harmonic of the fundamental frequency (btw, the fundamental frequency is the key you’re pressing). Luckily for us, harmonics are quite easy to figure out because they are simply integer multiples of the fundamental frequency. The wiki page for Hammond Organ says:
“the drawbar marked "16′" is an octave below, and the drawbars marked "4′", "2′" and "1′" are one, two and three octaves above, respectively. The other drawbars generate various other harmonics and subharmonics of the note.”
And we can get a full understanding of the various drawbars here:
This image shows the values for each drawbar when you’re hitting the C that matches up with the 8’ drawbar. Let’s write a function to calculate these values. We’ll first create a struct to model the current settings of the drawbar. The hammond organ had 8 amplitude settings per drawbar, so we’ll emulate that:
You see all the harmonic calculation is pretty simple. There’s one odd exception, which is the 5 ⅓ drawbar. It’s the third harmonic of the 16 drawbar. This will also be a perfect fifth of the fundamental frequency, which is generally a nice tone to throw into the mix.
Since we’re just adding these values together, one thing we need to make sure is to normalize our wave before we export it to wav, otherwise we’ll get overflow and our result will sound like futuristic garbage. Here’s a normalization function:
Alright, so let’s try that out:
Ahh. As Shakespeare would say “let the sounds of music creep in our ears!”
We can also check the waveform for an 888000000 drawbar configuration:
Awesome, looks like a match.
Okay, now try this on for size:
Chilling, right?
I’ll end this article on these notes of raw terror, but I hope you had fun doing a bit of recreational programming with me!
Your browser doesn't support HTML5 audio