Djent is built on a trick that sounds complicated but is surprisingly mechanical: a short, oddly-sized rhythmic phrase repeated over a steady 4/4 beat until the two line up again. Bands like Meshuggah and Periphery made a sound out of it, and because it's mechanical, it's perfect for code.
I built djentgen to generate these riffs as MIDI, so I could drop them into a DAW and play along, or use them as a starting point for songs. In this tutorial we'll build a generator like it from scratch in Python, and you'll understand every note it writes.
If you just want to hear the result first:
pip3 install djentgen
djentgen --tempo-bpm 140 --num-measures 8
The rhythmic idea: polymeter
Most rock riffs repeat every bar, or every two bars. A djent riff often repeats every 7 sixteenth notes, or 9, or 13, while the drums keep a steady 4/4 pulse of 16 sixteenths per bar.
Picture a 7-step phrase laid over a 16-step bar:
Bar grid: 1 . . . 2 . . . 3 . . . 4 . . . | 1 . . . 2 . . . 3 . . . 4 . . .
Phrase: x . x x - . . x . x x - . . x . | x x - . . x . x x - . . x . x x
^ phrase starts ^ bar 2 starts mid-phrase
Each time the phrase repeats, it lands at a different point in the bar. That constant shifting against a steady beat is what makes djent feel heavy and disorientating at the same time.
Left alone, a 7-step phrase and a 16-step bar only line up again after 112 steps, which is 7 bars. That's often too long to feel resolved, so most riffs reset the phrase at the start of a cycle of 2 or 4 bars. The listener gets the tension of the shifting phrase, then the release of everything landing together on the downbeat.
The sound: chugs on a low string
The other half of djent is the tone: palm-muted notes on a very low open string, usually a 7- or 8-string guitar tuned down.
- Root note: the low open string, played most of the time
- Accents: occasional higher notes, often dissonant intervals like the minor second or tritone
- Dynamics: loud accents on the start of each phrase, and quiet ghost notes in between
In MIDI, notes are numbered 0 to 127. A standard guitar's low E is note 40. A 7-string in drop A goes down to A1, which is note 33. We'll use 33 as our default root.
MIDI in five minutes
A MIDI file isn't audio. It's a list of instructions: "start note 33 now, at this velocity", "stop note 33 a sixteenth note later".
The parts you need to know:
- Ticks per beat: how finely a beat (a quarter note) is divided. We'll use 480, a common value, which makes a sixteenth note 120 ticks.
- Delta time: each message stores the time since the previous message, not since the start. This trips up almost everyone the first time.
- Velocity: how hard a note is played, from 1 to 127.
- Channels: 16 per file. Channel 10 (index 9 in code) is reserved for drums by convention, which is how DAWs know to load a drum kit.
- Tracks: a type 1 MIDI file can hold several tracks, which DAWs import as separate instruments.
Setup
We'll use mido, a small, well-maintained library for reading and writing MIDI files:
mkdir djent && cd djent
python3 -m venv .venv
source .venv/bin/activate
pip install mido
Your first chug
Here's the smallest useful program: a single sixteenth-note chug on the low A.
from mido import Message, MetaMessage, MidiFile, MidiTrack, bpm2tempo
TICKS_PER_BEAT = 480
SIXTEENTH = TICKS_PER_BEAT // 4
mid = MidiFile(ticks_per_beat=TICKS_PER_BEAT)
track = MidiTrack()
mid.tracks.append(track)
track.append(MetaMessage('set_tempo', tempo=bpm2tempo(140)))
track.append(Message('note_on', note=33, velocity=110, time=0))
track.append(Message('note_off', note=33, velocity=0, time=SIXTEENTH))
mid.save('chug.mid')
Drag chug.mid into any DAW, put a guitar or bass instrument on the track, and you'll hear one low note. Not much of a riff yet, but every part of the generator builds on these few lines.
Notice time=SIXTEENTH on the note_off: it means "a sixteenth note after the previous message", which is the note_on.
What's next
In the full tutorial we build the complete generator:
- generating random phrases from rhythm cells
- resetting the phrase on the cycle so the riff resolves
- giving each phrase a fixed voicing so it sounds like a riff, not noise
- accents and ghost notes with velocity
- a kick drum that locks to the guitar, plus a half-time snare
- a command-line interface with reproducible seeds
Checking access…