The Bass

EDM.2: waveforms, ADSR, filtering, and the low end

DnB has two load-bearing walls: drums and bass. You built the drums. Now the other half. You’ll start with a single low note and end with a filtered reese sitting under your breakbeat.

about this lesson

Repertoire: Dragonborn (Jeremy Soule, Skyrim, 2011) and Subwoofer Lullaby (C418, Minecraft, 2011). Two ends of the bass spectrum: one is power. The other is warmth.

Parallel composition: Adding a filtered bass drone under the koto. The ocean underneath the melody.

What you already know: s(), note(), stack(), setcpm(), mini-notation, .gain(), and the DnB breakbeat from EDM.1.

00The Low End

One note, all the way down

C in the first octave. A sine wave. The simplest possible bass sound.

sub bass

C2 is 65Hz. Low enough to feel. Most laptop speakers can handle it. Headphones help.

tweak it

Change c2 to c3. Then c4. Each octave doubles the frequency. C3 is 131Hz. C4 is 262Hz. The higher you go, the less you feel it and the more you hear it. Try c1 if you have headphones or a sub. That’s 33Hz. Pure floor.

octaves

An octave is a doubling of frequency. c2 = 65Hz. c3 = 131Hz. c4 = 262Hz. Same note name, different register. DnB sub bass typically lives around C2–C3.

Hold it longer: attack, decay, sustain

The default synth envelope is short; the note fades quickly. For bass, you want it to sustain.

sustained sub

Now it holds. .sustain(1) means full volume for the duration of the note. The sine just sits there, steady and heavy.

tweak it

Drop .sustain(1) to .sustain(0.3). The note dips after the attack. That’s the decay working. Useful for plucky bass, but for sub bass, keep sustain high.

A pattern in the basement

One note repeating isn’t a bassline. Two notes and a rest. Now it moves.

simple bassline

C and Eb. A minor third apart. The rests (~) give the pattern space to breathe. At 170bpm this is already bouncing.

sub bass

A sine wave below ~100Hz. Pure fundamental, no harmonics. Felt more than heard. Everything else sits on top of it. In a club, this is what makes your ribcage vibrate.

Repertoire: two ends of the bass spectrum

Skyrim — Dragonborn (Jeremy Soule, 2011). The bass in the Dragonborn theme is a choir singing low. Sustained, powerful, the floor of an orchestral mix. That’s the same principle as your sub bass: one low voice holding everything up.

bass drone exercise (inspired by Skyrim — real transcription TBD)

Now the opposite. Minecraft — Subwoofer Lullaby (C418, 2011). Soft, warm, filtered. The bass isn’t asserting power. It’s sitting underneath you like a cushion. Same waveform, different envelope, different filter:

sparse bass exercise (inspired by Minecraft — verify notes)

Same tools. .s(), .lpf(), .attack(), .sustain(). Soule makes a cathedral. C418 makes a bedroom. The difference is envelope shape and filter cutoff. That’s what you’re learning in this lesson.

01Wave Shape

Same note, different character

Swap sine for sawtooth. Same C2, completely different sound.

sine bass
sawtooth bass
square bass

Sine is smooth and round. Sawtooth is buzzy and aggressive, full of overtones. Square sits somewhere between, hollow like a clarinet. Play all three back to back. That difference is timbre.

tweak it

Try triangle too. It’s like a fatter sine. The four basic wave shapes (sine, sawtooth, square, triangle) are the building blocks of synthesis.

timbre

Same pitch, different sound. Timbre (pronounced “TAM-ber”) is what makes a guitar and a piano playing the same note sound different. In synthesis, wave shape determines timbre. More harmonics = brighter and buzzier.

rabbit hole: why waveforms sound different

Harmonics

A sine wave is a single frequency. A sawtooth contains every harmonic: the fundamental plus 2x, 3x, 4x, 5x… all stacked up, each quieter than the last. A square wave has only the odd harmonics (1x, 3x, 5x, 7x). That’s why it sounds hollow.

See it

Click a wave shape to draw it and hear a 1-second tone.

The sine is just one bump. The sawtooth ramps up and drops. All those harmonics create the sharp edge. The square jumps between two levels. The triangle climbs and descends smoothly, like a gentler sawtooth.

Harmonics table

waveharmonicscharacter
sinefundamental onlypure, round, sub bass
sawtoothall (1x, 2x, 3x, 4x…)bright, buzzy, aggressive
squareodd only (1x, 3x, 5x…)hollow, woody
triangleodd only, quietersoft, muted
rabbit hole: what harmonics actually are

The fundamental

A sine wave is a single frequency. Play C2 as a sine and that’s the fundamental: 65.4Hz, one frequency, one pitch. Nothing else in the signal. Pure tone.

Overtones

Every acoustic sound contains the fundamental plus higher frequencies at integer multiples. These are harmonics. The 2nd harmonic is 2× the fundamental (one octave above). The 3rd is 3× (an octave plus a fifth). The 4th is 4× (two octaves). And so on, stacking upward forever.

A plucked guitar string vibrates at C2 (65.4Hz), but also at 130.8Hz, 196.2Hz, 261.6Hz, and hundreds more simultaneously. The relative loudness of each harmonic is what makes a guitar sound like a guitar and not a clarinet.

Build it yourself

Toggle harmonics on and off. The canvas draws each active harmonic as a faint line and the composite (sum of all active) as a bright line. Watch how the composite shape changes as you stack harmonics.

active: 1st

Add only odd harmonics (1, 3, 5, 7) and the composite approaches a square wave. Add all of them (1, 2, 3, 4, 5, 6, 7, 8) and it approaches a sawtooth. The waveform shape IS the harmonic content. They’re two descriptions of the same thing.

Why waveforms sound different

A sine has no harmonics. Pure fundamental. A sawtooth has all harmonics (1, 2, 3, 4, 5…), each at 1/n amplitude. Buzzy and bright. A square has only odd harmonics (1, 3, 5, 7…), which gives it that hollow, clarinet-like character. A triangle also has only odd harmonics, but they fall off as 1/n² instead of 1/n, so they’re much quieter. Softer sound.

Filtering (.lpf()) removes upper harmonics. That’s why it makes a sawtooth darker: you’re peeling away the high-frequency content that made it buzzy. Push the cutoff low enough and any waveform starts to sound like a sine, because you’ve removed everything except the fundamental.

The overtone series

harmonicmultipleintervalnote (fund. = C2)
1st (fund.)unisonC2
2ndoctaveC3
3rdoctave + fifthG3
4th2 octavesC4
5th2 oct. + major 3rdE4
6th2 oct. + fifthG4
7th2 oct. + minor 7thB♭4 (approx)
8th3 octavesC5

Connection to music

Harmonics 4, 5, and 6 are C, E, and G. That’s a major triad, built into the physics of a vibrating string. Some argue this is why major chords sound “natural” or consonant: the intervals mirror the overtone series that every acoustic sound already contains. The relationship between harmonics and consonance is one of the oldest questions in music theory. No settled answer, but the pattern is hard to ignore.

02The Reese

One sawtooth is a buzz. Two is a weapon.

Play this. One sawtooth at C2.

one saw

Now two saws stacked, but the second one is slightly detuned, a quarter-tone flat.

two detuned saws

That slow, churning movement. The two frequencies are close enough to fight each other, producing a pulsing, phasing texture. More alive than a single saw.

tweak it

Change 0.15 to 0.5 for wider detune and faster beating. Try 0.05 for a tighter, slower throb. The sweet spot for a classic reese is somewhere between 0.1 and 0.3.

reese bass

Two detuned sawtooth oscillators. Named after Kevin Saunderson’s 1988 track “Just Want Another Chance” (released as Reese). The reese became a staple of jungle and DnB. Most modern bass patches start here.

rabbit hole: why detuning creates movement

Beating frequencies

When two tones are close in pitch, their peaks align and misalign at a regular rate. When peaks align: louder. When they oppose: quieter. This cycling between loud and quiet is called beating.

The beat rate equals the frequency difference. Two saws at 130Hz and 131Hz produce a 1Hz beat, one pulse per second. At 130Hz and 135Hz, the beating is 5Hz: five pulses per second, which sounds like a fast wobble.

The math

detunebeat ratecharacter
+1 Hz1 Hzslow throb, chorus-like
+3 Hz3 Hzmedium pulse, classic reese
+5 Hz5 Hzfast wobble, aggressive
+10 Hz10 Hzrough, almost dissonant

In the strudel editor above, .add(note(0.15)) adds 0.15 semitones to the pitch. At C2 (65.4Hz), that’s roughly a 0.6Hz difference: a slow, deep throb. The exact Hz depends on the base frequency, which is why the same detune amount sounds different in different octaves.

Why sawtooth specifically?

Sawtooths have the most harmonics of any basic wave shape. When two of them beat against each other, the beating happens at every harmonic simultaneously. The fundamental beats, the second harmonic beats, the third, and so on. Thick, complex movement across the whole spectrum. Two sines beating just gives you a simple volume pulse. Two saws give you the reese.

The reese as a pattern

Same two-note bassline from earlier, but with the reese instead of a bare sine.

reese bassline

Aggressive. Raw. Also way too bright. It’s eating the whole frequency spectrum.

03Filtering

Lowpass: cut everything above

A lowpass filter removes frequencies above a cutoff point. Apply one to the reese:

filtered reese

Darker. The top end is gone. .lpf(400) lets through everything below 400Hz and attenuates the rest. The reese still has movement from the detuning, but it’s tamed.

tweak it

Change 400 to 2000. Bright and aggressive again. Try 200: dark and subby, almost back to a sine. The cutoff frequency is a volume knob for brightness.

Resonance: boost the cutoff point

.lpq() adds resonance at the cutoff frequency. A boost right at the edge. Gentle warmth at low values, nasal honk at high ones.

resonant filter

Hear that acidic edge? The resonance boosts frequencies right at 600Hz. Higher Q values make the peak sharper and more aggressive. Low Q (1–3) is subtle. High Q (8+) is a statement.

tweak it

Push .lpq() up to 15 or 20. It starts to ring and whistle. That’s self-oscillation territory: the filter feeding back on itself. Useful in acid techno, dangerous in DnB.

Orange: lowpass response. The bump at cutoff is the resonance peak. Higher Q = sharper peak.

Moving the cutoff: filter sweeps

A static filter is fine. A moving filter is alive. Use a signal to sweep the cutoff over time.

filter sweep

sine.range(200, 2000).slow(4): a sine wave that sweeps from 200Hz to 2000Hz over 4 cycles. The bass breathes open and closed. Dark, bright, dark, bright.

lowpass filter

.lpf(freq) passes frequencies below freq and cuts the rest. .lpq(q) adds resonance, a volume boost at the cutoff frequency. Low cutoff = dark and subby. High cutoff = bright and present. Move the cutoff over time and you get a filter sweep.

Bandpass

Lowpass removes highs. Highpass removes lows. A bandpass does both — cuts the highs AND the lows, keeping only a band in the middle:

bandpass — keep only the middle

.bpf() sets the center frequency. .bpq() sets how narrow the band is. High Q = narrow, nasal. Low Q = wide, subtle. The bandpass focuses the sound on one frequency region.

filter types

Three filters, three jobs. .lpf() = lowpass (cut highs, keep lows). .hpf() = highpass (cut lows, keep highs). .bpf() = bandpass (cut both, keep a band in the middle). Each takes a frequency. Each has a Q parameter (.lpq(), .hpq(), .bpq()).

tweak it

Sweep the bandpass: .bpf(sine.range(200, 2000).slow(4)). The band moves through the spectrum. Try .bpq(20) for extreme narrow — the sawtooth becomes a whistle.

rabbit hole: filter types and frequency response

Lowpass vs. highpass

Two sides of the same idea. A lowpass lets the low end through and cuts the top. A highpass does the opposite: cuts the low end and lets the top through.

lowpass (.lpf)

frequency → vol cutoff pass cut

highpass (.hpf)

frequency → vol cutoff cut pass

In strudel: .lpf(1000) = lowpass at 1kHz. .hpf(200) = highpass at 200Hz. You can use both on the same sound to create a bandpass effect, only letting through a narrow range.

Resonance shape

When you add .lpq(), the frequency response curve gets a bump right at the cutoff. Low Q = gentle slope. High Q = sharp peak. At very high Q, the peak is so tall the filter starts to ring on its own.

Q valuecharacteruse
0–1gentle rolloffsubtle darkening
2–5noticeable peakpresence, warmth
5–10nasal, honkyacid bass, lead sounds
10+ringing, whistlingacid techno, special effects

Why DnB producers love lowpass

The reese has harmonics stretching to 20kHz. Without a filter, it eats the entire mix. A lowpass at 400–800Hz keeps the weight and movement but leaves room for drums, hats, and vocals above. The filter IS the mix tool.

04The Score Continues

The koto floats. The pulse sits underneath from L1. Now add a bass drone. Filtered sawtooth, low and slow. The ocean under the melody:

your ambient piece: adding the ocean

Three layers. Koto on top. Pulse in the middle. Bass drone on the bottom. The .attack(1) makes the drone fade in slowly. The .lpf(120) keeps it dark. This is starting to sound like the piece.

Your turn

Change the drone note. Try b1 for darker. Try a2 for warmer. Adjust .lpf() between 80 and 300. Lower = more felt than heard. Higher = more audible presence.

05Drums + Bass

Your EDM.1 breakbeat on top, the filtered reese underneath. The skeleton of every DnB track.

Everything combined. The DnB breakbeat from EDM.1 (kick, snare, hats) stacked with a filtered reese bass. Two detuned saws, lowpassed, moving under programmed drums at 170bpm.

drums + bass
tweak it

Try a different bassline: "c2 ~ g1 ~ eb2 ~ f1 ~". Or change the filter range: sine.range(200, 800) for darker, sine.range(400, 3000) for more bite. Adjust .gain() on the bass vs. drums to find your balance.

compose
  1. Replace the hi-hat pattern with s("[hh hh hh oh]*2"): open hat on every fourth hit. Adjust .gain() so the open hat is louder.
  2. Add a second bass note: change "c2 ~ eb2 ~" to "c2 c2 eb2 ~". The double C2 gives the bassline more urgency.
  3. Drop the bass an octave. Change c2 to c1 and eb2 to eb1 (headphones help). Notice how it gets muddier? That’s the sub-bass territory. Powerful in a club, invisible on laptop speakers.
  4. Add a sub layer: put note("c2 ~ eb2 ~").s("sine").gain(0.5).sustain(0.8) as another line in the stack. Sub sine underneath the reese. Two frequency ranges, one bass.
what you earned
tooldoeslooks like
.s("sine")sine wave synth, pure sub bassnote("c2").s("sine")
.s("sawtooth")sawtooth wave, bright, all harmonicsnote("c2").s("sawtooth")
.s("square")square wave, hollow, odd harmonicsnote("c2").s("square")
.s("triangle")triangle wave, soft, mutednote("c2").s("triangle")
.attack()fade-in time.attack(0.01)
.decay()fade from peak to sustain level.decay(0.1)
.sustain()held volume level (0–1).sustain(0.8)
.release()fade-out after note ends.release(0.1)
.lpf()lowpass filter, cut highs.lpf(400)
.lpq()filter resonance (Q).lpq(5)
.hpf()highpass filter, cut lows.hpf(200)
.add(note())detune / pitch offset.add(note(0.15))
sine.range()signal mapped to a value rangesine.range(200, 2000)
.slow()stretch signal over N cyclessine.range(200, 2000).slow(4)

Next: Layers. Polyrhythm, euclidean patterns, hi-hat rolls, and building a full arrangement.

synth + filter cheat sheet
parameterrangenotes
.lpf()20–20000 Hzlowpass cutoff. 200 = dark sub. 2000 = present. 10000+ = wide open.
.lpq()0–30+resonance. 0–3 = gentle. 5–10 = nasal. 15+ = ringing.
.hpf()20–20000 Hzhighpass cutoff. Use to thin out low end.
.attack()0–2+ sec0.001 = instant. 0.5 = slow fade in.
.decay()0–2+ sectime from peak to sustain level.
.sustain()0–1held level. 1 = full. 0 = silent after decay.
.release()0–2+ secfade out after note ends.
reese recipe

Two sawtooth oscillators. Detune the second by .add(note(0.1)) to .add(note(0.3)). Lowpass both at 400–1200Hz. Add .lpq(3) for presence. Done.

listening

Tracks that demonstrate this lesson’s concepts.

artisttrackwhy
Jeremy SouleSkyrim: Dragonborn (2011)(VGM) inspired by the orchestral weight, bass as power, the floor of a cathedral
C418Minecraft: Subwoofer Lullaby (2011)(VGM) filtered sine bass as warmth, ambient game audio
Reese (Kevin Saunderson)Just Want Another Chance (1988)(techno) the literal origin of the Reese bass
Renegade (Ray Keith)Terrorist (1994)(jungle) sampled Reese + amen = instant jungle
Ed Rush & OpticalWormhole (1998)(neurofunk) first neurofunk, filter sweeps + resampled bass
GoldieInner City Life (1995)(DnB) sub-bass carrying emotional weight
Wendy CarlosSwitched-On Bach (1968)(electronic) first Moog album, proved synthesis could carry a composition
history

The synthesizer turned sound into something you could sculpt. The bass that emerged changed how low-end works in all electronic music.

Bob Moog and voltage control (1964)

Robert Moog demonstrated the first practical voltage-controlled synthesizer at the Audio Engineering Society convention in 1964. His key insight: use voltage to control oscillator frequency, filter cutoff, and amplifier level. One control signal could shape all three. That’s the signal chain in every synth since — oscillator → filter → amplifier — and the chain you’re using with .lpf() and ADSR in this lesson.

Kevin Saunderson’s Casio CZ-1 (1988)

Saunderson recorded “Just Want Another Chance” as Reese. The bassline — two detuned sawtooth oscillators on a Casio CZ-1 — phased against each other to create a growling, living texture. He didn’t intend it as a bass revolution. UK producers sampled it directly. Ray Keith’s “Terrorist” (1994) lifted the bassline wholesale. The “Reese bass” became jungle’s default low-end weapon.

Neurofunk and bass design (1998–2005)

Ed Rush & Optical’s Wormhole (1998) applied studio processing — resampling, heavy filtering, distortion chains — to the Reese template. The bass became an instrument to be designed, not just played. Noisia (Netherlands) pushed this further with surgical mixing and layered sub/mid/high bass splits. Modern bass music production descends from this lineage.

Sources: Pinch & Trocco, Analog Days (2002); Attack Magazine, “Reese Deconstructed” (2016); DJ Mag, “Renegade’s Terrorist” (2019).

→ explore the full timeline