Muscript Variables

Muscript is a language for typesetting music.
This page describes the use of Variables, as introduced in muscript 3.1.
This part of the syntax is still under development; future backward-compatibility is not guaranteed.


Variable Names

Variable-names begin with a $ like Perl variables. Of the remainder, the first character must be an upper-case A-Z, and the rest upper-case letters or digits 0-9. This makes the variable easy to spot within the text. Some examples:
  $A $B6 $MIDDLE8 $RIFF1 $CODA


Variable Definition

 $B4 = 8 [D G B']
 $RIFF1 = 83 [E 163 e' G G# B 83 d' 163 B 83 A 163 B] 2 rest
The variable-definition must have a line to itself. On the left hand side of the equation, the variable-name, as in Perl, has a dollar in front. The right-hand-side may contain variable references; by default, these are not substituted here at definition-time, they are substituted recursively later at substitution-time. So:
  $A = cycle? D# : F# : A ?
  $B = [$A $A]
  =1 treble $B $B $B $B
evaluates to:
  =1 treble [D# F#] [A D#] [F# A] [D# F#]

If you want to force substitution here at definition-time, use == a double equal-sign. So:
  $A = cycle? D# : F# : A ?
  $B == [$A $A]
  =1 treble $B $B $B $B
evaluates to:
  =1 treble [D# F#] [D# F#] [D# F#] [D# F#]


Multiline Variables

 $B5 = {  # comments starting with a # are allowed here
     | 4.3
     =1 treble 4 G A B c
     =2 bass   8 rest 4 g e d 8 D
 }
This allows whole sections of music to be stored in a variable. When substituted, they are considered not to start with a newline, but they are considered to finish with an inbuilt newline. Therefore whole pieces of music can be expressed on one line, e.g.:
 $OPENING $VERSE $CHORUS $VERSE $CHORUS $MIDDLE8 $VERSE $CHORUS $CHORUS

If you want to force substitution here at definition-time, use == a double equal-sign. This can lead to recursion:

 $B5 == {
    | 4.3
    $B == [$A $A]
    =1 4 G $B c $B
    =2 8 rest 4 g e d 8 D
    =1 $B $B $B $B
    $C6 == {
       $D7 == {
          $E8 = {
             $F9 == {
                =1 1 $B
             }
          }
      }
    }
    $C6
    |
    $E8
    =1 4 G $B B c
    =2 8 rest 4 g e d 8 D
 }
In this (absurd) example, the value of the $E8 and $F9 variables will only be set when $B5 is actually used; until then, $E8 and $F9 remain undefined. But the variables $B5, $B, $C6 and $D7 are defined immediately, and $B5 contains no remaining dollar-signs outside the $E8 definition.


Array Variables

To make changing the notes of a chord easier, a very restricted one-line syntax allows :

 $B2-4 = G : Bb : d
which is neater than the equivalent :
 $B2 = G
 $B3 = Bb
 $B4 = d
Only single-digit suffixes are allowed.


Generator Functions

Variables can be generated by one of a number of in-built functions:
  aaba,   cycle,   leibnitz,   morse_thue,   rabbit and   random
These functions return one of their arguments each time they are invoked; they get invoked every time the variable occurs in the text and is substituted.
  $B = rabbit? 8 [D G B'] : 8 [Eb G A] ?
Think of the question-mark as introducing the question "which?", and think of the colon : as a field-separator, like it is in /etc/passwd. (These characters are not otherwise used in muscript syntax.)
There must be no space between the function-name and the first question-mark.
Spaces inside the question-marks, or next to the colons, are stripped away: you can use them for clarity.
If you want a multi-line field, you have to define a multiline variable, then use that variable in the field.

aaba
The Aaba sequence can be generated by starting with 0 0 1 0, then repeatedly appending to it the same thing, the inverse, and the same thing again. It's reminiscent of the "Sentence" or a minimalised "Sonata-Form", but it's fractal. It needs just two arguments. The first three stages are 0 0 1 0
then:   0 0 1 0   0 0 1 0   1 1 0 1   0 0 1 0
then:
    0 0 1 0   0 0 1 0   1 1 0 1   0 0 1 0
    0 0 1 0   0 0 1 0   1 1 0 1   0 0 1 0
    1 1 0 1   1 1 0 1   0 0 1 0   1 1 0 1
    0 0 1 0   0 0 1 0   1 1 0 1   0 0 1 0
cycle
This function just generates its arguments cyclically, in a loop.
leibnitz
The Leibnitz sequence with n=2 can be generated by repeatedly appending the current sequence with one added to it. The first five stages are 0, then 0 1, then 0 1 1 2, then 0 1 1 2 1 2 2 3, then 0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4.
The Leibnitz sequence with n=3 can be generated by repeatedly appending the current sequence with one added to it and then with two added to it. The first four stages are 0, then 0 1 2, then 0 1 2 1 2 3 2 3 4, then 0 1 2 1 2 3 2 3 4 1 2 3 2 3 4 3 4 5 2 3 4 3 4 5 4 5 6.
Since it's necessary to specify n, this is done as the first argument. For example,
    $A = leibnitz? 2 : A : B : c : d : e ?
    =1 $A $A $A $A $A $A $A $A $A $A $A $A $A $A $A $A

results in:
    =1 A B B c B c c d B c c d c d d e
morse_thue
The Morse-Thue sequence is named in honour of the Norwegian mathematician Axel Thue (1863-1922) and of Marston Morse of Princeton (1892-1977).   It is now more commonly known as the Thue-Morse Sequence.
With 2 arguments, the sequence can be generated by repeatedly appending the complement; the first five stages are 0, then 0 1, then 0 1 1 0, then 0 1 1 0 1 0 0 1, then 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0.
With K=3 it can be generated by recursively by adding 1 and then 2, modulo 3. The first three stages are 0, then 0 1 2, then 0 1 2 1 2 0 2 0 1.
See: en.wikipedia.org/wiki/Thue-Morse_sequence
rabbit
The Rabbit sequence arises from Fibonacci's rabbit-problem in the Liber Abaci (1202). It needs just two arguments. The sequence can be generated by starting with the first two stages 1, then 1 0, and then appending to each stage the previous stage; so the next four stages are 1 0 1, then 1 0 1 1 0, then 1 0 1 1 0 1 0 1, then 1 0 1 1 0 1 0 1 1 0 1 1 0.
See: en.wikipedia.org/wiki/Fibonacci_word
random
The Random sequence always returns one of its elements at random.


Variable Substitution

When a variable is encountered within the music (rather than just within a recursion in a variable-definition), then it is substituted, and any new variables which appear as a result are themselves substituted, and so on recursively until there are no variable-names left at all. Then the pre-processing is complete, and the result is interpreted by muscript.


The Preprocessor

 muscript -pp filename
This -pp command-line option outputs the pre-processed text, so that you can, for example, edit it by hand.


Examples

See alberti.txt, fingerpickin.txt and generators.txt in samples/index.html


See Also

test.pl, the test-script that this version passes
index.html, the muscript home page
Fractals, Chaos, Power Laws, Manfred Schroeder, 1991, W.H. Freeman, New York
en.wikipedia.org/wiki/Thue-Morse_sequence
en.wikipedia.org/wiki/Fibonacci_word, about the Rabbit Sequence.


Peter Billam   http://www.pjb.com.au