Let's get something out of the way first.
You don't need to know how to solder. You don't need a Eurorack case, a Moog Sub37, a vintage Roland SH-101 in powder blue, or a room full of patch cables that cost more than a semester of community college. You don't need to have grown up in Düsseldorf or spent three years as Giorgio Moroder's assistant or been in a Brooklyn loft in 1983 with a beatbox and a Roland TR-808 that everyone thought sounded like a broken drum set.
What you need is curiosity about sound and the willingness to feel like an idiot for about two hours while you figure out why it makes noise at all.
Everything else follows from that.
What a Synthesizer Actually Is
Before you build one, you should know what you're building. Not the marketing version — the actual thing.
A synthesizer is a machine for making sound from electricity. That's it. The complexity people associate with synthesizers — the patch cables, the knobs, the modular systems that cost more than a car — is all in service of that one idea: take electrical signals and shape them until they make the sound you want.
Sound is vibration. Vibration is waves. Waves have a few properties that matter: frequency (how fast they oscillate, which we hear as pitch), amplitude (how large they are, which we hear as volume), and shape (which we hear as timbre — the difference between a piano and a violin playing the same note).
A synthesizer generates waves and then gives you tools to manipulate those three properties. That's the whole thing. Kraftwerk understood this. Moroder understood this. The engineers at Moog understood this. The kid in 1982 who figured out that an 808's bass drum could be tuned to a pitch and used as a bass line understood this, and that understanding changed popular music permanently.
You're going to understand it too.
The Building Blocks
Every synthesizer, from a 1970s Moog modular the size of a refrigerator to a softsynth plugin running in your DAW to the thing we're about to build, has the same core architecture. Learn these four pieces and you understand every synthesizer ever made.
1. Oscillator (VCO)
The oscillator generates the raw wave. This is the sound source — the thing that actually vibrates. It produces a basic waveform at a given frequency. The most common shapes:
Sine wave — Pure tone, single frequency, no harmonics. What a tuning fork makes. Clean, simple, slightly boring. What Giorgio Moroder's sequenced basslines were built from, layered and processed until they weren't boring at all.
Square wave — Flips between full-on and full-off. Rich in odd harmonics. Has that hollow, reedy quality. Lots of early video game music. Lots of post-punk. The Minimoog's oscillators could do this. So can yours.
Sawtooth wave — Ramps up, drops instantly, ramps up again. The most harmonically rich of the basic shapes — full of both odd and even harmonics. This is the wave that makes synthesizers sound like synthesizers. The Kraftwerk lead sounds. The Moroder strings. The MGMT arpeggios on Time to Pretend that sound like the 80s dreamed them and 2007 made them real.
Triangle wave — Somewhere between sine and square. Softer harmonics, gentler sound.
2. Filter (VCF)
The filter is where personality lives. You take the harmonically rich oscillator output and cut or boost specific frequency ranges. The most important filter in synthesis history is the low-pass filter, which lets low frequencies through and cuts high ones. Sweep a low-pass filter up and you get that classic synthesizer "open up" sound — what the 303 bassline does, what the acid house producers discovered could make people lose their minds at 130 BPM.
The filter has a cutoff frequency (where it starts cutting) and a resonance control (how much it emphasizes the frequencies right at the cutoff, which at high settings creates that characteristic synth squeal).
3. Amplifier (VCA)
Controls volume over time. Not much more to it — it's the gain stage. The interesting part is what controls the amplifier.
4. Envelope (ADSR)
The envelope is time. It's the shape of a sound from start to finish.
Attack — How long it takes to reach full volume after a note is triggered. Decay — How long it takes to fall from the attack peak to the sustain level. Sustain — The level it holds while the note is held. Release — How long it takes to fade after the note is released.
A piano has a fast attack, fast decay, no sustain, and a medium release. A string section has a slow attack, slow decay, high sustain, and a slow release. Change those four numbers and you change the entire character of a sound. The 808's iconic kick drum is a sine wave with a very fast attack, instant decay, no sustain, and no release — plus a pitch envelope that drops fast. That's the whole secret. That's what changed hip hop.
ADSR Visualization:
Volume
|
| /\
| / \
| / \______
| / \
| / \
|/ \___
+--A---D---S--------R-----> Time
Let's Build One
Here's where we stop talking about synthesizers and start building one. In Python, in your browser, with no hardware required. The first version will make sound. The second version will make something you might actually want to listen to.
Step 1: The Oscillator in Python
import numpy as np
import sounddevice as sd
# Sample rate: 44100 Hz is CD quality
# This is how many samples per second we generate
SAMPLE_RATE = 44100
DURATION = 2.0 # seconds
def oscillator(frequency, waveform='sine', duration=DURATION, sample_rate=SAMPLE_RATE):
"""
Generate a basic waveform.
frequency: pitch in Hz (440 = A4, concert pitch)
waveform: 'sine', 'square', 'sawtooth', 'triangle'
"""
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
if waveform == 'sine':
wave = np.sin(2 * np.pi * frequency * t)
elif waveform == 'square':
wave = np.sign(np.sin(2 * np.pi * frequency * t))
elif waveform == 'sawtooth':
# Sawtooth: ramps from -1 to 1 each cycle
wave = 2 * (t * frequency - np.floor(t * frequency + 0.5))
elif waveform == 'triangle':
wave = 2 * np.abs(2 * (t * frequency - np.floor(t * frequency + 0.5))) - 1
return wave.astype(np.float32)
# Make some noise
wave = oscillator(440, waveform='sawtooth')
sd.play(wave, SAMPLE_RATE)
sd.wait()
Install the dependencies first: