PostScript Music Theory

art ps

Table of Contents

PostScript experiment

You open the prophets and your eyes are able to see nothing but the letters. But what can the letters say?

They are the black bars of the prison where the spirit strangles itself with screaming.

Between the letters and the lines, and all around the blank margins, the spirit circulates freely;

and I circulate with it and bring you this great message: Friars, first came the wings and then the angel!”

— Nikos Kazantzakis - The Last Temptation of Christ (Translation by P.A. Bien)

Global Constants

/w 900 def
/h 10 def
/p 50 def

Time signature: 4/4

Because clef signs are hard to draw, on a single staff "G" is on the second line (treble).

Staff

A staff is made up of five parallel lines.

/w 900 def
/h 10 def
/p 50 def
/staff {
    5 {
        0 0 moveto
        w 0 lineto
        stroke
        0 h translate
    } repeat
} def
/w 900 def
/h 10 def
/p 50 def
/staff {
    5 {
        0 0 moveto
        w 0 lineto
        stroke
        0 h translate
    } repeat
} def
50 50 translate
staff
music_staff.png

Grand Staff

/gstaff {
    2 {
        lines
        0 50 translate
    } repeat
} def

50 50 translate
/w 900 def
/h 10 def
/p 50 def
/staff {
    5 {
        0 0 moveto
        w 0 lineto
        stroke
        0 h translate
    } repeat
} def
music_repetition.png

Repeated Bars

/lines {
    5 {
        0 0 moveto
        900 0 lineto
        stroke
        0 10 translate
    } repeat
} def

/bars {
    2 {
        0 0 moveto
        0 40 lineto
        stroke
        5 0 translate
    } repeat
} def

50 50 translate
5 {
    gsave lines grestore
    gsave
    4 {
        gsave bars grestore
        225 0 translate
    } repeat
    grestore
    0 100 translate
} repeat
music_bars2.png

Rests

/lines {
    5 {
        0 0 moveto
        900 0 lineto
        stroke
        0 10 translate
    } repeat
} def

/bars {
    2 {
        0 0 moveto
        0 40 lineto
        stroke
        5 0 translate
    } repeat
} def

50 50 translate
5 {
    gsave lines grestore
    gsave
    4 {
        gsave bars grestore
        225 0 translate
    } repeat
    grestore
    0 100 translate
} repeat

Notes

/lines {
    5 {
        0 0 moveto
        900 0 lineto
        stroke
        0 10 translate
    } repeat
} def

/bars {
    2 {
        0 0 moveto
        0 40 lineto
        stroke
        5 0 translate
    } repeat
} def

/notes {
    10 20 890 {
        rand 10 mod 7 ge {
            rand 5 mod 10 mul 5 0 360 arc closepath fill
        } if
    } for
} def

50 50 translate
5 {
    gsave lines grestore
    gsave
    4 {
        gsave bars grestore
        225 0 translate
    } repeat
    grestore
    gsave notes grestore
    0 100 translate
} repeat
music_notes.png

Note Decoration

/lines {
    5 {
        0 0 moveto
        900 0 lineto
        stroke
        0 10 translate
    } repeat
} def

/bars {
    2 {
        0 0 moveto
        0 40 lineto
        stroke
        5 0 translate
    } repeat
} def

/note {
    0 0 5 0 360 arc closepath fill
    5 0 moveto 0 30 rlineto stroke
} def

/notes {
    10 20 890 {
        rand 10 mod 7 ge {
            gsave
            rand 5 mod 10 mul translate note
            grestore
        } if
    } for
} def

50 50 translate
5 {
    gsave lines grestore
    gsave
    4 {
        gsave bars grestore
        225 0 translate
    } repeat
    grestore
    gsave notes grestore
    0 100 translate
} repeat
music_notes2.png

Beams

/lines {
    5 {
        0 0 moveto
        900 0 lineto
        stroke
        0 10 translate
    } repeat
} def

/bars {
    2 {
        0 0 moveto
        0 40 lineto
        stroke
        5 0 translate
    } repeat
} def

/note {
    0 0 5 0 360 arc closepath fill
    5 0 translate
    0 0 moveto 0 30 rlineto stroke
} def

/notes {
    /last -1 def
    10 20 890 {
        /x exch def
        rand 10 mod 7 ge {
            /y rand 5 mod def
            gsave
            x y 10 mul translate
            gsave note grestore
            last y eq {
                5 25 moveto
                -15 25 lineto
                -15 30 lineto
                5 30 lineto
                closepath
                fill
            } if
            grestore
            /last y def
        }{
            /last -1 def
        } ifelse
    } for
} def

50 50 translate
5 {
    gsave lines grestore
    gsave
    4 {
        gsave bars grestore
        225 0 translate
    } repeat
    grestore
    gsave notes grestore
    0 100 translate
} repeat
music_notes2.png

Slight Digression

/lines {
    5 {
        0 0 moveto
        100 0 lineto
        stroke
        0 10 translate
    } repeat
} def

/bars {
    2 {
        0 0 moveto
        0 40 lineto
        stroke
        5 0 translate
    } repeat
} def

/note {
    0 0 5 0 360 arc closepath fill
    5 0 translate
    0 0 moveto 0 30 rlineto stroke
} def

/notes {
    /last -1 def
    12.5 25.0 100.1 {
        /x exch def
        rand 10 mod 7 ge {
            /y rand 5 mod def
            gsave
            x y 10 mul translate
            gsave note grestore
            last y eq {
                5 25 moveto
                -20 25 lineto
                -20 30 lineto
                5 30 lineto
                closepath
                fill
            } if
            grestore
            /last y def
        }{
            /last -1 def
        } ifelse
    } for
} def


/tri {
    2 dict begin
    /y exch def
    /x exch def
    x 0 eq y 0 eq and {
        true
    } {
        x 2 mod y 2 mod mul 1 eq {
            false
        } {
            x 2 idiv y 2 idiv tri
        } ifelse
    } ifelse
    end
} def

50 50 translate
0.5 0.5 scale
0 1 16 {
    /i exch def
    gsave
    0 1 16 {
        dup
        i tri {
            2 mod 0 eq {
                gsave bars grestore
            } if
            gsave lines grestore
            gsave notes grestore
        } if
        100 0 translate
    } for
    grestore
    0 100 translate
} for
music_digression.png

If you have an idea how this page could be improved or a comment send me a mail.