|
|
Drums++ (Drum Beat Programming Language)
Posted: August 2003
Updated: December 9, 2025
Introduction
Drums++ is a programming language designed for creating drum sequence .mid
files that can be imported into programs such as Garage Band. It uses simple
C ideas, for example // and /* */ comments and { } to seperate sections.
I tried to make it as simple as possible so even a non-programmer could
use it.
Recently the ability to have melody patterns was added so the
.mid file can have other instruments that play melodies.
Some examples where I used it for my own music:
Mandelbrot Cluster
Playstation 2 Java
Nintendo 64 Java
Source Code
Drums++ should be quite easy to build from the command line. There are no
dependencies, only requires a compiler on the system. Simply clone the
git repo below and just type: make
git clone https://github.com/mikeakohn/drumsplusplus.git
Sample
In the samples directory of the repo is
melody.dpp. The file has:
include "drum_defines.inc"
set bpm = 110;
set default_volume = 127;
set time_signature = 4/4;
pattern click_track
{
closed_hihat: 1 2 3 4;
}
pattern intro
{
closed_hihat: 1 2 3 4;
snare: 1;
crash_cymbal1: 1;
}
pattern main_1
{
bassdrum: 1 3 3.5;
snare: 2 4;
closed_hihat: 1 2 3 4;
}
pattern main_2
{
bassdrum: 1 3 4;
snare: 2 3.5 4.5;
closed_hihat: 1 2 3 4;
}
section start
{
play: click_track, intro, click_track;
}
section main
{
play: 3 main_1, main_2, 3 main_1, main_2;
}
phrase phrase_1
{
set midi_channel = 1;
voice: 4 A4, 4 B4, 8 B4, 8 B4, 4 C4;
voice: 4 C4, 4 R, 4 R, 4 E4;
voice: 4 E4, 4 R, 4 R, 4 G4;
}
song test_song
{
play drum_track: start, 2 main;
melody chords: phrase_1, phrase_1;
}
Breaking it down part by part, the file starts with a header:
include "drum_defines.inc"
set bpm = 110;
set default_volume = 127;
set time_signature = 4/4;
drum_defines.inc is another file in the samples directory that
maps drum names to the MIDI number that plays that instrument.
Next is a set of patterns:
pattern main_1
{
bassdrum: 1 3 3.5;
snare: 2 4;
closed_hihat: 1 2 3 4;
}
Each pattern gets a name, in this case main_1. Inside of the { }
are the name of the drum, colon, and then a list of beats they land on.
Each line ends with a semicolon. So in this case the snare is hit
on beat 2 and 4.
An optional section can be defined, which is a collection of patterns:
section main
{
play: 3 main_1, main_2, 3 main_1, main_2;
}
This section is called main. This section tells Drums++ to play
the main_1 pattern 3 times, then main_2, then main_1 3 times, and
then main_2.
The "phrase" keyword defines a phrase (small section) of a melody:
phrase phrase_1
{
set midi_channel = 1;
voice: 4 A4, 4 B4, 8 B4, 8 B4, 4 C4;
voice: 4 C4, 4 R, 4 R, 4 E4;
voice: 4 E4, 4 R, 4 R, 4 G4;
}
This phrase is named phrase_1 and plays on midi_channel 1 (piano?).
There are 3 voices here that will play at the same time in sequence.
the 4 signifies a quarter note (Q) can be used also. So in this case
it an Aminor chord is played, then just a quarter note B (4th octave),
2 eight notes of B, and then a Cmajor chord. The following modifiers
are valid:
Tones: A, B (or H), C, D, E, F, G
R = rest
Lengths: 1, 2, 4, 8, 16, 32
W, H, Q, E
Modifiers: #, b, .
A more complex example of a phrase:
phrase chorus
{
voice:
Q R,
H R, 4 B5, 8 B5, 8 A5, 8 B5, 4 C5, 4 B5, 4 A5, H C5, 8 R,
4 B5, 8 B5, 8 A5, 8 G4, W A5, Q R, 8 R,
8 B5, 8 B5, 8 B5, 8 A5, 8 G4, 4 A5.,
8 A5, 8 B5, 8 C5., 8 B5., 16 A5, 16 G4, 2 A5;
}
Finally the song needs a main "song" section:
song test_song
{
play drum_track: start, 2 main;
melody chords: phrase_1, phrase_1;
}
"play" is used to play drum tracks and "melody" is used to create
a melody track. Optionally, both play and melody can have a track
name on them. In this case, the .mid file would have 2 tracks in it,
one named "drum_track" and the other named "chords". Again the
names aren't needed and this could have been written as:
song test_song
{
play: start, 2 main;
melody: phrase_1, phrase_1;
}
The play: keyword can be followed by either patterns or sections.
The melody: keyboard can be followed by phrases. A number before
a pattern, section, or phrase will cause it to be repeated. .
To build the .mid file from the .dpp file:
drumsplusplus$ ./playdpp -o melody.mid samples/melody.dpp
Drums++ - November 26, 2025
Copyright 2003-2025 Michael Kohn
Infile: samples/melody.dpp
The song sounds like this: melody.mid
Other Syntax
set drift = 5;
set midi_channel = 9;
Drift allows volume of the drum to randomly be uneven by the drift
amount. This was done to try to make the drums sound less mechanical.
The midi_channel allows the drum sections to work with different
instruments. Not sure if that's very useful.
C style comments can be used, either // or /* */
define kickdrum 36
define snare 38
Defines can be used if needed. A list of good MIDI drum defines
are in the samples directly in a file called
drum_defines.inc.
Shown in
channels.dpp, some other features are:
pattern main
{
bassdrum: 1 1.5 3;
60/2: 1 3; // Play a middle C with midi channel 2 on beats 1 and 3
snare: 2 4:127;
highhat: 1 2 3 4;
}
pattern test
{
set bpm=240; // set beats per minute to 240 only in this pattern
set time_signature=3/4; // set the time signature to 3/4 only in this pattern
set midi_channel=1; // set the midi channel to 1 only in this pattern
bassdrum: 1 2 3;
highhat: 1
2
3;
}
pattern fill2
{
bassdrum: 1 3;
snare: 2 4:%120;
highhat: 1 2 3;
open_highhat: 4;
}
The main pattern here shows a drum of 60/2. This means play
tone 60 on channel 2. Basically just allows selection of
a different instrument. Could be useful of some instrument is
used more as a rhythm than a melody.
The "test" pattern shows that the bpm, time_signature, and
midi_channel can be changed only for the current pattern.
The "fill2" pattern shows the last beat of the snare as
4:%120. This allows that beat to have a velocity (loudness)
of 120 instead of the default 127.
Copyright 1997-2025 - Michael Kohn
|