NAME
MIDI::Simple::Drummer - Glorified Metronome
ABSTRACT
Is there a drummer in the house?
SYNOPSIS
use MIDI::Simple::Drummer;
my $d = MIDI::Simple::Drummer->new(-bpm => 100);
# A glorified metronome:
$d->count_in;
for(1 .. $d->phrases * $d->beats) {
$d->note($d->EIGHTH, $d->rotate_backbeat(-beat => $_));
$d->note($d->EIGHTH, $d->tick);
}
# A smarter drummer:
my($beat, $fill) = (0, 0);
$d->count_in;
for my $p (1 .. $d->phrases) {
if($p % 2 > 0) {
$beat = $d->beat(-name => 'rock_3', -fill => $fill);
}
else {
$beat = $d->beat(-name => 'rock_4');
$fill = $d->fill(-last => $fill);
}
}
$d->pattern('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->SIXTEENTH, $d->snare) for 0 .. 2;
$d->rest($d->SIXTEENTH);
$d->note($d->EIGHTH, $d->strike('Splash Cymbal','Bass Drum 1'));
}
DESCRIPTION
This module is embroyonic but may yet grow into a giant reptilian monster that smashes Tokyo.
Until then, this is just meant to be a robotic drummer and hide the MIDI::Simple details. It is not a "drum machine", that you have to "program" with some arcane specification syntax. Rather, it will evolve into a sufficiently intelligent drummer, that you can jam with.
Note that you, the user, should know what the patterns are named and what they do. For this, see the "pattern" in MIDI::Simple::Drummer method.
Since we are talking about patterns (A.K.A. beats and fills), this is entirely perl logic based, so you could use a Markov chain, stochastic techniques or a Parse::RecDescent grammar, even.
METHODS
* new()
my $d = MIDI::Simple::Drummer->new(%arguments);
Far away in a distant galaxy... But nevermind that, Luke. Use The Source.
Currently, the accepted attributes are:
# Rhythm metrics:
-bpm => 120,
-phrases => 4,
-beats => 4,
# MIDI settings:
-channel => '9',
-volume => '100',
# The Goods[TM]:
-patterns => undef,
-kit => undef,
-file => 'Drummer.mid',
-score => MIDI::Simple->new_score,
These can all be overridden by supplying them to the constuctor.
* phrases()
$x = $d->phrases;
$d->phrases($x);
Return or set the number of phrases to play.
* beats()
$x = $d->beats;
$d->beats($x);
Return or set the number of beats per measure.
* score()
$x = $d->score;
$d->score($x);
Return or set the "score" in MIDI::Simple object.
* 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
.
* kicktick()
$x = $d->kicktick;
$x = $d->kicktick(['Bass Drum 1','Mute Triangle']);
Strike or set the "kicktick" patches. By default, these are the predefined kick
and tick
patches.
* 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.
* 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 just a pass-through to "n" in MIDI::Simple.
* rest()
$d->rest($d->SIXTEENTH);
$d->rest('sn');
Add a rest to the score. This is just 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(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.)
* rotate_backbeat()
$x = $d->rotate_backbeat;
$x = $d->rotate_backbeat(-beat => $y);
$x = $d->rotate_backbeat(-fill => $z);
$x = $d->rotate_backbeat(-options => ['Cowbell','Hand Clap']);
$x = $d->rotate_backbeat(-backbeat => ['Bass Drum 1','Electric Snare']);
$x = $d->rotate_backbeat(-tick => ['Claves']);
Return the rotating backbeat
with either the tick
or an option patch. If the beat given is the first, a post-fill option strike is made.
* beat()
$x = $d->beat;
$x = $d->beat(-name => $x);
$x = $d->beat(-last => $x);
$x = $d->beat(-fill => $x);
$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 => $y
argument, where $y
is the fill we just played. Similarly, the -last => $z
argument indicates that $z
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 drum-fill to the MIDI score.
* fill()
This is just a handy alias to the beat
method but with -type => 'fill'
added.
* pattern()
$x = $d->pattern;
$x = $d->pattern('foo');
$x = $d->pattern(bar => \&bar);
$x = $d->pattern('paraflamaramadiddle', \&code, 'fill');
$x = $d->pattern(\%patterns);
Return the code reference to the named pattern(s). If a second, coderef argument is provided, the named pattern is assigned to it. A third named argument can be supplied so that a type can be set or selected. -type => 'fill'
to select a named fill.
If the argument is a single hash reference, each is added to the set of known beats.
If no argument is given, all the known patterns are returned.
* kit()
$x = $d->kit;
$x = $d->kit('clank');
$x = $d->kit(clunk => ['Foo','Bar']);
$x = $d->kit(\%drumkit);
Return or set part or all of the percussion set.
* write()
$x = $d->write;
$x = $d->write('Buddy-Rich.mid');
This is just 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.
CONVENIENCE METHODS
These are just meant to avoid literal strings and the need to remember and type the relevant MIDI variables.
* WHOLE
$d->WHOLE;
Return 'wn'
.
* HALF
Return 'hn'
.
* QUARTER
Return 'qn'
.
* EIGHTH
Return 'en'
.
* SIXTEENTH
Return 'sn'
.
* _p2n()
Return %MIDI::percussion2notenum
a la "GOODIES" in MIDI.
* _n2p()
Return the inverse: %MIDI::notenum2percussion
.
TO DO
* It don't mean a thing if it ain't got that swing.
* Make any and all appropriate MIDI::Simple
parameters available in the constructor.
* Intelligently modulate dynamics (i.e. "add nuance" like accent or crescendo).
* Possibly load patterns automatically with qw(:rock)
syntax, in the use
line.
* Import patterns via "read_score" in MIDI::Simple, maybe.
* Leverage "from_drum_tab" in MIDI::Tab, possibly.
SEE ALSO
The eg/* and t/* files, that come with this distribution.
MIDI::Simple itself.
http://maps.google.com/maps?q=mike+avery+joplin - my drum teacher.
AUTHOR AND COPYRIGHT
Gene Boggs <gene@cpan.org>
Copyright 2009, Gene Boggs, All Rights Reserved.
LICENSE
This program is free software; you can redistribute or modify it under the same terms as Perl itself.