Beethoven: Piano Sonata No. 14 in C♯ minor, Op. 27, No. 2

This example demonstrates parallel parts and various control structures.

The first measures of Beethoven’s Piano Sonata No. 14 in C♯ minor, Op. 27, No. 2, commonly known as Moonlight Sonata, have the following score representation:

In MPS, this can be represented in terms of individual contextual layers as depicted below (click to enlarge):

An equivalent context tree model using nested repetitions and other control structures looks like this (click to enlarge):

The arpeggios in the right hand are automatically generated by an arpeggio generator. It is configured with a start inversion (2, where 0 is the base inversion, 1 the first inversion and 2 the second inversion) and finds the nearest inversion of following harmonies (which are defined in the harmonic progression context) automatically. In this way, all the notes in the right hand can be algorithmically generated.

The left hand part is specified by using a pitch expression, which is a function call (getBassNote()). This expression evaluates to the current bass note defined by the current harmonic context, which changes over time in this model. The evaluated note is extended to a simultaneously sounding octave using a parallelInterval modifier.

The basic descriptions of the right and left hand were extracted into individual fragments named chordArpeggio (right hand) and bassOctaves (left hand). These are referenced from different contexts, which are nested in repetition control structures in order to invoke the two fragments an appropriate number of times.

The language representation of this model is:

composer "Ludwig van Beethoven"
title "Piano Sonata No. 14 in C♯ minor, Op. 27, No. 2"

composition
{
    instrument piano, time 2/2, tempo 54, loudness pp, key C#m
    {
        harmonicProgression C#m C#m/B A D/F# G#7-D# C#m/G# G# sus4 G#7-G#_3
        {
            harmonicRhythm 1 1 2 2 4 4 4 4
            {
                repeat 2
                {
                    parallel
                    {
                        repeat 4
                        {
                            fragmentRef chordArpeggio
                        }
                        rhythm 1
                        {
                            fragmentRef bassOctaves
                        }
                    }
                }
                repeat 4
                {
                    parallel
                    {
                        repeat 2
                        {
                            fragmentRef chordArpeggio
                        }
                        rhythm 2
                        {
                            fragmentRef bassOctaves
                        }
                    }
                }
            }
        }
    }

}

fragment chordArpeggio
{
    rhythm (3/2 : 8 8 8)
    {
        arpeggioGenerator startInversion 2 startOctave 3 findNearestInversion true noteIndexSequence 0 1 2
    }
}

fragment bassOctaves
{
    pitches (startOctave 3 findNearestOctave true) @getBassNote()
    {
        parallelInterval mode octaves -1
    }
}

The source code and the corresponding representations shown in this example are also available in the github example repository.