|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package MIDI::Simple::Drummer;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $AUTHORITY = 'cpan:GENE';  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: An algorithmic MIDI drummer  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.0811';  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
2552
 | 
 use strict;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
120
 | 
    | 
| 
9
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
20
 | 
 use warnings;  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
    | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
2531
 | 
 use MIDI::Simple ();  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87080
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
120
 | 
    | 
| 
12
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
1982
 | 
 use Music::Duration ();  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1559
 | 
    | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
300
 | 
    | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 BEGIN {  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Define a division structure to use for durations.  | 
| 
16
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1320
 | 
     use constant DIVISION => {  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         w => { number =>  1, ordinal =>  '1st', name => 'whole' },  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         h => { number =>  2, ordinal =>  '2nd', name => 'half' },  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         q => { number =>  4, ordinal =>  '4th', name => 'quarter' },  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         e => { number =>  8, ordinal =>  '8th', name => 'eighth' },  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         s => { number => 16, ordinal => '16th', name => 'sixteenth' },  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         x => { number => 32, ordinal => '32nd', name => 'thirtysecond' },  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         y => { number => 64, ordinal => '64th', name => 'sixtyfourth' },  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         z => { number => 128, ordinal => '128th', name => 'onetwentyeighth' },  | 
| 
25
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
28
 | 
     };  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Add constants for each known duration.  | 
| 
28
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
39
 | 
     for my $n (keys %MIDI::Simple::Length) {  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Get the duration part of the note name.  | 
| 
30
 | 
160
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
699
 | 
         my $name = $n =~ /([whqesxyz])n$/ ? $1 : '';  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
160
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
237
 | 
         if ($name) {  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # Create a meaningful prefix for the named constant.  | 
| 
34
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
183
 | 
             my $prefix = '';  | 
| 
35
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
316
 | 
             $prefix .= 'triplet'       if $n =~ /t\w/;  | 
| 
36
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
279
 | 
             $prefix .= 'double_dotted' if $n =~ /^dd/;  | 
| 
37
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
271
 | 
             $prefix .= 'dotted'        if $n =~ /^d[^d]/;  | 
| 
38
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
248
 | 
             $prefix .= '_' if $prefix;  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # Add name-based duration.  | 
| 
41
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
304
 | 
             my $key = uc($prefix . DIVISION->{$name}{name});  | 
| 
42
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2646
 | 
             constant->import($key => $n); # LeoNerd++ clue  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # Add a _prefix for numeric duration constants.  | 
| 
44
 | 
160
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
377
 | 
             $prefix .= '_' unless $prefix;  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # Add number-based duration.  | 
| 
46
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
304
 | 
             $key = uc($prefix . DIVISION->{$name}{ordinal});  | 
| 
47
 | 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18000
 | 
             constant->import($key => $n);  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
50
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             warn "ERROR: Unknown note value '$n' - Skipping."  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new { # Is there a drummer in the house?  | 
| 
56
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
1377
 | 
     my $class = shift;  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Our drummer is a set of attributes.  | 
| 
58
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
     my $self  = {  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # MIDI  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -channel    => 9,  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -volume     => 100,  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -pan        => 64,  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -pan_width  => 0,  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -patch      => 0,  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -reverb     => 20,  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -chorus     => 0,  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Rhythm  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -accent     => 30,  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -bpm        => 120,  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -phrases    => 4,  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -bars       => 4,  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -beats      => 4,  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -divisions  => 4,  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -signature  => '',  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # The Goods™  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -score      => undef,  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -file       => 'Drummer.mid',  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -kit        => undef,  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -patterns   => undef,  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         @_  # Capture any override or extra arguments.  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Make our drummer a proper object.  | 
| 
84
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     bless $self, $class;  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Perform any pre-flight default setting.  | 
| 
87
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     $self->_setup;  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
89
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     return $self;  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _setup { # Where's my roadies, Man?  | 
| 
93
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
15
 | 
     my $self = shift;  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Give unto us, a score with which to fondle.  | 
| 
96
 | 
9
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
69
 | 
     $self->{-score} ||= MIDI::Simple->new_score;  | 
| 
97
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
790
 | 
     $self->{-score}->noop('c'.$self->{-channel}, 'V'.$self->{-volume});  | 
| 
98
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
451
 | 
     $self->{-score}->set_tempo(int(60_000_000 / $self->{-bpm}));  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Give unto us a drum, so that we might bang upon it all day, instead of working.  | 
| 
101
 | 
9
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
189
 | 
     $self->{-kit} ||= $self->_default_kit;  | 
| 
102
 | 
9
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
39
 | 
     $self->{-patterns} ||= $self->_default_patterns;  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set the groove dimensions if a time signature is given.  | 
| 
105
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     if ($self->{-signature}) {  | 
| 
106
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         $self->signature($self->{-signature});  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # If no signature is provided, assume 4/4.  | 
| 
110
 | 
8
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
22
 | 
         $self->{-beats}     ||= 4;  | 
| 
111
 | 
8
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
19
 | 
         $self->{-divisions} ||= 4;  | 
| 
112
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
         $self->{-signature} = "$self->{-beats}/$self->{-divisions}";  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $self->{-score}->time_signature(  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->{-beats},  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         sqrt( $self->{-divisions} ),  | 
| 
118
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
         ( $self->{-divisions} == 8 ? 24 : 18 ),  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         8  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Reset the backbeat if the signature is a 3 multiple.  | 
| 
123
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
139
 | 
     my $x = $self->{-beats} / 3;  | 
| 
124
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
71
 | 
     if ($x !~ /\./) {  | 
| 
125
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         $self->backbeat('Acoustic Bass Drum', 'Acoustic Snare', 'Acoustic Bass Drum');  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set the method name for the division metric. Ex: QUARTER for 4.  | 
| 
129
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     for my $note (keys %{+DIVISION}) {  | 
| 
 
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
    | 
| 
130
 | 
72
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
140
 | 
         if (DIVISION->{$note}{number} == $self->{-divisions}) {  | 
| 
131
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
             $self->div_name(uc DIVISION->{$note}{name});  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set effects.  | 
| 
136
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     $self->reverb;  | 
| 
137
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
     $self->chorus;  | 
| 
138
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     $self->pan_width;  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
140
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     return $self;  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Convenience functions:  | 
| 
144
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
 
 | 
34729
 | 
 sub _durations { return \%MIDI::Simple::Length }  | 
| 
145
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
 sub _n2p { return \%MIDI::notenum2percussion }  | 
| 
146
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
 sub _p2n { return \%MIDI::percussion2notenum }  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Accessors:  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub channel { # The general MIDI drumkit is often channel 9.  | 
| 
150
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
1188
 | 
     my $self = shift;  | 
| 
151
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     $self->{-channel} = shift if @_;  | 
| 
152
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     return $self->{-channel};  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub patch { # Drum kit  | 
| 
155
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my $self = shift;  | 
| 
156
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{-patch} = shift if @_;  | 
| 
157
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{-score}->patch_change($self->{-channel}, $self->{-patch});  | 
| 
158
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $self->{-patch};  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub reverb { # [0 .. 127]  | 
| 
161
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
14
 | 
     my $self = shift;  | 
| 
162
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     $self->{-reverb} = shift if @_;  | 
| 
163
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     $self->{-score}->control_change($self->{-channel}, 91, $self->{-reverb});  | 
| 
164
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
133
 | 
     return $self->{-reverb};  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub chorus { # [0 .. 127]  | 
| 
167
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
16
 | 
     my $self = shift;  | 
| 
168
 | 
9
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
     $self->{-chorus} = shift if @_;  | 
| 
169
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $self->{-score}->control_change($self->{-channel}, 93, $self->{-chorus});  | 
| 
170
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
118
 | 
     return $self->{-chorus};  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub pan { # [0 Left-Middle-Right 127]  | 
| 
173
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
10
 | 
     my $self = shift;  | 
| 
174
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $self->{-pan} = shift if @_;  | 
| 
175
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     $self->{-score}->control_change($self->{-channel}, 10, $self->{-pan});  | 
| 
176
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
147
 | 
     return $self->{-pan};  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub pan_width { # [0 .. 64] from center  | 
| 
179
 | 
17
 | 
 
 | 
 
 | 
  
17
  
 | 
  
1
  
 | 
29
 | 
     my $self = shift;  | 
| 
180
 | 
17
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     $self->{-pan_width} = shift if @_;  | 
| 
181
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     return $self->{-pan_width};  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub bpm { # Beats per minute  | 
| 
184
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
390
 | 
     my $self = shift;  | 
| 
185
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $self->{-bpm} = shift if @_;  | 
| 
186
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
     return $self->{-bpm};  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub volume { # TURN IT DOWN IN THERE!  | 
| 
189
 | 
22
 | 
 
 | 
 
 | 
  
22
  
 | 
  
1
  
 | 
818
 | 
     my $self = shift;  | 
| 
190
 | 
22
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     $self->{-volume} = shift if @_;  | 
| 
191
 | 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     return $self->{-volume};  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub phrases { # o/` How many more times? Treat me the way you wanna do?  | 
| 
194
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
1101
 | 
     my $self = shift;  | 
| 
195
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     $self->{-phrases} = shift if @_;  | 
| 
196
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     return $self->{-phrases};  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub bars { # Number of measures  | 
| 
199
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
797
 | 
     my $self = shift;  | 
| 
200
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $self->{-bars} = shift if @_;  | 
| 
201
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
     return $self->{-bars};  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub beats { # Beats per measure  | 
| 
204
 | 
78
 | 
 
 | 
 
 | 
  
78
  
 | 
  
1
  
 | 
1227
 | 
     my $self = shift;  | 
| 
205
 | 
78
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
128
 | 
     $self->{-beats} = shift if @_;  | 
| 
206
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
185
 | 
     return $self->{-beats};  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub divisions { # The division of the measure that is "the pulse."  | 
| 
209
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
1260
 | 
     my $self = shift;  | 
| 
210
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     $self->{-divisions} = shift if @_;  | 
| 
211
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     return $self->{-divisions};  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub signature { # The ratio of discipline  | 
| 
214
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
823
 | 
     my $self = shift;  | 
| 
215
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     if (@_) {  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Set the argument to the signature string.  | 
| 
217
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         $self->{-signature} = shift;  | 
| 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Set the rhythm metrics.  | 
| 
219
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         ($self->{-beats}, $self->{-divisions}) = split /\//, $self->{-signature}, 2;  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
221
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     return $self->{-signature};  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub div_name { # The name of the denominator of the time signature.  | 
| 
224
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
  
1
  
 | 
18
 | 
     my $self = shift;  | 
| 
225
 | 
12
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     $self->{-div_name} = shift if @_;  | 
| 
226
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     return $self->{-div_name};  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub file { # The name of the MIDI file output  | 
| 
229
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
826
 | 
     my $self = shift;  | 
| 
230
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $self->{-file} = shift if @_;  | 
| 
231
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     return $self->{-file};  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub score { # The MIDI::Simple score with no-op-ability  | 
| 
235
 | 
21
 | 
 
 | 
 
 | 
  
21
  
 | 
  
1
  
 | 
414
 | 
     my $self = shift;  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # If we are presented with a M::S object, assign it as the score.  | 
| 
238
 | 
21
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
37
 | 
     $self->{-score} = shift if ref $_[0] eq 'MIDI::Simple';  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set any remaining arguments as score no-ops.  | 
| 
241
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     $self->{-score}->noop($_) for @_;  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
243
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
385
 | 
     return $self->{-score};  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub accent_note { # Accent a single note.  | 
| 
247
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my $self = shift;  | 
| 
248
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $note = shift;  | 
| 
249
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->score('V' . $self->accent); # Accent!  | 
| 
250
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->note($note, $self->strike);  | 
| 
251
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->score('V' . $self->volume); # Reset the note volume.  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # API: Subclass and redefine to emit nuance.  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub accent { # Pump up the Volume!  | 
| 
256
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
  
1
  
 | 
723
 | 
     my $self = shift;  | 
| 
257
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
     $self->{-accent} = shift if @_;  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Add a bit of volume.  | 
| 
260
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     my $accent = $self->{-accent} + $self->volume;  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # But don't try to go above the top.  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $accent = $MIDI::Simple::Volume{fff}  | 
| 
263
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
         if $accent > $MIDI::Simple::Volume{fff};  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Hand back the new volume.  | 
| 
266
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
     return $accent;  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # API: Subclass and redefine to emit nuance.  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub duck { # Drop the volume.  | 
| 
270
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my $self = shift;  | 
| 
271
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{-accent} = shift if @_;  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Subtract a bit of volume.  | 
| 
274
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $duck = $self->volume - $self->{-accent};  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # But don't try to go below the bottom.  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $duck = $MIDI::Simple::Volume{ppp}  | 
| 
277
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         if $duck > $MIDI::Simple::Volume{ppp};  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Hand back the new volume.  | 
| 
280
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $duck;  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub kit { # Arrayrefs of patches  | 
| 
284
 | 
120
 | 
 
 | 
 
 | 
  
120
  
 | 
  
1
  
 | 
1242
 | 
     my $self = shift;  | 
| 
285
 | 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
189
 | 
     return $self->_type('-kit', @_);  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub patterns { # Coderefs of patterns  | 
| 
288
 | 
65
 | 
 
 | 
 
 | 
  
65
  
 | 
  
1
  
 | 
4882
 | 
     my $self = shift;  | 
| 
289
 | 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
131
 | 
     return $self->_type('-patterns', @_);  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _type { # Both kit and pattern access  | 
| 
293
 | 
185
 | 
 
 | 
 
 | 
  
185
  
 | 
 
 | 
209
 | 
     my $self = shift;  | 
| 
294
 | 
185
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
304
 | 
     my $type = shift || return;  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
296
 | 
185
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
406
 | 
     if (!@_) { # If there are no arguments, return all known types.  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
297
 | 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
187
 | 
         return $self->{$type};  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif (@_ == 1) { # Return a single named type with either name=>value or just value.  | 
| 
300
 | 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
136
 | 
         my $i = shift;  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return wantarray  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             ? ($i => $self->{$type}{$i})  | 
| 
303
 | 
122
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
377
 | 
             : $self->{$type}{$i};  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     elsif (@_ > 1 && !(@_ % 2)) { # Add new types if given an even list.  | 
| 
306
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
         my %args = @_;  | 
| 
307
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
         my @t = ();  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
309
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
         while (my ($i, $v) = each %args) {  | 
| 
310
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
             $self->{$type}{$i} = $v;  | 
| 
311
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
             push @t, $i;  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Return the named types.  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return wantarray  | 
| 
315
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             ? (map { $_ => $self->{$type}{$_} } @t) # Hash of named types.  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             : @t > 1                                # More than one?  | 
| 
317
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 ? [map { $self->{$type}{$_} } @t]   # Arrayref of types.  | 
| 
318
 | 
11
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
137
 | 
                 : $self->{$type}{$t[0]};            # Else single type.  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else { # Unlikely to ever be triggered.  | 
| 
321
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         warn 'WARNING: Mystery arguments. Giving up.';  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub name_of { # Return instrument name(s) given kit keys.  | 
| 
326
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
471
 | 
     my $self = shift;  | 
| 
327
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
4
 | 
     my $key  = shift || return;  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return wantarray  | 
| 
329
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         ? @{$self->kit($key)} # List of names  | 
| 
330
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         : join ',', @{$self->kit($key)}; # CSV of names  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _set_get { # Internal kit access  | 
| 
334
 | 
57
 | 
 
 | 
 
 | 
  
57
  
 | 
 
 | 
73
 | 
     my $self = shift;  | 
| 
335
 | 
57
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
169
 | 
     my $key  = shift || return;  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set the kit event.  | 
| 
338
 | 
57
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
95
 | 
     $self->kit($key => [@_]) if @_;  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
340
 | 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
68
 | 
     return $self->option_strike(@{$self->kit($key)});  | 
| 
 
 | 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
102
 | 
    | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # API: Add other keys to your kit & patterns, in a subclass.  | 
| 
344
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
452
 | 
 sub backbeat { return shift->_set_get('backbeat', @_) }  | 
| 
345
 | 
39
 | 
 
 | 
 
 | 
  
39
  
 | 
  
1
  
 | 
1049
 | 
 sub snare    { return shift->_set_get('snare', @_) }  | 
| 
346
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
564
 | 
 sub kick     { return shift->_set_get('kick', @_) }  | 
| 
347
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
  
1
  
 | 
440
 | 
 sub tick     { return shift->_set_get('tick', @_) }  | 
| 
348
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
469
 | 
 sub hhat     { return shift->_set_get('hhat', @_) }  | 
| 
349
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
466
 | 
 sub crash    { return shift->_set_get('crash', @_) }  | 
| 
350
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
452
 | 
 sub ride     { return shift->_set_get('ride', @_) }  | 
| 
351
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
430
 | 
 sub tom      { return shift->_set_get('tom', @_) }  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub strike { # Return note values.  | 
| 
354
 | 
139
 | 
 
 | 
 
 | 
  
139
  
 | 
  
1
  
 | 
2178
 | 
     my $self = shift;  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set the patches, default snare.  | 
| 
357
 | 
139
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
302
 | 
     my @patches = @_ ? @_ : @{$self->kit('snare')};  | 
| 
 
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
    | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Build MIDI::Simple note names from the patch numbers.  | 
| 
360
 | 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
200
 | 
     my @notes = map { 'n' . $MIDI::percussion2notenum{$_} } @patches;  | 
| 
 
 | 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
402
 | 
    | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
362
 | 
139
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
450
 | 
     return wantarray ? @notes : join(',', @notes);  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # API: Redefine this method to use a different decision than rand().  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub option_strike { # When in doubt, crash.  | 
| 
366
 | 
61
 | 
 
 | 
 
 | 
  
61
  
 | 
  
1
  
 | 
1379
 | 
     my $self = shift;  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set the patches, default crashes.  | 
| 
369
 | 
61
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
146
 | 
     my @patches = @_ ? @_ : @{$self->kit('crash')};  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Choose a random patch!  | 
| 
372
 | 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
183
 | 
     return $self->strike($patches[int(rand @patches)]);  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub rotate { # Rotate through a list of patches.  | 
| 
376
 | 
23
 | 
 
 | 
 
 | 
  
23
  
 | 
  
1
  
 | 
2556
 | 
     my $self    = shift;  | 
| 
377
 | 
23
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
48
 | 
     my $beat    = shift || 1; # Assume that we are on the first beat if none is given.  | 
| 
378
 | 
23
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
53
 | 
     my $patches = shift || $self->kit('backbeat'); # Default backbeat.  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Strike a note from the patches, based on the beat.  | 
| 
381
 | 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
59
 | 
     return $self->strike($patches->[$beat % @$patches]);  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub backbeat_rhythm { # AC/DC forever  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Rotate the backbeat with tick & post-fill strike.  | 
| 
385
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
3424
 | 
     my $self = shift;  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set the default parameters with an argument override.  | 
| 
388
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     my %args = (  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -beat => 1,  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -fill => 0,  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -backbeat => scalar $self->kit('backbeat'),  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -tick => scalar $self->kit('tick'),  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -patches => scalar $self->kit('crash'),  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         @_  # Capture any override or extra arguments.  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Strike a cymbal or use the provided patches.  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $c = $args{-beat} == 1 && $args{-fill}  | 
| 
399
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         ? $self->option_strike(@{$args{-patches}})  | 
| 
400
 | 
8
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
30
 | 
         : $self->strike(@{$args{-tick}});  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
    | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Rotate the backbeat.  | 
| 
403
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
     my $n = $self->rotate($args{-beat}, $args{-backbeat});  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Return the cymbal and backbeat note.  | 
| 
406
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     return wantarray ? ($n, $c) : join(',', $n, $c);  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Readable, MIDI score pass-throughs.  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub note {  | 
| 
411
 | 
129
 | 
 
 | 
 
 | 
  
129
  
 | 
  
1
  
 | 
602
 | 
     my $self = shift;  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #use Data::Dumper;warn Data::Dumper->new([@_])->Indent(1)->Terse(1)->Sortkeys(1)->Dump;  | 
| 
413
 | 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
286
 | 
     return $self->{-score}->n(@_)  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
415
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
1
  
 | 
25
 | 
 sub rest { return shift->{-score}->r(@_) }  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub count_in { # And-a one, and-a two...  | 
| 
418
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
306
 | 
     my $self = shift;  | 
| 
419
 | 
3
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
9
 | 
     my $bars = shift || 1; # Assume that we are on the first bar if none is given.  | 
| 
420
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     my $div  = $self->div_name;  | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Define the note to strike with the given patch. Default 'tick' patch.  | 
| 
423
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     my $strike = @_ ? $self->strike(@_) : $self->tick;  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Play the number of bars with a single strike.  | 
| 
426
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     for my $i (1 .. $self->beats * $bars) {  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Accent if we are on the first beat.  | 
| 
428
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
         $self->score('V'.$self->accent) if $i % $self->beats == 1;  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Add a note to the score.  | 
| 
431
 | 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
86
 | 
         $self->note($self->$div, $strike);  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Reset the note volume if we just played the first beat.  | 
| 
434
 | 
32
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1469
 | 
         $self->score('V'.$self->volume) if $i % $self->beats == 1;  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Hand back the note we just used.  | 
| 
438
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
     return $strike;  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub metronome { # Keep time with a single patch. Default: Pedal Hi-Hat  | 
| 
441
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
737
 | 
     my $self = shift;  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # A metronome is just a count-in over the number of phrases  | 
| 
443
 | 
2
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
7
 | 
     return $self->count_in($self->phrases, shift || 'Pedal Hi-Hat');  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub beat { # Pattern selector method  | 
| 
447
 | 
25
 | 
 
 | 
 
 | 
  
25
  
 | 
  
1
  
 | 
8645
 | 
     my $self = shift;  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Receive or default arguments.  | 
| 
449
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
132
 | 
     my %args = (  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -name => 0, # Provide a pattern name  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -fill => 0, # Provide a fill pattern name  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -last => 0, # Is this the last beat?  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -type => '', # Is this a fill if not named in -fill?  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         -time => $self->QUARTER, # Default duration is a quarter note.  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         @_  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Bail out unless we have a proper repertoire.  | 
| 
459
 | 
25
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
57
 | 
     return undef unless ref($self->patterns) eq 'HASH';  | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Get the names of the known patterns.  | 
| 
462
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     my @k = keys %{$self->patterns};  | 
| 
 
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
    | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Bail out if we know nothing.  | 
| 
464
 | 
25
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
49
 | 
     return undef unless @k;  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Do we want a certain type that isn't already in the given name?  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $n = $args{-name} && $args{-type} && $args{-name} !~ /^.+\s+$args{-type}$/  | 
| 
468
 | 
25
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
130
 | 
           ? "$args{-name} $args{-type}" : $args{-name};  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
470
 | 
25
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
48
 | 
     if (@k == 1) { # Return the pattern if there is only one.  | 
| 
471
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n = $k[0];  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else { # Otherwise choose a different pattern.  | 
| 
474
 | 
25
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
105
 | 
         while ($n eq 0 || $n eq $args{-last}) {  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # TODO API: Allow custom decision method.  | 
| 
476
 | 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108
 | 
             $n = $k[int(rand @k)];  | 
| 
477
 | 
28
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
82
 | 
             if ($args{-type}) {  | 
| 
478
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
173
 | 
                 (my $t = $n) =~ s/^.+\s+($args{-type})$/$1/;  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 # Skip if this is not a type for which we are looking.  | 
| 
480
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
67
 | 
                 $n = 0 unless $t eq $args{-type};  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Beat it - i.e. add the pattern to the score.  | 
| 
486
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
     $self->{-patterns}{$n}->($self, %args);  | 
| 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Return the beat note.  | 
| 
488
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1622
 | 
     return $n;  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub fill {  | 
| 
491
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
1
  
 | 
736
 | 
     my $self = shift;  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Add the beat pattern to the score.  | 
| 
493
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
     return $self->beat(@_, -type => 'fill');  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sync_tracks {  | 
| 
497
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
18
 | 
     my $self = shift;  | 
| 
498
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $self->{-score}->synch(@_);  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub write { # You gotta get it out there, you know. Make some buzz, Man.  | 
| 
502
 | 
7
 | 
 
 | 
 
 | 
  
7
  
 | 
  
1
  
 | 
1604
 | 
     my $self = shift;  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Set the file if provided or use the default.  | 
| 
505
 | 
7
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
23
 | 
     my $file = shift || $self->{-file};  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Write the score to the file!  | 
| 
508
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
28
 | 
     $self->{-score}->write_score($file);  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Return the filename if it was created or zero if not.  | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # XXX Check file-size not existance.  | 
| 
512
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11148
 | 
     return -e $file ? $file : 0;  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # API: Redefine these methods in a subclass.  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _default_kit {  | 
| 
517
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
 
 | 
16
 | 
     my $self = shift;  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Hand back a set of instruments as lists of GM named patches.  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return {  | 
| 
520
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
123
 | 
       backbeat => ['Acoustic Snare', 'Acoustic Bass Drum'],  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       snare => ['Acoustic Snare'],     # 38  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       kick  => ['Acoustic Bass Drum'], # 35  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       tick  => ['Closed Hi-Hat'],  | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       hhat  => ['Closed Hi-Hat',  # 42  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Open Hi-Hat',    # 46  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Pedal Hi-Hat',   # 44  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ],  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       crash => ['Chinese Cymbal', # 52  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Crash Cymbal 1', # 49  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Crash Cymbal 2', # 57  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Splash Cymbal',  # 55  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ],  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ride  => ['Ride Bell',      # 53  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Ride Cymbal 1',  # 51  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Ride Cymbal 2',  # 59  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ],  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       tom   => ['High Tom',       # 50  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Hi-Mid Tom',     # 48  | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Low-Mid Tom',    # 47  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Low Tom',        # 45  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'High Floor Tom', # 43  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 'Low Floor Tom',  # 41  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ],  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # There are no known patterns. We are a wannabe at this point.  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _default_patterns {  | 
| 
548
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
8
 | 
     my $self = shift;  | 
| 
549
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
     return {};  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |