Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 352 lines (311 sloc) 12.887 kb
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
1 use v6;
2 use ABC::Header;
3 use ABC::Tune;
4 use ABC::Grammar;
5 use ABC::Actions;
0d17ae0 Solomon Foster Rename Duration.Str to Duration.duration-to-str (so it can be easily use...
authored
6 use ABC::Duration;
7 use ABC::Note;
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
8
6aeb675 Solomon Foster Add crude paper size control.
authored
9 my $paper-size = "letter"; # or switch to "a4" for European paper
10
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
11 my %accidental-map = ( '' => "",
12 '=' => "",
13 '^' => "is",
14 '^^' => "isis",
15 '_' => "es",
16 '__' => "eses" );
17
6c5a781 Solomon Foster Add support for 3/4 time, octave modifiers.
authored
18 my %octave-map = ( -1 => "",
19 0 => "'",
20 1 => "''",
21 2 => "'''" );
b73499a Solomon Foster Get the octave right again, delete dead %note-map hash.
authored
22
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
23 class Context {
c68369e Solomon Foster Tweaks to get inline fields working better, plus more tests for them.
authored
24 has $.key-name;
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
25 has %.key;
e57f6a8 Solomon Foster Add support for meters other than 4/4.
authored
26 has $.meter;
56c09ce Solomon Foster Support length field and proper final bar line.
authored
27 has $.length;
28 has %.cheat-length-map;
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
29
56c09ce Solomon Foster Support length field and proper final bar line.
authored
30 method new($key-name, $meter, $length) {
31 my %cheat-length-map;
32 given $length {
33 when "1/8" { %cheat-length-map = ( '/' => "16",
34 "" => "8",
35 "1" => "8",
36 "3/2" => "8.",
37 "2" => "4",
38 "3" => "4.",
39 "4" => "2",
40 "6" => "2.",
41 "8" => "1");
42 }
43 when "1/4" { %cheat-length-map = ( '/' => "8",
44 "" => "4",
45 "1" => "4",
46 "3/2" => "4.",
47 "2" => "2",
48 "3" => "2.",
49 "4" => "1",
50 "6" => "1.");
51 }
52 die "Don't know how to handle note length $length";
53 }
54 self.bless(*, :$key-name,
55 :key(key_signature($key-name)),
56 :$meter,
57 :$length,
58 :%cheat-length-map);
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
59 }
60
61 method get-real-pitch($nominal-pitch) {
62 my $match = ABC::Grammar.parse($nominal-pitch, :rule<pitch>);
63 if $match<accidental> {
64 $nominal-pitch;
65 } else {
66 ($.key{$match<basenote>.uc} // "") ~ $match<basenote> ~ $match<octave>;
67 }
68 }
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
69
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
70 method get-Lilypond-pitch($abc-pitch) {
71 # say :$abc-pitch.perl;
72 my $real-pitch = self.get-real-pitch($abc-pitch);
73 # say :$real-pitch.perl;
74 my $match = ABC::Grammar.parse($real-pitch, :rule<pitch>);
75
b73499a Solomon Foster Get the octave right again, delete dead %note-map hash.
authored
76 my $octave = +((~$match<basenote>) ~~ 'a'..'z');
6c5a781 Solomon Foster Add support for 3/4 time, octave modifiers.
authored
77 given $match<octave> {
78 when /\,/ { $octave -= (~$match<octave>).chars }
79 when /\'/ { $octave += (~$match<octave>).chars }
80 }
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
81
b73499a Solomon Foster Get the octave right again, delete dead %note-map hash.
authored
82 $match<basenote>.lc ~ %accidental-map{~$match<accidental>} ~ %octave-map{$octave};
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
83 }
f9cdf54 Solomon Foster Refactor in preparation for handling base note lengths other than 1/8.
authored
84
85 method get-Lilypond-duration(ABC::Duration $abc-duration) {
56c09ce Solomon Foster Support length field and proper final bar line.
authored
86 %.cheat-length-map{$abc-duration.duration-to-str};
f9cdf54 Solomon Foster Refactor in preparation for handling base note lengths other than 1/8.
authored
87 }
e57f6a8 Solomon Foster Add support for meters other than 4/4.
authored
88
138f1a9 Solomon Foster Replace write-meter and write-key with meter-to-string and key-to-string...
authored
89 method meter-to-string() {
90 "\\time $.meter ";
e57f6a8 Solomon Foster Add support for meters other than 4/4.
authored
91 }
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
92
56c09ce Solomon Foster Support length field and proper final bar line.
authored
93 method ticks-in-measure() {
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
94 given $.meter {
56c09ce Solomon Foster Support length field and proper final bar line.
authored
95 when "C" { 1 / $.length.eval; }
96 $.meter.eval / $.length.eval;
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
97 }
98 }
b561dfc Solomon Foster Refactor key signature handling a bit.
authored
99
138f1a9 Solomon Foster Replace write-meter and write-key with meter-to-string and key-to-string...
authored
100 method key-to-string() {
b561dfc Solomon Foster Refactor key signature handling a bit.
authored
101 my $sf = %.key.map({ "{.key}{.value}" }).sort.Str.lc;
102 my $major-key-name;
103 given $sf {
104 when "" { $major-key-name = "c"; }
105 when "f^" { $major-key-name = "g"; }
106 when "c^ f^" { $major-key-name = "d"; }
107 when "c^ f^ g^" { $major-key-name = "a"; }
108 when "c^ d^ f^ g^" { $major-key-name = "e"; }
109 when "a^ c^ d^ f^ g^" { $major-key-name = "b"; }
110 when "a^ c^ d^ e^ f^ g^" { $major-key-name = "fis"; }
111 when "a^ b^ c^ d^ e^ f^ g^" { $major-key-name = "cis"; }
112 when "b_" { $major-key-name = "f"; }
113 when "b_ e_" { $major-key-name = "bes"; }
114 when "a_ b_ e_" { $major-key-name = "ees"; }
115 when "a_ b_ d_ e_" { $major-key-name = "aes"; }
116 when "a_ b_ d_ e_ g_" { $major-key-name = "des"; }
117 when "a_ b_ c_ d_ e_ g_" { $major-key-name = "ges"; }
118 when "a_ b_ c_ d_ e_ f_ g_" { $major-key-name = "ces"; }
119 }
138f1a9 Solomon Foster Replace write-meter and write-key with meter-to-string and key-to-string...
authored
120 "\\key $major-key-name \\major\n";
b561dfc Solomon Foster Refactor key signature handling a bit.
authored
121 }
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
122 }
123
124 sub HeaderToLilypond(ABC::Header $header) {
125 say "\\header \{";
126
127 my @titles = $header.get("T")>>.value;
70e5a12 Solomon Foster Add "Tali Foster's" to r-star.abc file so we can easily test multiple tu...
authored
128 say " piece = \"{ @titles[0] }\"";
129 my @composers = $header.get("C")>>.value;
130 say " composer = \"{ @composers[0] }\"" if ?@composers;
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
131
132 say "}";
133 }
134
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
135 class TuneConvertor {
136 has $.context;
7f72e30 Solomon Foster Very weak implementation of tuple that works for the common triplet case...
authored
137
56c09ce Solomon Foster Support length field and proper final bar line.
authored
138 method new($key, $meter, $length) {
139 self.bless(*, :context(Context.new($key, $meter, $length)));
0d17ae0 Solomon Foster Rename Duration.Str to Duration.duration-to-str (so it can be easily use...
authored
140 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
141
142 # MUST: this is context dependent too
143 method Duration($element) {
144 $element.value ~~ ABC::Duration ?? $element.value.ticks !! 0;
145 }
146
147 method StemToLilypond($stem, $suffix = "") {
2f95a2d Solomon Foster Rewrite StemToLilypond to return the string for the note, rather than pr...
authored
148 given $stem {
149 when ABC::Note {
150 " "
151 ~ $.context.get-Lilypond-pitch($stem.pitch)
152 ~ $.context.get-Lilypond-duration($stem)
f1f1c11 Solomon Foster Add support for ties.
authored
153 ~ ($stem.is-tie ?? '~' !! '')
2f95a2d Solomon Foster Rewrite StemToLilypond to return the string for the note, rather than pr...
authored
154 ~ $suffix
155 ~ " ";
156 }
157 "";
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
158 }
159 }
160
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
161 method WrapBar($lilypond-bar, $duration) {
56c09ce Solomon Foster Support length field and proper final bar line.
authored
162 my $ticks-in-measure = $.context.ticks-in-measure;
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
163 my $result = "";
56c09ce Solomon Foster Support length field and proper final bar line.
authored
164 if $duration % $ticks-in-measure != 0 {
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
165 $result = "\\partial { 1 / $.context.length.eval }*{ $duration % $ticks-in-measure } ";
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
166 }
167
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
168 $result ~ $lilypond-bar;
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
169 }
170
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
171 method SectionToLilypond(@elements) {
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
172 my $chords = "";
173 my $notes = "";
2f95a2d Solomon Foster Rewrite StemToLilypond to return the string for the note, rather than pr...
authored
174 my $lilypond = "";
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
175 my $duration = 0;
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
176 my $chord-duration = 0;
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
177 my $suffix = "";
178 for @elements -> $element {
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
179 $duration += self.Duration($element);
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
180 $chord-duration += self.Duration($element);
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
181 given $element.key {
2ea4347 Solomon Foster Add dynamics support (and a few dynamics to "Tali Foster's" so we can ch...
authored
182 when "stem" {
183 $lilypond ~= self.StemToLilypond($element.value, $suffix);
184 $suffix = "";
185 }
186 when "rest" {
187 $lilypond ~= " r{ $.context.get-Lilypond-duration($element.value) } ";
188 $suffix = "";
189 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
190 when "tuplet" {
7d82741 Solomon Foster Special hack to try to get eighth note triplets to have a beam of their ...
authored
191 $lilypond ~= " \\times 2/3 \{";
192 if +$element.value.notes == 3 && $element.value.ticks == 2 {
193 $lilypond ~= self.StemToLilypond($element.value.notes[0], "[");
194 $lilypond ~= self.StemToLilypond($element.value.notes[1]);
195 $lilypond ~= self.StemToLilypond($element.value.notes[2], "]");
196 } else {
197 for $element.value.notes -> $stem {
198 $lilypond ~= self.StemToLilypond($stem);
199 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
200 }
2f95a2d Solomon Foster Rewrite StemToLilypond to return the string for the note, rather than pr...
authored
201 $lilypond ~= " } ";
2ea4347 Solomon Foster Add dynamics support (and a few dynamics to "Tali Foster's" so we can ch...
authored
202 $suffix = "";
1221bde Solomon Foster Get triplets working.
authored
203 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
204 when "broken_rhythm" {
2f95a2d Solomon Foster Rewrite StemToLilypond to return the string for the note, rather than pr...
authored
205 $lilypond ~= self.StemToLilypond($element.value.effective-stem1, $suffix);
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
206 # MUST: handle interior graciings
2f95a2d Solomon Foster Rewrite StemToLilypond to return the string for the note, rather than pr...
authored
207 $lilypond ~= self.StemToLilypond($element.value.effective-stem2);
2ea4347 Solomon Foster Add dynamics support (and a few dynamics to "Tali Foster's" so we can ch...
authored
208 $suffix = "";
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
209 }
210 when "gracing" {
211 given $element.value {
2ea4347 Solomon Foster Add dynamics support (and a few dynamics to "Tali Foster's" so we can ch...
authored
212 when "~" { $suffix ~= "\\turn"; }
213 when "." { $suffix ~= "\\staccato"; }
db5ceec Solomon Foster Substitute regular expressions to detect pianos and fortes, so that arbi...
authored
214 when /^p+$/ | "mp" | "mf" | /^f+$/
2ea4347 Solomon Foster Add dynamics support (and a few dynamics to "Tali Foster's" so we can ch...
authored
215 { $suffix ~= "\\" ~ $element.value; }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
216 }
06b7722 Solomon Foster Get basic rolls and staccato notes working.
authored
217 }
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
218 when "barline" {
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
219 $notes ~= self.WrapBar($lilypond, $duration);
220 $notes ~= " |\n";
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
221 $lilypond = "";
222 $duration = 0;
2f95a2d Solomon Foster Rewrite StemToLilypond to return the string for the note, rather than pr...
authored
223 }
8d09a3e Solomon Foster Get in-line key changes working.
authored
224 when "inline_field" {
225 given $element.value.key {
226 when "K" {
56c09ce Solomon Foster Support length field and proper final bar line.
authored
227 $!context = Context.new($element.value.value,
228 $!context.meter,
229 $!context.length);
138f1a9 Solomon Foster Replace write-meter and write-key with meter-to-string and key-to-string...
authored
230 $lilypond ~= $!context.key-to-string;
8d09a3e Solomon Foster Get in-line key changes working.
authored
231 }
ee29618 Solomon Foster Allow changing meters, add crooked Newfoundland double to the ABC tunes ...
authored
232 when "M" {
56c09ce Solomon Foster Support length field and proper final bar line.
authored
233 $!context = Context.new($!context.key-name,
234 $element.value.value,
235 $!context.length);
138f1a9 Solomon Foster Replace write-meter and write-key with meter-to-string and key-to-string...
authored
236 $lilypond ~= $!context.meter-to-string;
ee29618 Solomon Foster Allow changing meters, add crooked Newfoundland double to the ABC tunes ...
authored
237 }
56c09ce Solomon Foster Support length field and proper final bar line.
authored
238 when "L" {
239 $!context = Context.new($!context.key-name,
240 $!context.meter,
241 $element.value.value);
242 }
8d09a3e Solomon Foster Get in-line key changes working.
authored
243 }
244 }
a63e6e6 Solomon Foster Support slurs, too.
authored
245 when "slur_begin" {
246 $suffix ~= "(";
247 }
248 when "slur_end" {
249 $lilypond .= subst(/(\s+)$/, { ")$0" });
250 }
8d09a3e Solomon Foster Get in-line key changes working.
authored
251 # .say;
06b7722 Solomon Foster Get basic rolls and staccato notes working.
authored
252 }
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
253 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
254
f133cf1 Solomon Foster Refactor so that notes are stored up rather than output bar-by-bar.
authored
255 say "\{";
256 $notes ~= self.WrapBar($lilypond, $duration);
257 say $notes;
2261a59 Solomon Foster Refactor a bit, handle measures with other numbers of eighth notes.
authored
258 say " \}";
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
259 }
260
b561dfc Solomon Foster Refactor key signature handling a bit.
authored
261 method BodyToLilypond(@elements) {
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
262 say "\{";
138f1a9 Solomon Foster Replace write-meter and write-key with meter-to-string and key-to-string...
authored
263 print $.context.key-to-string;
264 printf $.context.meter-to-string;
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
265
266 my $start-of-section = 0;
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
267 loop (my $i = 0; $i < +@elements; $i++) {
4385d53 Solomon Foster Make $length a bit smarter.
authored
268 # say @elements[$i].WHAT;
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
269 if @elements[$i].key eq "nth_repeat"
270 || ($i > $start-of-section
271 && @elements[$i].key eq "barline"
272 && @elements[$i].value ne "|") {
273 if @elements[$i].key eq "nth_repeat"
274 || @elements[$i].value eq ':|:' | ':|' | '::' {
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
275 print "\\repeat volta 2 "; # 2 is abitrarily chosen here!
276 }
277 self.SectionToLilypond(@elements[$start-of-section ..^ $i]);
278 $start-of-section = $i + 1;
7e906b7 Solomon Foster Turn off the double bar code, as it currently conflicts with more import...
authored
279 # if @elements[$i].value eq '||' {
280 # say '\\bar "||"';
281 # }
56c09ce Solomon Foster Support length field and proper final bar line.
authored
282 if @elements[$i].value eq '|]' {
283 say '\\bar "|."';
284 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
285 }
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
286
287 if @elements[$i].key eq "nth_repeat" {
56c09ce Solomon Foster Support length field and proper final bar line.
authored
288 my $final-bar = False;
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
289 say "\\alternative \{";
290 my $endings = 0;
291 loop (; $i < +@elements; $i++) {
4385d53 Solomon Foster Make $length a bit smarter.
authored
292 # say @elements[$i].WHAT;
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
293 if @elements[$i].key eq "barline"
294 && @elements[$i].value ne "|" {
295 self.SectionToLilypond(@elements[$start-of-section ..^ $i]);
296 $start-of-section = $i + 1;
56c09ce Solomon Foster Support length field and proper final bar line.
authored
297 $final-bar = True if @elements[$i].value eq '|]';
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
298 last if ++$endings == 2;
299 }
300 }
301 if $endings == 1 {
4385d53 Solomon Foster Make $length a bit smarter.
authored
302 # say @elements[$i].WHAT;
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
303 self.SectionToLilypond(@elements[$start-of-section ..^ $i]);
304 $start-of-section = $i + 1;
56c09ce Solomon Foster Support length field and proper final bar line.
authored
305 $final-bar = True if @elements[$i].value eq '|]';
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
306 }
307 say "\}";
56c09ce Solomon Foster Support length field and proper final bar line.
authored
308
309 if $final-bar {
310 say '\\bar "|."';
311 }
312
c4d049a Solomon Foster Repeats are up and running, though still a bit hacky.
authored
313 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
314 }
315
316 if $start-of-section + 1 < @elements.elems {
317 if @elements[*-1].value eq ':|:' | ':|' | '::' {
549756a Solomon Foster Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
318 print "\\repeat volta 2 "; # 2 is abitrarily chosen here!
319 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
320 self.SectionToLilypond(@elements[$start-of-section ..^ +@elements]);
56c09ce Solomon Foster Support length field and proper final bar line.
authored
321 if @elements[*-1].value eq '|]' {
322 say '\\bar "|."';
323 }
549756a Solomon Foster Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
324 }
325
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
326 say "\}";
549756a Solomon Foster Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
327 }
102ec2f Solomon Foster Refactor a bunch of the functions into a TuneConvertor class, so it is e...
authored
328
549756a Solomon Foster Make abs2ly.pl somewhat smarter about repeats and partial measures.
authored
329 }
330
29745ec Solomon Foster Crude first script to translate ABC to Lilypond.
authored
331 my $match = ABC::Grammar.parse($*IN.slurp, :rule<tune_file>, :actions(ABC::Actions.new));
332
333 say '\\version "2.12.3"';
6aeb675 Solomon Foster Add crude paper size control.
authored
334 say "#(set-default-paper-size \"{$paper-size}\")";
945131a Solomon Foster Get the key signature correct (at least for simple key signatures) but n...
authored
335
70e5a12 Solomon Foster Add "Tali Foster's" to r-star.abc file so we can easily test multiple tu...
authored
336 for @( $match.ast ) -> $tune {
337 say "\\score \{";
e6612a5 Solomon Foster Add double bar line to the grammar, and some durations longer than a dot...
authored
338
339 # say ~$tune.music;
70e5a12 Solomon Foster Add "Tali Foster's" to r-star.abc file so we can easily test multiple tu...
authored
340
341 my $key = $tune.header.get("K")[0].value;
342 my $meter = $tune.header.get("M")[0].value;
4385d53 Solomon Foster Make $length a bit smarter.
authored
343 my $length = $tune.header.get("L") ?? $tune.header.get("L")[0].value !! "1/8";
70e5a12 Solomon Foster Add "Tali Foster's" to r-star.abc file so we can easily test multiple tu...
authored
344
56c09ce Solomon Foster Support length field and proper final bar line.
authored
345 my $convertor = TuneConvertor.new($key, $meter, $length);
b561dfc Solomon Foster Refactor key signature handling a bit.
authored
346 $convertor.BodyToLilypond($tune.music);
70e5a12 Solomon Foster Add "Tali Foster's" to r-star.abc file so we can easily test multiple tu...
authored
347 HeaderToLilypond($tune.header);
348
f92e603 Solomon Foster Add tests for inline meter changes.
authored
349 say "}\n\n";
70e5a12 Solomon Foster Add "Tali Foster's" to r-star.abc file so we can easily test multiple tu...
authored
350 }
351
Something went wrong with that request. Please try again.