-
Notifications
You must be signed in to change notification settings - Fork 5
/
random-beat
50 lines (40 loc) · 1.13 KB
/
random-beat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/env perl
use strict;
use warnings;
# Choose a random beat from all possible 3-strike, eighth-note patterns.
use Data::Dumper::Compact qw(ddc);
use String::Random;
use MIDI::Drummer::Tiny;
my $bpm = 100;
my $bars = 4; # Repeat the phrase (4 times)
my $digits = 3; # Simultaneous events (closed hihat, snare, kick)
my $groups = 8; # Divisions of the bar (eighth notes)
my $dura = 'en';
# NB: 2**3 = 8 possible strings of [01]{3} => n. groups => k
# NB: variations_with_repetition(n,k) = n**k => 8**8 = 16,777,216
my $sr = String::Random->new;
my @beat = map { $sr->randregex("[01]{$digits}") } 1 .. $groups;
print ddc(\@beat);
my $d = MIDI::Drummer::Tiny->new(
file => "$0.mid",
bpm => $bpm,
bars => $bars,
);
my @strikes = (
$d->closed_hh,
$d->snare,
$d->kick,
);
for my $bar (1 .. $d->bars) {
for my $beat (@beat) {
my @strike;
my $i = 0;
# Decide what strikes should happen if any
for my $bit (split //, $beat) {
push @strike, $strikes[$i] if $bit;
$i++;
}
@strike ? $d->note($dura, @strike) : $d->rest($dura);
}
}
$d->write;