NAME
MIDI::Simple::Drummer - Glorified metronome
SYNOPSIS
# A glorified metronome:
use MIDI::Simple::Drummer;
my $d = MIDI::Simple::Drummer->new(-bpm => 100);
$d->count_in;
for(1 .. $d->phrases * $d->bars) {
$d->note($d->EIGHTH, $d->backbeat_rhythm(-beat => $_));
$d->note($d->EIGHTH, $d->tick);
}
# Shuffle:
use MIDI::Simple::Drummer;
my $d = MIDI::Simple::Drummer->new(-bpm => 100);
$d->count_in;
for(1 .. $d->phrases * $d->bars) {
$d->note($d->TRIPLET_EIGHTH, $d->backbeat_rhythm(-beat => $_));
$d->rest($d->TRIPLET_EIGHTH);
$d->note($d->TRIPLET_EIGHTH, $d->tick);
}
# A rock drummer:
use MIDI::Simple::Drummer::Rock;
$d = MIDI::Simple::Drummer::Rock->new(-bpm => 100);
my($beat, $fill) = (0, 0);
$d->count_in;
for my $p (1 .. $d->phrases) {
if($p % 2 > 0) {
$beat = $d->beat(-name => 3, -fill => $fill);
}
else {
$beat = $d->beat(-name => 4);
$fill = $d->fill(-last => $fill);
}
}
$d->patterns(fin => \&fin);
$d->beat(-name => 'fin');
$d->write;
sub fin {
my $d = shift;
$d->note($d->EIGHTH, $d->option_strike;
$d->note($d->EIGHTH, $d->strike('Splash Cymbal','Bass Drum 1'));
$d->note($d->TRIPLET_SIXTEENTH, $d->snare) for 0 .. 2;
$d->rest($d->SIXTEENTH);
$d->note($d->EIGHTH, $d->strike('Splash Cymbal','Bass Drum 1'));
}
# Multi-tracking:
use MIDI::Simple::Drummer;
my $d = MIDI::Simple::Drummer->new;
$d->sync_tracks(
sub { $d->beat(-name => 'b1') },
sub { $d->beat(-name => 'b2') },
);
$d->write();
sub b1 { # tick
my $self = shift;
my %args = @_;
my $strike = $self->tick;
$self->note($self->QUARTER(), $strike) for 1 .. $self->beats;
return $strike;
}
sub b2 { # kick
my $self = shift;
my %args = @_;
my $strike = $self->kick;
$self->note($self->QUARTER(), $strike) for 1 .. $self->beats;
return $strike;
}
DESCRIPTION
This is a "robotic" drummer that provides simple methods to make beats.
This is not a "drum machine" that you control in a traditional, mechanical sense. It is intended to be a "sufficiently intelligent" drummer, with which you can practice, improvise, compose, record and experiment.
These "beats" are entirely constructed with perl and as such, any method can be used to generate the phrases - Stochastic, Evolutionary, L-system, Recursive descent grammar, Bayseian, Markov, Quantumm::Whatever...
Note that you, the programmer, should know what the patterns and kit elements are named and what they do. For these, check out the source of this package, the included style subclass(es), the eg/* files and the .mid files they produce.
The default kit is the exciting, general MIDI drumkit. Fortunately, you can import the .mid file into your favorite sequencer and assign better patches. Voilà!
METHODS
new()
my $d = MIDI::Simple::Drummer->new(%arguments);
Return a new MIDI::Simple::Drummer
instance with these arguments:
# MIDI
-channel => 9
-volume => 100
# Rhythm metrics
-accent => 30
-bpm => 120
-phrases => 4
-bars => 4
-beats => 4
-swing => 0,
# The Goods[TM].
-file => Drummer.mid
-kit => Set by the API unless provided
-patterns => Set by the API "
-score => "
These arguments can be overridden with this constuctor or the following accessor methods.
volume()
$x = $d->volume;
$x = $d->volume($y);
Return and set the volume.
bpm()
Beats per minute.
phrases(), bars(), beats()
Number of phrases, measures and beats per measure. These are just variables for you to use as rhythm metrics. They have no other meaning or hidden functionality.
swing()
Use triplet or even time. This just sets an attribute that can be checked conditionally.
channel()
MIDI channel.
file()
Name for the .mid file to write.
sync_tracks()
Combine beats in parallel with an argument list of anonymous subroutines.
patterns()
Return or set known style patterns.
score()
$x = $d->score;
$x = $d->score($score);
$x = $d->score($score, 'V127');
$x = $d->score('V127');
Return or set the "score" in MIDI::Simple if provided as the first argument. If there are any other arguments, they are set as score no-ops.
accent()
$x = $d->accent();
Either return the current volume plus the accent increment or set the accent increment. This has an upper limit of MIDI fff.
duck()
Reduce the volume by the accent volume.
strike()
$x = $d->strike;
$x = $d->strike('Cowbell');
$x = $d->strike('Cowbell','Tambourine');
@x = $d->strike('Cowbell','Tambourine');
Return note values for percussion names from the standard MIDI percussion set (with "notenum2percussion" in MIDI) in either scalar or list context. (Default predefined snare patch.)
option_strike()
$x = $d->option_strike;
$x = $d->option_strike('Short Guiro','Short Whistle','Vibraslap');
Return a note value from a list of patches (default predefined crash cymbals). If another set of patches is given, one of those is chosen at random.
note()
$d->note($d->SIXTEENTH, $d->snare);
$d->note('sn', 'n38');
Add a note to the score. This is a pass-through to "n" in MIDI::Simple.
rest()
$d->rest($d->SIXTEENTH);
$d->rest('sn');
Add a rest to the score. This is a pass-through to "r" in MIDI::Simple.
metronome()
$d->metronome;
$d->metronome('Mute Triangle');
Add beats * phases of the Pedal Hi-Hat
, unless another patch is provided.
count_in()
$d->count_in;
$d->count_in(2);
$d->count_in(1, 'Side Stick');
And a-one and a-two and a-one, two, three!</Lawrence Welk> ..11</FZ>
If No arguments are provided, the Closed Hi-Hat
is used.
rotate()
$x = $d->rotate;
$x = $d->rotate(3);
$x = $d->rotate(5, ['Mute Hi Conga','Open Hi Conga','Low Conga']);
Rotate through a list of patches according to the given beat number. (Default backbeat patches.)
backbeat_rhythm()
$x = $d->backbeat_rhythm;
$x = $d->backbeat_rhythm(-beat => $y);
$x = $d->backbeat_rhythm(-fill => $z);
$x = $d->backbeat_rhythm(-patches => ['Cowbell','Hand Clap']);
$x = $d->backbeat_rhythm(-backbeat => ['Bass Drum 1','Electric Snare']);
$x = $d->backbeat_rhythm(-tick => ['Claves']);
Return the rotating backbeat
with either the tick
or an option patch (default crashes), if it's the first beat and we just filled.
beat()
$x = $d->beat;
$x = $d->beat(-name => $n);
$x = $d->beat(-last => $y);
$x = $d->beat(-fill => $z);
$x = $d->beat(-type => 'fill');
Play a beat type and return the id for the selected pattern. Beats and fills are both just patterns but drummers think of them as distinct animals.
This method adds an anecdotal "beat" to the MIDI score. You can indicate that we filled in the previous bar, and do something exciting like crash on the first beat, by supplying the -fill => $z
argument, where $z
is the fill we just played. Similarly, the -last => $y
argument indicates that $y
is the last beat we played, so that we can maintain "context sensitivity."
Unless specifically given a pattern to play with the -name
argument, we try to play something different each time, so if the pattern is the same as the -last
, or if there is no given pattern to play, another is chosen.
For -type => 'fill'
, we append a named fill to the MIDI score.
fill()
This is an alias to the beat
method with -type => 'fill'
added.
patterns()
$x = $d->patterns;
$x = $d->patterns('rock_1');
@x = $d->patterns(paraflamaramadiddle => \&code, 'foo fill' => \&foo_fill);
Return or set the code references to the named patterns. If no argument is given, all the known patterns are returned.
write()
$x = $d->write;
$x = $d->write('Buddy-Rich.mid');
This is an alias for "write_score" in MIDI::Simple but with unimaginably intelligent bits. It returns the name of the written file if successful. If no filename is given, we use the preset -file
attribute.
KIT ACCESS
kit()
$x = $d->kit;
$x = $d->kit('snare');
@x = $d->kit( clapsnare => ['Handclap','Electric Snare'],
kickstick => ['Bass Drum 1','Side Stick']);
@x = $d->kit('clapsnare');
Return or set part or all of the percussion set.
name_of()
$x = $d->name_of('kick'); # "Acoustic Bass Drum"
@x = $d->name_of('crash'); # ('Chinese Cymbal', 'Crash Cymbal 1...)
Return the instrument names behind the kit nick-name lists.
hhat()
$x = $d->hhat;
$x = $d->hhat('Cabasa','Maracas','Claves');
Strike or set the "hhat" patches. By default, these are the Closed Hi-Hat
, Open Hi-Hat
and the Pedal Hi-Hat.
crash()
$x = $d->crash;
$x = $d->crash(@crashes);
Strike or set the "crash" patches. By default, these are the Chinese Cymbal
, Crash Cymbal 1
, Crash Cymbal 2
and the Splash Cymbal.
ride()
$x = $d->ride;
$x = $d->ride(@rides);
Strike or set the "ride" patches. By default, these are the Ride Bell
, Ride Cymbal 1
and the Ride Cymbal 2.
tom()
$x = $d->tom;
$x = $d->tom('Low Conga','Mute Hi Conga','Open Hi Conga');
Strike or set the "tom" patches. By default, these are the High Tom
, Hi-Mid Tom
, etc.
kick()
$x = $d->kick;
$x = $d->kick('Bass Drum 1');
Strike or set the "kick" patch. By default, this is the Acoustic Bass Drum
.
tick()
$x = $d->tick;
$x = $d->tick('Mute Triangle');
Strike or set the "tick" patch. By default, this is the Closed Hi-Hat
.
snare()
$x = $d->snare;
$x = $d->snare('Electric Snare');
Strike or set the "snare" patches. By default, this is the Acoustic Snare.
backbeat()
$x = $d->backbeat;
$x = $d->backbeat('Bass Drum 1','Side Stick');
Strike or set the "backbeat" patches. By default, these are the predefined kick
and snare
patches.
CONVENIENCE METHODS
These are meant to avoid literal strings and the need to remember and type the relevant MIDI variables.
WHOLE or 1st
$x = $d->WHOLE;
$x = $d->_1st;
Return 'wn'
.
HALF or or _2nd
Return 'hn'
.
QUARTER or _4th
Return 'qn'
.
EIGHTH or _8th
Return 'en'
.
SIXTEENTH or _16th
Return 'sn'
.
THIRTYSECOND or _32nd
Return 'yn'
.
SIXTYFOURTH or _64th
Return 'xn'
.
_p2n()
Return %MIDI::percussion2notenum
a la "GOODIES" in MIDI.
_n2p()
Return the inverse: %MIDI::notenum2percussion
.
_default_patterns()
Patterns provided by default. This is {}
, that is, nothing. This is defined in a MIDI::Simple::Drummer::* style package.
_default_kit()
Kit provided by default. This is a subset of the exciting general MIDI kit. This can also be defined in a MIDI::Simple::Drummer::* style package, to use better patches.
TO DO
* Comprehend time signature via beat construction and keep a running clock/total to know where we are in time, at all times.
* Intelligently modulate dynamics to add nuance and "humanize."
* Make a MIDI::Simple::Drummer::AC\x{26A1}DC
?
* Import patterns via "read_score" in MIDI::Simple?
* Leverage "from_drum_tab" in MIDI::Tab?
SEE ALSO
The eg/* and t/* files, that come with this distribution show how to use it.
The MIDI::Simple::Drummer::* styles, which you can make (and upload).
MIDI::Simple itself, of course.
http://maps.google.com/maps?q=mike+avery+joplin - my drum teacher.
This distribution at https://github.com/ology/Music/tree/master/MIDI-Simple-Drummer, where interim changes are made, long before any CPAN release.
AUTHOR AND COPYRIGHT
Gene Boggs <gene@cpan.org>
Copyright 2011, Gene Boggs, All Rights Reserved.
LICENSE
This program is free software; you can redistribute or modify it under the same terms as Perl itself.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 509:
Non-ASCII character seen before =encoding in 'I<Voilà!>'. Assuming UTF-8