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.
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.
C in the first octave. A sine wave. The simplest possible bass sound.
C2 is 65Hz. Low enough to feel. Most laptop speakers can handle it. Headphones help.
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.
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.
The default synth envelope is short; the note fades quickly. For bass, you want it to sustain.
Now it holds. .sustain(1) means full volume for the duration of the note. The sine just sits there, steady and heavy.
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.
One note repeating isn’t a bassline. Two notes and a rest. Now it moves.
C and Eb. A minor third apart. The rests (~) give the pattern space to breathe. At 170bpm this is already bouncing.
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.
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.
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:
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.
Swap sine for sawtooth. Same C2, completely different sound.
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.
Try triangle too. It’s like a fatter sine. The four basic wave shapes (sine, sawtooth, square, triangle) are the building blocks of synthesis.
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.
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.
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.
| wave | harmonics | character |
|---|---|---|
| sine | fundamental only | pure, round, sub bass |
| sawtooth | all (1x, 2x, 3x, 4x…) | bright, buzzy, aggressive |
| square | odd only (1x, 3x, 5x…) | hollow, woody |
| triangle | odd only, quieter | soft, muted |
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.
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.
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.
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.
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.
| harmonic | multiple | interval | note (fund. = C2) |
|---|---|---|---|
| 1st (fund.) | 1× | unison | C2 |
| 2nd | 2× | octave | C3 |
| 3rd | 3× | octave + fifth | G3 |
| 4th | 4× | 2 octaves | C4 |
| 5th | 5× | 2 oct. + major 3rd | E4 |
| 6th | 6× | 2 oct. + fifth | G4 |
| 7th | 7× | 2 oct. + minor 7th | B♭4 (approx) |
| 8th | 8× | 3 octaves | C5 |
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.
Play this. One sawtooth at C2.
Now two saws stacked, but the second one is slightly detuned, a quarter-tone flat.
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.
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.
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.
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.
| detune | beat rate | character |
|---|---|---|
| +1 Hz | 1 Hz | slow throb, chorus-like |
| +3 Hz | 3 Hz | medium pulse, classic reese |
| +5 Hz | 5 Hz | fast wobble, aggressive |
| +10 Hz | 10 Hz | rough, 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.
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.
Same two-note bassline from earlier, but with the reese instead of a bare sine.
Aggressive. Raw. Also way too bright. It’s eating the whole frequency spectrum.
A lowpass filter removes frequencies above a cutoff point. Apply one to the 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.
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.
.lpq() adds resonance at the cutoff frequency. A boost right at the edge. Gentle warmth at low values, nasal honk at high ones.
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.
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.
A static filter is fine. A moving filter is alive. Use a signal to sweep the cutoff over time.
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.
.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.
Lowpass removes highs. Highpass removes lows. A bandpass does both — cuts the highs AND the lows, keeping only a band in 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.
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()).
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.
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)
highpass (.hpf)
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.
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 value | character | use |
|---|---|---|
| 0–1 | gentle rolloff | subtle darkening |
| 2–5 | noticeable peak | presence, warmth |
| 5–10 | nasal, honky | acid bass, lead sounds |
| 10+ | ringing, whistling | acid techno, special effects |
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.
The koto floats. The pulse sits underneath from L1. Now add a bass drone. Filtered sawtooth, low and slow. The ocean under the melody:
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.
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.
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.
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.
s("[hh hh hh oh]*2"): open hat on every fourth hit. Adjust .gain() so the open hat is louder."c2 ~ eb2 ~" to "c2 c2 eb2 ~". The double C2 gives the bassline more urgency.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.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.| tool | does | looks like |
|---|---|---|
| .s("sine") | sine wave synth, pure sub bass | note("c2").s("sine") |
| .s("sawtooth") | sawtooth wave, bright, all harmonics | note("c2").s("sawtooth") |
| .s("square") | square wave, hollow, odd harmonics | note("c2").s("square") |
| .s("triangle") | triangle wave, soft, muted | note("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 range | sine.range(200, 2000) |
| .slow() | stretch signal over N cycles | sine.range(200, 2000).slow(4) |
Next: Layers. Polyrhythm, euclidean patterns, hi-hat rolls, and building a full arrangement.
| parameter | range | notes |
|---|---|---|
| .lpf() | 20–20000 Hz | lowpass cutoff. 200 = dark sub. 2000 = present. 10000+ = wide open. |
| .lpq() | 0–30+ | resonance. 0–3 = gentle. 5–10 = nasal. 15+ = ringing. |
| .hpf() | 20–20000 Hz | highpass cutoff. Use to thin out low end. |
| .attack() | 0–2+ sec | 0.001 = instant. 0.5 = slow fade in. |
| .decay() | 0–2+ sec | time from peak to sustain level. |
| .sustain() | 0–1 | held level. 1 = full. 0 = silent after decay. |
| .release() | 0–2+ sec | fade out after note ends. |
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.
Tracks that demonstrate this lesson’s concepts.
| artist | track | why |
|---|---|---|
| Jeremy Soule | Skyrim: Dragonborn (2011) | (VGM) inspired by the orchestral weight, bass as power, the floor of a cathedral |
| C418 | Minecraft: 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 & Optical | Wormhole (1998) | (neurofunk) first neurofunk, filter sweeps + resampled bass |
| Goldie | Inner City Life (1995) | (DnB) sub-bass carrying emotional weight |
| Wendy Carlos | Switched-On Bach (1968) | (electronic) first Moog album, proved synthesis could carry a composition |
The synthesizer turned sound into something you could sculpt. The bass that emerged changed how low-end works in all electronic music.
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.
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.
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).