The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

MIDI::Drummer::Tiny - Glorified metronome

VERSION

version 0.4305

SYNOPSIS

  use MIDI::Drummer::Tiny;

  my $d = MIDI::Drummer::Tiny->new(
    file      => 'drums.mid',
    bpm       => 100,
    volume    => 100,
    signature => '5/4',
    bars      => 8,
    reverb    => 0,
    soundfont => '/you/soundfonts/TR808.sf2', # option
    #kick  => 36, # Override default patch
    #snare => 40, # "
  );

  $d->count_in(1);  # Closed hi-hat for 1 bar

  $d->metronome54;  # 5/4 time for the number of bars

  $d->rest($d->whole);

  $d->set_time_sig('4/4');

  $d->metronome44(3);  # 4/4 time for 3 bars

  $d->flam($d->quarter, $d->snare);
  $d->crescendo_roll([50, 127, 1], $d->eighth, $d->thirtysecond);
  $d->note($d->sixteenth, $d->crash1);
  $d->accent_note(127, $d->sixteenth, $d->crash2);

  my $patterns = [ your_function(5, 16), your_function(7, 16) ];
  $d->pattern( instrument => $d->kick, patterns => $patterns );

  # Alternate kick and snare
  $d->note($d->quarter, $d->open_hh, $_ % 2 ? $d->kick : $d->snare)
    for 1 .. $d->beats * $d->bars;

  # Same but with beat-strings:
  $d->sync_patterns(
    $d->open_hh => [ '1111' ],
    $d->snare   => [ '0101' ],
    $d->kick    => [ '1010' ],
  ) for 1 .. $d->bars;

  $d->add_fill('...'); # see doc...

  print 'Count: ', $d->counter, "\n";

  # As a convenience, and sometimes necessity:
  $d->set_bpm(200); # handy for tempo changes
  $d->set_channel;  # reset back to 9 if ever changed

  $d->timidity_cfg('timidity-drummer.cfg');

  $d->write;

  # OR:

  $d->play_with_timidity;

DESCRIPTION

This module provides handy defaults and tools to produce a MIDI score with drum parts.

Below, the term "spec" refers to a note length duration, like an eighth or quarter note, for instance.

ATTRIBUTES

verbose

Default: 0

file

Default: MIDI-Drummer.mid

score

Default: MIDI::Simple->new_score

soundfont

  $soundfont = $tabla->soundfont;

The file location, where a soundfont lives.

reverb

Default: 15

channel

Default: 9

volume

Default: 100

bpm

Default: 120

bars

Default: 4

signature

Default: 4/4

beats / divisions

beats

Computed from the signature, if not given in the constructor.

Default: 4

divisions

Computed from the signature.

Default: 4

counter

  $d->counter( $d->counter + $duration );
  $count = $d->counter;

Beat counter of durations, where a quarter-note is equal to 1. An eighth-note is 0.5, etc.

This is automatically accumulated each time a rest or note is added to the score.

KIT

click, bell (metronome)
open_hh, closed_hh, pedal_hh
crash1, crash2, splash, china
ride1, ride2, ride_bell
snare, acoustic_snare, electric_snare, side_stick, clap

Where the snare is by default the same as the acoustic_snare but can be overridden with the electric_snare ('n40').

hi_tom, hi_mid_tom, low_mid_tom, low_tom, hi_floor_tom, low_floor_tom
kick, acoustic_bass, electric_bass

Where the kick is by default the same as the acoustic_bass but can be overridden with the electric_bass ('n36').

tambourine, cowbell, vibraslap
hi_bongo, low_bongo, mute_hi_conga, open_hi_conga, low_conga, high_timbale, low_timbale
high_agogo, low_agogo, cabasa, maracas, short_whistle, long_whistle, short_guiro, long_guiro, claves, hi_wood_block, low_wood_block, mute_cuica, open_cuica
mute_triangle, open_triangle

DURATIONS

whole, triplet_whole, dotted_whole, double_dotted_whole
half, triplet_half, dotted_half, double_dotted_half
quarter, triplet_quarter, dotted_quarter, double_dotted_quarter
eighth, triplet_eighth, dotted_eighth, double_dotted_eighth
sixteenth, triplet_sixteenth, dotted_sixteenth, double_dotted_sixteenth
thirtysecond, triplet_thirtysecond, dotted_thirtysecond, double_dotted_thirtysecond
sixtyfourth, triplet_sixtyfourth, dotted_sixtyfourth, double_dotted_sixtyfourth
onetwentyeighth, triplet_onetwentyeighth, dotted_onetwentyeighth, double_dotted_onetwentyeighth

METHODS

new

  $d = MIDI::Drummer::Tiny->new(%arguments);

Return a new MIDI::Drummer::Tiny object and add a time signature event to the score.

note

 $d->note( $d->quarter, $d->closed_hh, $d->kick );
 $d->note( 'qn', 42, 35 ); # Same thing

Add notes to the score.

This method takes the same arguments as "Parameters for n/r/noop" in MIDI::Simple.

It also keeps track of the beat count with the counter attribute.

accent_note

  $d->accent_note($accent_value, $d->sixteenth, $d->snare);

Play an accented note.

For instance, this can be a "ghosted note", where the accent is a smaller number (< 50). Or a note that is greater than the normal score volume.

rest

 $d->rest( $d->quarter );

Add a rest to the score.

This method takes the same arguments as "Parameters for n/r/noop" in MIDI::Simple.

It also keeps track of the beat count with the counter attribute.

count_in

 $d->count_in;
 $d->count_in($bars);
 $d->count_in({ bars => $bars, patch => $patch });

Play a patch for the number of beats times the number of bars.

If no bars are given, the object setting is used. If no patch is given, the closed hihat is used.

metronome38

  $d->metronome38;
  $d->metronome38($bars);

Add a steady 3/8 beat to the score.

metronome34

  $d->metronome34;
  $d->metronome34($bars);

Add a steady 3/4 beat to the score.

metronome44

  $d->metronome44;
  $d->metronome44($bars);
  $d->metronome44($bars, $flag);

Add a steady 4/4 beat to the score.

If a flag is provided the beat is modified to include alternating eighth-note kicks.

metronome44swing

  $d->metronome44swing;
  $d->metronome44swing($bars);

Add a steady 4/4 swing beat to the score.

metronome54

  $d->metronome54;
  $d->metronome54($bars);

Add a 5/4 beat to the score.

metronome58

  $d->metronome58;
  $d->metronome58($bars);

Add a 5/8 beat to the score.

metronome68

  $d->metronome68;
  $d->metronome68($bars);

Add a 6/8 beat to the score.

metronome74

  $d->metronome74;
  $d->metronome74($bars);

Add a 7/4 beat to the score.

metronome78

  $d->metronome78;
  $d->metronome78($bars);

Add a 7/8 beat to the score.

flam

  $d->flam($spec);
  $d->flam( $spec, $grace_note );
  $d->flam( $spec, $grace_note, $patch );
  $d->flam( $spec, $grace_note, $patch, $accent );

Add a "flam" to the score, where a ghosted 64th gracenote is played before the primary note.

If not provided the snare is used for the grace and patch patches. Also, 1/2 of the score volume is used for the accent if that is not given.

If the grace note is given as a literal 'r', rest instead of adding a note to the score.

roll

  $d->roll( $length, $spec );
  $d->roll( $length, $spec, $patch );

Add a drum roll to the score, where the patch is played for duration length in spec increments.

If not provided the snare is used for the patch.

crescendo_roll

  $d->crescendo_roll( [$start, $end, $bezier], $length, $spec );
  $d->crescendo_roll( [$start, $end, $bezier], $length, $spec, $patch );

Add a drum roll to the score, where the patch is played for duration length in spec notes, at increasing or decreasing volumes from start to end.

If not provided the snare is used for the patch.

If true, the bezier flag will render the crescendo with a curve, rather than as a straight line.

     |            *
     |           *
 vol |         *
     |      *
     |*
     ---------------
           time

pattern

  $d->pattern( patterns => \@patterns );
  $d->pattern( patterns => \@patterns, instrument => $d->kick );
  $d->pattern( patterns => \@patterns, instrument => $d->kick, %options );

Play a given set of beat patterns with the given instrument.

The patterns are an arrayref of "beat-strings". By default these are made of contiguous ones and zeros, meaning "strike" or "rest". For example:

  patterns => [qw( 0101 0101 0110 0110 )],

This method accumulates the number of beats in the object's counter attribute.

The vary option is a hashref of coderefs, keyed by single character tokens, like the digits 0-9. Each coderef duration should add up to the given duration option. The single argument to the coderefs is the object itself and may be used as: my $self = shift; in yours.

Defaults:

  instrument: snare
  patterns: [] (i.e. empty!)
  Options:
    duration: quarter-note
    beats: given by constructor
    repeat: 1
    negate: 0 (flip the bit values)
    vary:
        0 => sub { $self->rest( $args{duration} ) },
        1 => sub { $self->note( $args{duration}, $args{instrument} ) },

sync_patterns

  $d->sync_patterns( $instrument1 => $patterns1, $inst2 => $pats2, ... );
  $d->sync_patterns(
      $d->open_hh => [ '11111111') ],
      $d->snare   => [ '0101' ],
      $d->kick    => [ '1010' ],
      duration    => $d->eighth, # render all notes at this level of granularity
  ) for 1 .. $d->bars;

Execute the pattern method for multiple voices.

If a duration is provided, this will be used for each pattern (primarily for the add_fill method).

add_fill

  $d->add_fill( $fill, $instrument1 => $patterns1, $inst2 => $pats2, ... );
  $d->add_fill(
      sub {
          my $self = shift;
          return {
            duration       => 16, # sixteenth note fill
            $self->open_hh => '00000000',
            $self->snare   => '11111111',
            $self->kick    => '00000000',
          };
      },
      $d->open_hh => [ '11111111' ],  # example phrase
      $d->snare   => [ '0101' ],      # "
      $d->kick    => [ '1010' ],      # "
  );

Add a fill to the beat pattern. That is, replace the end of the given beat-string phrase with a fill. The fill is given as the first argument and should be a coderef that returns a hashref. The default is a three-note, eighth-note snare fill.

set_time_sig

  $d->set_time_sig;
  $d->set_time_sig('5/4');
  $d->set_time_sig( '5/4', 0 );

Add a time signature event to the score, and reset the beats and divisions object attributes.

If a ratio argument is given, set the signature object attribute to it. If the 2nd argument flag is 0, the beats and divisions are not reset.

set_bpm

  $d->set_bpm($bpm);

Reset the beats per minute.

set_channel

  $d->set_channel;
  $d->set_channel($channel);

Reset the channel to 9 by default, or the given argument if different.

set_volume

  $d->set_volume;
  $d->set_volume($volume);

Set the volume to the given argument (0-127).

If not given a volume argument, this method mutes (sets to 0).

sync

  $d->sync(@code_refs);

This is a simple pass-through to the score synch method.

This allows simultaneous playing of multiple "tracks" defined by code references.

write

Output the score as a MIDI file with the module "file" attribute as the file name.

timidity_cfg

  $timidity_conf = $d->timidity_cfg;
  $d->timidity_cfg($config_file);

Return a timidity.cfg paragraph to use a defined soundfont attribute. If a config_file is given, the timidity configuration is written to that file.

play_with_timidity

  $d->play_with_timidity;
  $d->play_with_timidity($config_file);

Play the score with timidity.

If there is a soundfont attribute, either the given config_file or timidity-midi-util.cfg is used for the timidity configuration. If a soundfont is not defined, a timidity configuration file is not rendered.

SEE ALSO

The t/* test file and the eg/* programs in this distribution.

Also eg/drum-fills-advanced in the Music::Duration::Partition distribution.

https://ology.github.io/midi-drummer-tiny-tutorial/

Data::Dumper::Compact

List::Util

Math::Bezier

MIDI::Util

Moo

Music::Duration

Music::RhythmSet::Util

https://en.wikipedia.org/wiki/General_MIDI#Percussion

https://en.wikipedia.org/wiki/General_MIDI_Level_2#Drum_sounds

AUTHOR

Gene Boggs <gene@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2014-2023 by Gene Boggs.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.