Sep 30

LilyPond with Frescobaldi: open source music engraving

LilyPond is open source music engraving software. LilyPond “…was designed to solve the problems we found in existing software and to create beautiful music that mimics the finest hand-engraved scores.” It produces some of the finest looking scores you can imagine, and almost any style of note or notation you can imagine. But it’s a scripting language—which for many people makes it very difficult to learn, and much too tedious to use. Enter Frescobaldi.

Frescobaldi is an open source editing tool for LilyPond. I won’t pretend there’s no learning curve, but if you want to print absolutely stunning music scores and enjoy learning technology it’s worth it, and I’ll help you get started. And if you’re a music educator I’ll make some suggestions about how I might use this in teaching, albeit at a high school level or higher, with students who have already learned the basics of reading. Thanks to Frescobaldi’s built-in MIDI player I see applications to ear training, as well as more obvious help with general notation problems. I’ve also screen-recorded some of my first explorations, and I intend to edit them down and add audio, and continue with a video tutorial, hopefully in just a few days.

Both programs run on Windows, Mac or Linux, but there’s no Mac or Linux installer for Frescobaldi, so if you’re not running Windows you may need some extra skills there. First, download and install both programs using the links below. You will not need to launch LilyPond. You’ll launch Frescobaldi, tell it where to find LilyPond and Frescobaldi will take it from there.

Software links

LilyPond is a music engraving program, devoted to producing the highest-quality sheet music possible. Download

Frescobaldi is a LilyPond sheet music text editor. It aims to be powerful, yet lightweight and easy to use. Download

  1. On first launch Frescobaldi opens an empty document. You type and insert LilyPond code in the left Editor panel and then press the LilyPond icon ion the toolbar to render a gorgeous PDF in the right, or Music View panel. hide image Screen shot
  2. Choose EditPreferences… show image
  3. Set path to LilyPond show image
    Windows default: C:/Program Files (x86)/LilyPond/usr/bin/lilypond-windows.exe
  4. Choose ToolsPreferencesSetup New Score… (Ctrl+Shift+N) to open the Score Setup Wizard show image
     Other items on this list will be of great interest soon… I used the Quick Insert tool and the MIDI Player early in my very first score.

    The Score Setup Wizard lets you set the following up front—especially recommended your first time, as once you create the file you’ll need to get code snippets from the documentation, the other tools in the Tools menu, another file, or know what to type.
     You might even want to fill in all the fields and save a MasterSnippet.ly file for later reference. Frescobaldi also has its own built-in Snippets manager.

    1. Titles and Headers show
    2. Parts show
    3. Score Settings show
       Be sure to try the Preview button!

To get started I just picked 8 bars of a Stevie Wonder tune I happened to have loaded in iTunes. You can see the first 2 bars of the lick on the right of the screen shot below. The script on the left side, which you’d have to write from scratch without an editor, demonstrates rather aptly I think, why a tool like Frescobaldi can likely make LilyPond more useful to a much larger community. What will be much easier to demonstrate in a video tutorial is how I copy/pasted a snippet of code from the documentation into the editor and then tweaked it until I got what I wanted. The notes you see on the right are formed entirely by this part of the script on the left. 'is' as a sharp is not intuitive (unless you speak Dutch), but now that I’ve told you perhaps you can see the 4, 8 and 16 that sets note values, ‘r’ for rest, and the lower case note names, key of B Major. The tildes (~) create the ties, and I entered staccato and accents using the Quick Insert tool shown in the left panel of the final screen shot below.
 All your music goes immediately after the % Music follows here. and before the closing curly brace (}) that lines up flush left with the instrument name above it and the code \score below it (see both screen shots beneath the following code snippet).

// You can group and nest notes in curly braces for readability.
// Here I've grouped each beat within each measure on its own line.
{
{b4-.} {r16 b16 dis cis->~}  {cis-. cis16 gis' fis->~} {fis8-. fis,16 gis}
}
{
{b8->-. cis16 cisis16} {dis16 fis gis b->~}  {b16 cis16 cisis dis->~} {dis4-.}
}

Screen shot

By the time I’d finished I’d opened the MIDI Player to check my work. You need to press the Engrave button to refresh the output on the right (there are further options under the LilyPond menu). Frescobaldi supplies the bar lines based on the time signature in the score settings, and plays audio—I feel those two facts have pedagogical implications. I slowed down my 8-bar passage using Audacity, played them side by side, and by refreshing the output was able to see and hear what I had right and wrong along the way.
Screen shot
I hope this is enough to pique your interest. There’s another LilyPond editor I plan to try soon too, Denemo, highlighted with even more on the LilyPond site. It looks quite sophisticated, but I can tell I’ve barely scratched the surface of Frescobaldi, which was intuitive enough out of the box to keep me intrigued and progressing—getting this far was fun! Please use the comments section and stay tuned for some video tutorials as I get in further.

§

Richard studied as a teenager with Trevor Payne at John Abbott College and attended Berklee College of Music in Boston. He has performed across Canada with full-time rock bands since the early 80s. He’s been a teacher of rock, jazz & classical guitar at the now defunct Toronto Percussion Centre, and at The Arts Music Store for many years. He holds the degrees of Bachelor of Fine Arts Music (Special Honours), Bachelor of Education, and Master of Education from York University, plays guitar and trombone, and taught grade 6-8 band at the Toronto District School Board and North York School Board.

Bookmarklets update

Aside

Last June I explored “bookmarklets,” which I’ve found to be an engaging way to explore JavaScript, primarily by leveraging the power of pet peeves—enticing novice learners to change something they don’t like about a web page to be more the way they’d like it to be. As an example I offered a simple script that toggles the visibility of the ads on a Facebook home page.

javascript:(function()
{
  var 
  rCol=document.getElementById('rightCol'),
  isHidden=rCol.style.visibility==='hidden'?true:false;
if(isHidden)
  {
    rCol.style.visibility='visible'
  }
else
  {
    rCol.style.visibility='hidden'
  }
})();
To actually use this as a bookmarklet, first remove all the line breaks and optimize spaces.

Such a snippet can lead to a discussion of the differences between CSS display and visibility or more advanced ideas like native functions and how and when to import external libraries. My bookmarklet soon evolved into the next snippet, which uses an updated id and display:none;

javascript:(function(){var%20adsDiv=document.getElementById('pagelet_side_ads'),isHidden=adsDiv.style.display==='none';if(isHidden){adsDiv.style.display='inline-block';}else{adsDiv.style.display='none';}})();

This worked fine on the Home page, but not elsewhere. Looking into it with Firebug you quickly see the id is different—on a Messages page, for example, it’s pagelet_ego_pane. You might try simply adding a conditional, if it’s not 'pagelet_side_ads' try ‘pagelet_ego_pane’. But this will fail in JavaScript when the document.getElementById method can’t find the id it’s looking for. While there are elegant advanced ways to do this, and we don’t know how many different ids there might be, I followed the learner’s first suggestion and let it turn into an introduction of try/catch blocks and error handling. These work as follows:

try
  { /*something. If it fails...*/ }
catch(errorObjectName)
  {/*report the error and/or try something else*/}

The errorObjectName is usually error and you can retrieve error.message from it, amongst other things.

If at first you don’t succeed, try/catch again

Here’s the expanded code that tries to find an element with id="pagelet_side_ads" and if that returns and error, it catches that and “tries” again with id="pagelet_ego_pane". If that fails it attempts to log that information to the console. Notice I didn’t say “tries” as there’s no additional try/catch block and I want to avoid using the same word with two meanings. What do you think would happen if the browser has no console object containing a log() method? Below the expanded version is a single line version of the same code (except generic console.log() has been refined to console.error() see this link) to use, as expanded code doesn’t work in this context.

javascript:
(function() 
{
  try
    {
      var adsDiv=document.getElementById('pagelet_side_ads'),
          isHidden=adsDiv.style.display==='none';
      if (isHidden) 
      {
        adsDiv.style.display='inline-block';
      }
      else
      {
        adsDiv.style.display='none';
      }
     }
  catch(e) 
  {
    try 
    {
      var adsDiv=document.getElementById('pagelet_ego_pane'),
          isHidden=adsDiv.style.display==='none';
      if (isHidden) 
      {
        adsDiv.style.display='inline-block';
      }
      else 
      {
        adsDiv.style.display='none';
      }
    }
    catch(e)
    {
      console.log('Failed. Message: ',e.message)
    }
   }
})();

Single line version for general use:

javascript:(function(){try{var adsDiv=document.getElementById('pagelet_side_ads'),isHidden=adsDiv.style.display==='none';if(isHidden){adsDiv.style.display='inline-block';}else{adsDiv.style.display='none';}}catch(e){ try{var adsDiv=document.getElementById('pagelet_ego_pane'),isHidden=adsDiv.style.display==='none';if(isHidden){adsDiv.style.display='inline-block';}else{adsDiv.style.display='none';}}catch(e){console.warn('toggleFBAds failed. Message:',e.message,'. This can mean the id was not found.')}}})();

Drag it to your Bookmarks toolbar: Toggle FB ads

You wouldn’t want to nest try/catch blocks in catch statements endlessly, so you might extend this into lessons on arrays, loops, recursion… that depends on you and your learners’ situation.

§

Further reading

console on the Mozilla Developer Network

try…catch on the Mozilla Developer Network