DnB has two load-bearing walls: drums and bass. You built the drums. Now the other half.
Bass in DnB lives below 200Hz. It’s physical. You feel it in your chest before you hear it in your ears. This lesson starts with a single low note and ends with a filtered reese sitting under your EDM.1 breakbeat.
s(), note(), stack(), setcpm(),
mini-notation ([] * ~ () <>), .gain(),
.lpf(), .decay(), .sustain(),
and the DnB breakbeat from EDM.1.
C in the first octave. A sine wave. The simplest possible bass sound.
If your speakers are small, you might barely hear it. That’s normal. C1 is 32.7Hz. Most laptop speakers roll off around 80Hz. Headphones or a subwoofer will make this lesson significantly more educational.
Change c1 to c2. Then c3. Each octave doubles the frequency.
C2 is 65Hz. C3 is 131Hz. Notice how the higher you go, the less you feel it and the more you hear it.
An octave is a doubling of frequency. c1 = 32.7Hz. c2 = 65.4Hz. c3 = 130.8Hz. Same note name, different register. DnB sub bass typically lives around C1–C2.
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. The foundation that everything else sits on top of. In a club, this is what makes your ribcage vibrate.
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 |
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. The result is 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. The result is 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, from gentle warmth to nasal honk.
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.
A static filter is fine. A moving filter is alive. Use a signal to sweep the cutoff.
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.
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 two pillars. Your EDM.1 breakbeat on top, the filtered reese underneath. This is 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. Notice how it gets muddier? That’s why most DnB bass sits at C2, not C1.note("c1 ~ eb1 ~").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("c1").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.