line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#! perl |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
81432
|
use strict; |
|
3
|
|
|
|
|
9
|
|
|
3
|
|
|
|
|
132
|
|
4
|
3
|
|
|
3
|
|
16
|
use warnings; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
93
|
|
5
|
3
|
|
|
3
|
|
903
|
use utf8; |
|
3
|
|
|
|
|
13
|
|
|
3
|
|
|
|
|
14
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
package Music::ChordBot::Song; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 NAME |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
Music::ChordBot::Song - Generate ChordBot songs. |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use Music::ChordBot::Song; |
16
|
|
|
|
|
|
|
song "All Of Me"; |
17
|
|
|
|
|
|
|
tempo 105; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
section "All Of Me 1"; |
20
|
|
|
|
|
|
|
style "Chicago"; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
C 4; C; E7; E7; A7; A7; Dm7; Dm7; |
23
|
|
|
|
|
|
|
E7; E7; Am7; Am7; D7; D7; Dm7; G7; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
section "All Of Me 2"; |
26
|
|
|
|
|
|
|
style "Swingatron"; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
C 4; C; E7; E7; A7; A7; Dm7; Dm7; |
29
|
|
|
|
|
|
|
Dm7; Ebdim7; Em7; A9; Dm7b5; G13; |
30
|
|
|
|
|
|
|
C 2; Ebdim7; Dm7; G7; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=head1 DESCRIPTION |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Music::ChordBot::Song exports a number of subroutines that can be used |
35
|
|
|
|
|
|
|
to construct a CordBot song. Upon program termination, the song is |
36
|
|
|
|
|
|
|
written out to standard output in JSON format, suitable for import into |
37
|
|
|
|
|
|
|
the ChordBot app. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=cut |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
our $VERSION = 0.01; |
42
|
|
|
|
|
|
|
|
43
|
3
|
|
|
3
|
|
1720
|
use Music::ChordBot::Opus; |
|
3
|
|
|
|
|
12
|
|
|
3
|
|
|
|
|
117
|
|
44
|
3
|
|
|
3
|
|
2453
|
use Music::ChordBot::Opus::Section; |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
149
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
our @EXPORT = qw( song chord section tempo style ); |
47
|
3
|
|
|
3
|
|
16
|
use base 'Exporter'; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
1893
|
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
my $song; |
50
|
|
|
|
|
|
|
my $section; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=head1 SUBROUTINES |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=head2 song I |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
Starts a new song with the given title. |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=cut |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub song($) { |
61
|
3
|
50
|
|
3
|
1
|
25
|
_export() if $song; |
62
|
3
|
|
|
|
|
30
|
$song = Music::ChordBot::Opus->new( name => shift ); |
63
|
3
|
|
|
|
|
9
|
undef $section; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head2 tempo I |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
Sets the tempo in beats per minute. |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=cut |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub tempo($) { |
73
|
3
|
|
|
3
|
1
|
22
|
$song->tempo(@_); |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=head2 section I |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
Starts a song section. A section groups a number of bars with chords. |
79
|
|
|
|
|
|
|
Each section can have a style associated although it is common to have |
80
|
|
|
|
|
|
|
a single style for the whole song. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=cut |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub section($) { |
85
|
4
|
|
|
4
|
1
|
43
|
$section = Music::ChordBot::Opus::Section->new( name => shift ); |
86
|
4
|
|
|
|
|
28
|
$song->add_section( $section ); |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=head2 style I |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Associate the given style to the current section. For a list of |
92
|
|
|
|
|
|
|
presets, see http://chordbot.com/style-lookup.php . |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=cut |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub style($) { |
97
|
4
|
|
|
4
|
1
|
28
|
$section->set_style(@_); |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head2 chord I, I, I |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
Append a chord with given key, type and duration. Note that duration |
103
|
|
|
|
|
|
|
is measured in number of beats. The three arguments may also be |
104
|
|
|
|
|
|
|
specified in a single string argument, space separated. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
You can specify a bass note for the chord by separating the key and |
107
|
|
|
|
|
|
|
bass with a slash. E.g., C<"C/B"> denotes a C chord with B bass. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=cut |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub chord($) { |
112
|
14
|
|
|
14
|
1
|
110
|
$section->add_chord( @_ ); |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# Automatically export the song at the end of the program. |
116
|
|
|
|
|
|
|
sub END { |
117
|
3
|
50
|
|
3
|
|
17624
|
_export() if $song; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
3
|
|
|
3
|
0
|
33
|
sub json { $song->json } |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
sub _export { |
123
|
3
|
|
|
3
|
|
29
|
binmode( STDOUT, ':utf8'); |
124
|
3
|
|
|
|
|
20
|
print STDOUT $song->json, "\n"; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=head1 QUICK ACCESS CHORDS |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
For convenience, subroutines are exported for quick access to chords. |
130
|
|
|
|
|
|
|
So instead of |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
chord "C", "Maj", 4; |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
you can also write: |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
C 4; |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
If you omit the duration it will use the duration of the previous |
139
|
|
|
|
|
|
|
chord: |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
C 4; C; F; G; # same as C 4; C 4; F 4; G 4; |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
The subroutine name is the key of the chord, optionally followed by a |
144
|
|
|
|
|
|
|
chord modifier. So C is C major, C is C minor, and so on. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Chord keys are A B C D E F G Ab Bb Db Eb Gb Ais Cis Dis Fis Gis. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
Modifiers are m 7 m7 maj7 9 11 13 auf 7b5 m7b5 dim dim7. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=cut |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
my $_key = "C"; |
153
|
|
|
|
|
|
|
my $_mod = "Maj"; |
154
|
|
|
|
|
|
|
my $_dur = 4; |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub _chord { |
157
|
34
|
|
|
34
|
|
63
|
my ( $key, $mod, $dur ) = @_; |
158
|
34
|
100
|
|
|
|
66
|
$_dur = $dur if $dur; |
159
|
34
|
|
|
|
|
98
|
$section->add_chord( $key, $mod, $_dur ); |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
for my $key ( qw( A B C D E F G |
163
|
|
|
|
|
|
|
Ab Bb Db Eb Gb |
164
|
|
|
|
|
|
|
Ais Cis Dis Fis Gis |
165
|
|
|
|
|
|
|
) ) { |
166
|
|
|
|
|
|
|
my $k2 = $key =~ /^(.)is$/ ? "$1#" : $key; |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
my %m = ( |
169
|
|
|
|
|
|
|
"" => "Maj", |
170
|
|
|
|
|
|
|
"m" => "Min", |
171
|
|
|
|
|
|
|
"7" => "7", |
172
|
|
|
|
|
|
|
"m7" => "Min7", |
173
|
|
|
|
|
|
|
"maj7" => "Maj7", |
174
|
|
|
|
|
|
|
"9" => "9", |
175
|
|
|
|
|
|
|
"11" => "11", |
176
|
|
|
|
|
|
|
"13" => "13", |
177
|
|
|
|
|
|
|
"aug" => "Aug", |
178
|
|
|
|
|
|
|
"7b5" => "7(b5)", |
179
|
|
|
|
|
|
|
"m7b5" => "Min7(b5)", |
180
|
|
|
|
|
|
|
"dim" => "Dim", |
181
|
|
|
|
|
|
|
"dim7" => "Dim7", |
182
|
|
|
|
|
|
|
); |
183
|
|
|
|
|
|
|
|
184
|
3
|
|
|
3
|
|
22
|
no strict 'refs'; |
|
3
|
|
|
|
|
17
|
|
|
3
|
|
|
|
|
546
|
|
185
|
|
|
|
|
|
|
while ( my ($k, $t) = each( %m ) ) { |
186
|
|
|
|
|
|
|
*{ __PACKAGE__ . '::' . $key.$k } = |
187
|
34
|
|
|
34
|
|
193
|
sub { &_chord( $k2, $t, $_[0] ) }; |
188
|
|
|
|
|
|
|
push( @EXPORT, $key.$k ); |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# Rest 'chord'. |
193
|
0
|
|
|
0
|
0
|
|
sub NC { &_chord( "A", "Silence", $_[0] ) } |
194
|
|
|
|
|
|
|
*S = \&NC; |
195
|
|
|
|
|
|
|
push( @EXPORT, "S", "NC" ); |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=head1 DISCLAIMER |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
There is currently NO VALIDATION of argument values. Illegal values |
200
|
|
|
|
|
|
|
will result in program crashes and songs that cannot be imported, or |
201
|
|
|
|
|
|
|
played, by ChordBot. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=head1 AUTHOR, COPYRIGHT & LICENSE |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
See L. |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=cut |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
1; |