Imitating a Drum Circle
Ever been to the park and heard a tribe drumming in the distance? This is a drum circle. Upon closer inspection, each drummer has a single instrument (or maybe a set of bongos). Each drummer keeps a steady beat in common and in syncopation with his or her fellow drummers.
I wondered if this could be simulated somehow? There are of course decisions to be made - parts to this equation... How should the drummers enter? All at once or gradually? How should a drum be chosen or selected? And what phrase(s) should be played anyway?
Enter MIDI-Perl. Here is the program: drum-circle
Basically it does the following:
Use the modules necessary to have a drummer and rhythmic phrases.
Define the number of drummers ($max) as a number supplied by the user (or 4 by default).
Define a MIDI::Drummer::Tiny instance ($d), which will drive everything.
Set the possible drums to use (@DRUMS). In our case this is a group of toms, bongos, congas, cabasa, maracas, guiro, claves, and wood blocks.
Declare an array of phrases (@phrases), which is to be populated with code-references.
Define a 4 bar Music::Duration::Partition instance ($mdp), which we will use to generate rhythmic motifs for each drummer.
Loop from 1 to $max, appending phrases to play for each new drummer.
Add the phrases to the score such that they are played simultaneously.
Write the generated "composition" to disk, as a MIDI file named after the program "drum-circle."
Define the subroutine to generate our phrases!
This last part is shown here:
sub phrase {
my ($p) = @_; # Phrase number
# Get an unseen drum to use
my $drum = $DRUMS[int rand @DRUMS];
while ($seen{$drum}++) {
$drum = $DRUMS[int rand @DRUMS];
}
# Create a rhythmic phrase
my $motif = $mdp->motif;
# Either rest or play the motif
my $phrase = sub {
for my $n (1 .. $d->bars + 4) {
# If we are not up yet, then rest
if ($n < ($p * 4)) {
$d->rest($d->whole);
next;
}
# Otherwise play the rhythmic phrase!
for my $i (@$motif) {
# Get a fluctuating velocity between f and fff
my $vol = 'v' . (96 + int(rand 32));
$d->note($i, $drum, $vol);
}
}
};
return $phrase;
}
Here the variable $p is the number 1 to $max from our loop in step #7 above. Next, an unseen drum is selected at random. Then a quasi-random rhythmic motif is generated by Music::Duration::Partition as defined above. Finally an anonymous subroutine is returned, that just decides whether to play the generated motif or rest for a whole note.
This resting is crucial. Each drummer enters after 4 bars of the previous drummer having played. So, the second drummer enters after that many bars, the third after another 4, the fourth after another, etc. Having everyone play at once or at random was just not a pleasant musical evolution. So I chose to have them enter one at a time.
Each run of this is different. Sometimes you get a "pleasant musical evolution", but sometimes you get all toms, or just a weird clash of rhythms. Here is one with 8 voices that is ok:
And how about another?
Ok, one more!