Intro
Rhythm is an allusive element in music creation, it can be as simple as a quarter note ostinato on the bass drum or as complex as multiple parts playing in different tempi or different subdivisions of the beat. Today, we’ll dive into a semi-randomized approach to rhythmic pattern generation. We’ll look at how these patterns can add variety and spontaneity, even when working within the confines of traditional western music notation.
Written rhythms are usually tied to some underlying pulse, regardless of whether or not that pulse is explicitly present in the recorded or performed result. Historically, notation in western music developed from only two basic note lengths—longa and breve—into the increasingly subdivided system we know today. Along with this, bars (or measures) and bar lines were introduced to maintain a structured rhythmic framework.
Because of this structure, it becomes easy to represent rhythmic patterns digitally. If each bar is subdivided into equal units (eight eighth notes, for instance), then every moment in the bar can be labeled as either “play” or “rest.” This binary approach lends itself well to generating possibilities programmatically.
Generating Rhythmic Patterns
To illustrate the concept of rhythm generation, I have written a simple script that creates all possible permutations of eight notes and breaks within a bar of n
beats. Each bar is represented by a list of booleans, where True
signifies a beat and False
represents a break. By randomly selecting bars from this list, we can produce semi-randomized rhythmic patterns that maintain a sense of structure.
Here’s a brief overview of the script:
import random
def generate_all_bar_options(n: int) -> list:
result = [[]]
for i in range(n):
result = [[True] + rest for rest in result] + [[False] + rest for rest in result]
return result
def generate_bars(num_bars: int, beats_per_bar: int) -> list:
options = generate_all_bar_options(beats_per_bar)
return [random.choice(options) for _ in range(num_bars)]
# Example usage
num_bars = 8
beats_per_bar = 4
bars = generate_bars(num_bars, beats_per_bar)
Code language: Python (python)
But it doesn’t end there, the script then takes this list of booleans and produces LilyPond code. With a single function call, we can generate multiple bars, define part names for different facets of the drum kit, and produce a fully notated score. The code can be found here:
https://codeberg.org/guyoob/generative-music-resources/src/branch/master/drum_beats
Why LilyPond?
One of the major advantages of LilyPond is that it’s text-based, making it straightforward for generative scripts to alter and create music notation dynamically. If you want to change the number of bars or the length of the measure (e.g., eight eighth notes per bar, ten eighth notes per bar, etc.), you can do so with just a few lines of Python. When you compile the LilyPond file, you’ll end up with both a PDF for standard music notation and a MIDI file that can be imported into any digital audio workstation (DAW).
Making actual music
To demonstrate the practical application of these generated rhythms, I have prepared a few musical examples.
Because these parts are being generated on the fly, you can impose structural patterns like “AABACCA” and map each letter to a specific bar pattern or to a group of bars. This means each occurrence of an “A” bar might be identical or perhaps get variations if the script re-rolls the dice. Whether you’re composing for a traditional drum kit, an avant-garde percussion ensemble, or even a synthesizer emulating drum sounds, the possibilities are endless.

You might worry that random beats will sound jarring, but there’s value in letting a certain amount of chance guide the creative process. Sometimes, a random spark is precisely what’s needed to push a composition in a new direction. I’ve experimented with these randomly generated drum parts in two tracks:
“When the Keyboard Breaks.”
Here, I used six different randomly generated sets of drum patterns, each assigned to a distinct drum kit component. The result was a dense, swirling mass of rhythms—an ostinato that’s almost hypnotic, with a guitar sample layered on top for added texture.
“Consentual Suicide.”
In this track, a jazz piano sample sets the harmonic tone, while the drum part is entirely derived from one of my randomly generated patterns. Using Ardour’s midi transformation feature, I have assigned each tone to a different part of the drum set. It added a playful yet slightly disruptive feel that I found intriguing, especially layered against more conventional chord progressions.