First Sheet Music!

There were a number of comments on #perl6 on how to improve the code from my last post, but I’m ignoring them all today and forging ahead to get an actual ABC to Lilypond translator up and running. Here’s the core of the code:

sub StemToLilypond(Context $context, $stem) {
    my $match = ABC::Grammar.parse($stem, :rule<mnote>); # bad in at least two ways....
    my $pitch = ~$match<pitch>;
    my $length = ~$match<note_length>;
    print " { %note-map{$pitch} }{ %cheat-length-map{$length} } ";
sub BodyToLilypond(Context $context, @elements) {
    say "\{";
    for @elements -> $element {
        given $element.key {
            when "stem" { StemToLilypond($context, $element.value); }
            when "barline" { say " |"; }
    say "\}";

This code is wrong for a host of reasons. But the cool thing is, for simple tunes, it very nearly works. Basically, we go through the list of musical elements in the tune. When we see a barline, we output a bar line to Lilypond. When we see a stem, we parse it again (ugh) assuming it is the simple form a a stem, then map the pitch portion to the equivalent Lilypond note (ignoring key signature and accidentals), and the rhythm portion to the equivalent Lilypond duration (assuming that the ABC is notated in 8ths, and ignoring almost all potential complexity). This crude approximation almost suffices to properly notate “The Star of Rakudo”!

Here’s the PDF Lilypond outputs when feed the output of this script. At first glance this looks pretty good, but actually it’s got one major issue (as well as a host of minor ones). I think it might be obvious even to those who don’t read sheet music if it is compared to this proper PDF: the notes are all correct, but they are shifted one eighth note off in the measures! This is because Lilypond apparently treats bar lines in the source code as a mere debugging aid — if they don’t agree with what it thinks they should be, it will issue a warning and then go with what it thinks rather than what you said. I guess that behavior might make sense in big orchestral scores, but it is just annoying at this level.

So, what needs to be done to make this tune work:
1) Detect pick up bars and send the \partial command to Lilypond so that it keeps the bar lines in the correct places.

2) Preprocess the music looking for repeats, so that the repeated section can be properly marked for Lilypond.

3) Handle the key signature correctly.

4) Handle the ~ gracing, which in should generate a turn symbol over the note. (Used here to indicate an Irish-style roll.)

It appears to me that these are straightforward programming problems, so I’m going to forge ahead and see what I can do…

One Response to “First Sheet Music!”

  1. ABC Update « Just Rakudo It Says:

    […] on it here, as the changes have been pretty straightforward. All of the goals at the end of my First Sheet Music post have now been achieved. Here’s the latest version of “The Star of Rakudo” […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: