Recently I added chords to Deltaphone, which required me to rethink how I was structuring the blocks to play notes. Previously, the
play block came in two forms. There was a form for an absolutely-specified note, like “play C natural in the fourth octave.” And there was a form for a relatively-specified note, like “play the note 2 halfsteps up from where I’m currently at on the staff.” They looked like this:
How do I add chords to this? My first attempt was to add a new
chord statement that accepted a stack of
play statements. Something like this:
But this structure has two problems. First, a chord generally should have all of its notes be of the same duration. (The MusicXML docs agree.) Each
play block has its duration specified separately and is therefore vulnerable to getting out of sync with its siblings. Second, other statements can be nested inside the chord, like
repeat blocks, which is nonsense.
I decided instead to generalize the
play to a single block that could play absolute notes, relative notes, or chords. Polymorphism fixes everything, right? The new block looked like this in its different contexts:
But after using this new
play block to compose some simple songs, it felt too heavyweight. I want to be able to take Deltaphone into an elementary school classroom, and I expected that the polymorphic solution would require too much explanation. But I still needed a way to play chords. So, I decided to keep all three forms of the
See them at work as I program the stepping-up-and-stepping-down exercise:
The exercise ends with three chords: a I chord, a V7 chord, and a I chord. With chords, only the root note has any long-term effect on the “cursor” that marks our current position on the staff.