slippery chicken documentation - "primary disposition" &emdash; core usage

## "Primary Disposition" — A guide to the core usage of slippery chicken

### + Associated files

- The slippery-chicken file from this guide
- The MIDI output generated by this file
- The PDF score produced with this file's LilyPond output
- The CMN EPS output generated by this file
- An MP3 of the piece using instrument samples

close

NB: An exercise relating to the material covered in this tutorial can be found on the Exercises page.

This document assumes you have familiarised yourself with the overview and essential concepts of slippery chicken.

The following is a brief introduction to the most basic use of slippery chicken's core features. In this example all of the set palettes and maps, rhythm palettes and maps, pitch contours, articulation, and dynamics are entered by hand. This should provide the beginning user with an understanding of the framework that underlies slippery chicken. More advanced users will most probably begin replacing the hand-typed data with Lisp routines that will generate it for them.

While slippery chicken is not limited to any specific style, it has so far been used for abstract, atonal, and microtonal avant-garde compositions. This first example, however, will be a piece in a slightly more minimalist style.

### + The code

The code is first presented on its own here, then explained point by point below.

NB: It is strongly recommended that the user not copy and paste code from the web browser into the Lisp listener, as this can occasionally lead to errors. The code below can be downloaded in complete form under the Associated files section above.

    (in-package :sc)

    (in-scale :chromatic)

    (make-slippery-chicken
     '+primary-disposition+
     :title "Primary Disposition"
     :instrument-palette +slippery-chicken-standard-instrument-palette+
     :ensemble '(((flt (flute :midi-channel 1))
                  (clr (b-flat-clarinet :midi-channel 2))
                  (vln-one (violin :midi-channel 3))
                  (vla (viola :midi-channel 4))
                  (cel (cello :midi-channel 5))))
     :staff-groupings '(2 3)
     :tempo-map '((1 (q 84)))
     :set-palette '((set1 ((fs2 b2 d4 a4 d5 e5 a5 d6)))
                    (set2 ((b2 fs3 d4 e4 a4 d5 e5 a5 d6)))
                    (set3 ((cs3 fs3 e4 a4 e5 a5 e6)))
                    (set4 ((fs2 cs3 e4 a4 b4 e5 a5 b5 e6))))
     :set-map '((1 (set1 set1 set2 set1 set2))
                (2 (set2 set2 set3 set2 set3 set2 set3))
                (3 (set3 set2 set4 set2 set4 set3 set4 set4 set2 set3 set4))
                (4 (set4 set1 set4 set1 set4 set1 set1)))
     :set-limits-high '((vla (0 b4 100 b4))
                        (cel (0 f4 100 f4)))
     :rthm-seq-palette
     '((seq1 ((((4 4) - 16 16 8 - { 5 - 20 10 20 20 - } { 3 3 6 } )
               ( - s s s s - (s) - s s s - - +e. s - q))
              :pitch-seq-palette (1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9)
              :marks (mp 1 a 1 s 3 slur 1 3 a 4 slur 4 7 s 9 a 10 slur 16 18)))
       (seq2 ((((4 4) - e e - - s s s s - (s) s (s) s { 3 - te te te - } )
               ( - s s s - (s)  { 3 - te te - (te) } q \+8 (e) ))
              :pitch-seq-palette (11 10 9 11 10 8 7 11 10 6 5 11 10 9 8 7 11)
              :marks (mf 1 s 1 2 a 3 slur 3 4 a 5 slur 5 6 s 7 s 8 a 9
                         slur 9 11 a 12 slur 12 14 s 15 16 a 17)))
       (seq3 ((((4 4) { 3 - te te te - } - e e - - s s s s - (s) s (s) s )
               (- s s s s - - s s s s - { 3 - te te te - } { 3 - +te te te - } ))
              :pitch-seq-palette (1 2 1 2 3 1 2 3 4 5 6 1 2 3 5 4 4 4 2 7 5 4 5 6)
              :marks (f 1 slur 1 3 a 4 s 4 5 slur 6 7 slur 8 9 s 10 11
                        slur 12 13 slur 14 15 a 16 slur 18 19 slur 20 21 a 22
                        slur 24 25)))
       (seq4 ((((4 4) - s s (s) s - - s s - (e) - e s - (s) { 3 - te te te - } )
               ( { 5 - 10 10 20 - } - +s s s s - (e) - e+32 32 s s s - ))
              :pitch-seq-palette (4 5 4 4 5 4 5 4 7 13
                                    17 15 14 15 11 12 13 4 5 7 8)
              :marks (ff 1 slur 1 2 s 3 slur 4 5 a 6 slur 8 10 s 10 a 11 s 11
                         a 12 s 12 slur 13 15 slur 16 17 a 18 slur 19 22))))
     :rthm-seq-map
     '((1 ((flt (seq1 seq1 seq2 seq1 seq2))
           (clr (seq1 seq2 seq1 seq2 seq1))
           (vln-one (seq1 seq1 seq2 seq1 seq2))
           (vla (seq1 seq2 seq1 seq2 seq1))
           (cel (seq1 seq1 seq2 seq1 seq2))))
       (2 ((flt (seq1 seq1 seq2 seq1 seq2 seq1 seq2))
           (clr (seq1 seq1 seq3 seq1 seq3 seq1 seq3))
           (vln-one (seq2 seq2 seq3 seq2 seq3 seq2 seq3))
           (vla (seq2 seq2 seq1 seq2 seq1 seq2 seq1))
           (cel (seq3 seq3 seq2 seq3 seq2 seq3 seq2))))
       (3 ((flt (seq1 seq1 seq2 seq1 seq2 seq1 seq2 seq2 seq1 seq2 seq2))
           (clr (seq2 seq2 seq3 seq2 seq3 seq2 seq3 seq3 seq2 seq3 seq3))
           (vln-one (seq3 seq3 seq4 seq3 seq4 seq3 seq4 seq4 seq3 seq4 seq4))
           (vla (seq4 seq4 seq3 seq4 seq3 seq4 seq3 seq3 seq4 seq3 seq3))
           (cel (seq4 seq4 seq2 seq4 seq2 seq4 seq2 seq2 seq4 seq2 seq2))))
       (4 ((flt (seq4 seq3 seq4 seq1 seq4 seq1 seq1))
           (clr (seq3 seq2 seq3 seq2 seq1 seq2 seq1))
           (vln-one (seq2 seq1 seq1 seq1 seq2 seq1 seq1))
           (vla (seq4 seq3 seq4 seq2 seq1 seq1 seq1))
           (cel (seq2 seq2 seq2 seq1 seq2 seq1 seq1))))))

    (midi-play +primary-disposition+ :midi-file "/tmp/primary-disposition.mid")

    (cmn-display +primary-disposition+ :file "/tmp/primary-disposition.eps")

    (write-lp-data-for-all +primary-disposition+ :base-path "/tmp/")

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;;; EOF primary-disposition.lsp

close

### The code explained

#### Setting the environment

The first two lines in this example set two global parameters of the Lisp environment in which slippery chicken will generate the musical data and any accompanying output. It is encouraged to include these in each slippery chicken file.

The first of these:

    (in-package :sc)

…instructs the Lisp environment to process the following code within the `sc` (slippery chicken) package.

The second:

    (in-scale :chromatic)

…instructs slippery chicken to use the `chromatic` scale as the `#<tuning>` environment when processing all note-name symbols. See the page on note-names and scales for more detail on global `#<tuning>` environments.

#### The call to make-slippery-chicken

First the `make-slippery-chicken` function is called. This creates a slippery chicken object, which holds all of the data necessary to generate the piece.

    (make-slippery-chicken

The first argument to the make-slippery-chicken function is a global variable that is defined for the music created (the slippery chicken object). The global nature of this variable allows for editing and manipulating the musical data after it is has been generated.

     '+primary-disposition+

The next argument sets the title of the composition, which is used both for the title of the piece within the generated sheet music output as well as for the names of the LilyPond files automatically generated by slippery chicken (if that feature is used).

     :title "Primary-Disposition"

#### The instruments and ensemble

Next, the instruments and ensemble are specified. The ensemble is made up of players, each of which can be assigned one or more instruments. For this example, each player plays only one instrument.

##### Instruments

The `instrument-palette` argument points to the `instrument-palette` used for the given piece. An `instrument-palette` contains the list of `instrument` objects used in the ensemble, with definitions of attributes such as pitch ranges, transpositions, and score names and abbreviations, etc. This piece uses the `+slippery-chicken-standard-instrument-palette+`, which is defined in the file `instruments.lsp` and automatically assigned to this global variable when slippery chicken is loaded.

     :instrument-palette
            +slippery-chicken-standard-instrument-palette+

A description of how to modify the attributes of instruments in a given palette for the scope of a given composition, as well as how to create a new palette or combine existing palettes, can be found on the page on tailoring instrument definitions.

##### Ensemble

In the `ensemble` block, IDs are defined for each of the ensemble's players, and instruments from the `instrument-palette` are then assigned to each player. Indications for the MIDI channels on which the instruments are to be played back can be entered here as well, if MIDI output is desired. The ID chosen by the user for the player (e.g. `flt`) can be any arbitrary alpha-numeric combination, and will be used as a reference within the `rthm-seq-map` section of the call to the `make-slippery-chicken` function later. The name of the instrument must be the ID of the given `instrument` object exactly as it is defined in the `instrument-palette` used.

NB: If LilyPond is to be used for printable output, the names chosen for the ensemble's players cannot contain numbers (e.g. `violin1`), as LilyPond's parser does not accept them. One option is to use hyphenated alphabetical characters instead, such as `violin-one`. Note that this does not refer to staff-names of instruments, just the symbol that identified a player in the `ensemble`, `rthm-seq-palette`, etc.

     :ensemble '(((flt (flute :midi-channel 1))
                  (clr (b-flat-clarinet :midi-channel 2))
                  (vln-one (violin :midi-channel 3))
                  (vla (viola :midi-channel 4))
                  (cel (cello :midi-channel 5))))

##### Staff groupings for printed output

Should printed output be desired, the staff grouping layout of the score can be indicated using the `:staff-groupings` argument. This argument takes a list of the number of consecutive players grouped together from top to bottom, as they appear in the `ensemble` block. Thus, the following code indicates that in the score, the players of the ensemble are to be grouped into 2 instruments, and 3 instruments (`flt` with `clr`, and `vln-one, vla, cel`).

     :staff-groupings '(2 3)

#### Tempo

The next argument is used to set the tempo. This example uses the `:tempo-map` argument for this purpose (see the page on tempo for other options). The `:tempo-map` argument takes a list of 2-item lists. The first item in each of these lists is the measure number at which the subsequent tempo indication is to begin. A starting tempo attached to the first measure at the very least must be specified here. The second item is the tempo indication itself, which takes a beat-type indicator paired with the number of beats per minute. The beat-type can be indicated using either numeric (e.g. `4` for a quarter-note) or alphabetic rhythm representations (e.g. `q` for a quarter note). (See the page on rhythms for more detail on rhythmic representations in slippery chicken).

The `tempo-map` stated here thus means that the tempo will be quarter = 84 starting in measure 1. This example will use just one tempo for the entire piece.

     :tempo-map '((1 (q 84)))

#### Pitch collections

The pitch (or "set") data for a given piece is entered in the `set-palette` and `set-map` blocks. Each of the sets in the `set-palette` block defines a limited collection of pitches. The first element of each list in the `set-palette` block is the set's ID, which is chosen by the user and can consist of any alpha-numeric combination. This ID will then be referenced from within the `set-map` block when mapping the sets to the piece's structure. The pitches are entered here using the note-naming conventions spelled out in the documentation for note-names and scales.

This example defines pentatonic sets:

     :set-palette '((set1 ((fs2 b2 d4 a4 d5 e5 a5 d6)))
                    (set2 ((b2 fs3 d4 e4 a4 d5 e5 a5 d6)))
                    (set3 ((cs3 fs3 e4 a4 e5 a5 e6)))
                    (set4 ((fs2 cs3 e4 a4 b4 e5 a5 b5 e6))))

The `set-map` block then determines which sets of pitches are available for each sequence in the piece. Any given sequence will contain only pitches from the corresponding set referred to in the `set-map` for that sequence.

The first number of each list in the `set-map` is the ID assigned to that section of the piece, and corresponds to the section ID of the other `-maps` in the `slippery-chicken` object being created. Section IDs must be numerical values only. The list following the section ID is a series of the IDs defined for the sets in the `set-palette`. These can be used in any order in the `set-map`. They apply to the entire ensemble for the corresponding sequence within the composition.

     :set-map '((1 (set1 set1 set2 set1 set2))
                (2 (set2 set2 set3 set2 set3 set2 set3))
                (3 (set3 set2 set4 set2 set4 set3 set4 set4 set2 set3 set4))
                (4 (set4 set1 set4 set1 set4 set1 set1)))

##### Limiting an instrument's pitch range

The pitch ranges of the instruments in the `+slippery-chicken-standard-instrument-palette+` are defined to include the absolute spectrum of pitches available to the instruments. This can occasionally result in slippery chicken choosing pitches from the extreme ends of the pitch ranges. A number of options are available for addressing this. For this piece, `set-limits-high` is used to limit the upper range of the cello to `F4` and that of the viola to `B4`.

     :set-limits-high '((vla (0 b4 100 b4))
                        (cel (0 f4 100 f4)))

See the page on pitches for more details on the usage of `:set-limits-high` and `:set-limits-low`.

#### Rhythms

The rhythmic data for the piece is defined in the `rthm-seq-palette`. The `rthm-seq-palette` consists of a list of rhythm sequences (`rthm-seq` objects), which are enclosed in separate sets of parentheses. As with the `set-palette`, each `rthm-seq` is given an ID by the user, and these IDs too can consist of any alpha-numeric combination.

The individual `rthm-seq` objects consist of a list of numbers and/or letters that represent rhythmic durations. Each `rthm-seq` can be one or more measures long, and each measure may start with a time signature (see the documentation on the rthm-seq object for more detail on how to construct a `rthm-seq`). Rhythmic values can be written in numeric form or using the alphabetic nomenclature (see the documentation on rhythms for more detail on rhythm-naming conventions).

     :rthm-seq-palette
    '((seq1 ((((4 4) - 16 16 8 - { 5 - 20 10 20 20 - } { 3 3 6 } )
               ( - s s s s - (s) - s s s - - +e. s - q))

### Pitch curves

Each `rthm-seq` in the `rthm-seq-palette` also requires indications for the melodic contour of the pitches that slippery chicken will automatically assign to the rhythms it contains. This is done by defining a `pitch-seq-palette` within each `rthm-seq`.

The list of numbers in the `pitch-seq-palette` represent a general pitch linear contour that is scaled to the available pitches for each instrument playing that `rthm-seq` in any given sequence. The difference between two consecutive numbers in the `pitch-seq-palette` indicates the direction and relative size of the interval between the corresponding two pitches selected by slippery chicken. The actual pitches selected by slippery chicken from the current set will depend on a number of factors, including the range of the instrument playing them.

See the page on pitches for more on understanding pitch-seq curves and more detail on how slippery chicken selects pitches.

                :pitch-seq-palette (1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9)

### Articulation, dynamics, slurs

Indications for articulation, dynamics, slurs and many performance techniques for both CMN and LilyPond output can also be enclosed within each individual `rthm-seq` of the `rthm-seq-palete`. This is done using the `:marks` keyword followed by a list of the marks to be added (such as `a` for an accent or `s` for staccato) paired with index numbers for the specific `rhythm` items within the `rthm-seq` to which the marks are to be attached.

More about adding marks to a score can be found on the page about articulation, dynamics, and performance techniques. A list of the marks available can be found on the tables of marks portion of that same page.

NB: Marks are attached to `rhythm` items of the `rthm-seq`, and not to items in the `pitch-seq` of the `pitch-seq-palette`. Two tied rhythmic values are counted as separate items for this function.

     :marks (mp 1 a 1 s 3 slur 1 3 a 4 slur 4 7 s 9 a 10 slur 16 18)))

The rest of the `rthm-seq-palette` in this example is constructed in the same manner:

       (seq2 ((((4 4) - e e - - s s s s - (s) s (s) s { 3 - te te te - } )
               ( - s s s - (s)  { 3 - te te - (te) } q \+8 (e) ))
              :pitch-seq-palette (11 10 9 11 10 8 7 11 10 6 5 11 10 9 8 7 11)
              :marks (mf 1 s 1 2 a 3 slur 3 4 a 5 slur 5 6 s 7 s 8 a 9
                         slur 9 11 a 12 slur 12 14 s 15 16 a 17)))
       (seq3 ((((4 4) { 3 - te te te - } - e e - - s s s s - (s) s (s) s )
               (- s s s s - - s s s s - { 3 - te te te - } { 3 - +te te te - } ))
              :pitch-seq-palette (1 2 1 2 3 1 2 3 4 5 6 1 2 3 5 4 4 4 2 7 5 4 5 6)
              :marks (f 1 slur 1 3 a 4 s 4 5 slur 6 7 slur 8 9 s 10 11
                        slur 12 13 slur 14 15 a 16 slur 18 19 slur 20 21 a 22
                        slur 24 25)))
       (seq4 ((((4 4) - s s (s) s - - s s - (e) - e s - (s) { 3 - te te te - } )
               ( { 5 - 10 10 20 - } - +s s s s - (e) - e+32 32 s s s - ))
              :pitch-seq-palette (4 5 4 4 5 4 5 4 7 13
                                    17 15 14 15 11 12 13 4 5 7 8)
              :marks (ff 1 slur 1 2 s 3 slur 4 5 a 6 slur 8 10 s 10 a 11 s 11
                         a 12 s 12 slur 13 15 slur 16 17 a 18 slur 19 22))))

### The structure

The last major block of the `make-slippery-chicken` function is the `rthm-seq-map`. This is where the individual `rthm-seq` objects, with their pitch contours and marks, are assembled into the desired order to create the structure of the piece.

There must be exactly the same number of sections in this map as there are in the `set-map`, and the section IDs must be the same. Following the section ID, the first item in each list of a given section is then the player (e.g. `flt`), as named in the `ensemble` block. The items within the lists associated with each player must consist of IDs assigned to the individual `rthm-seq` objects in the `rthm-seq-palette`. There must be exactly the same number of `rthm-seq` IDs for each player of each section as there are set IDs in the `set-map` for the corresponding section.

All simultaneously occurring `rthm-seq` objects in the `rthm-seq-map` must be of equal length—i.e. same number of bars and same metrical structure. For this piece, all `rthm-seq` objects have been made equal in length and meter in the `rthm-seq-palette` so that all combinations are possible.

See the documentation on rthm-seq-maps for more detail.

     :rthm-seq-map
     '((1 ((flt (seq1 seq1 seq2 seq1 seq2))
           (clr (seq1 seq2 seq1 seq2 seq1))
           (vln-one (seq1 seq1 seq2 seq1 seq2))
           (vla (seq1 seq2 seq1 seq2 seq1))
           (cel (seq1 seq1 seq2 seq1 seq2))))
       (2 ((flt (seq1 seq1 seq2 seq1 seq2 seq1 seq2))
           (clr (seq1 seq1 seq3 seq1 seq3 seq1 seq3))
           (vln-one (seq2 seq2 seq3 seq2 seq3 seq2 seq3))
           (vla (seq2 seq2 seq1 seq2 seq1 seq2 seq1))
           (cel (seq3 seq3 seq2 seq3 seq2 seq3 seq2))))
       (3 ((flt (seq1 seq1 seq2 seq1 seq2 seq1 seq2 seq2 seq1 seq2 seq2))
           (clr (seq2 seq2 seq3 seq2 seq3 seq2 seq3 seq3 seq2 seq3 seq3))
           (vln-one (seq3 seq3 seq4 seq3 seq4 seq3 seq4 seq4 seq3 seq4 seq4))
           (vla (seq4 seq4 seq3 seq4 seq3 seq4 seq3 seq3 seq4 seq3 seq3))
           (cel (seq4 seq4 seq2 seq4 seq2 seq4 seq2 seq2 seq4 seq2 seq2))))
       (4 ((flt (seq4 seq3 seq4 seq1 seq4 seq1 seq1))
           (clr (seq3 seq2 seq3 seq2 seq1 seq2 seq1))
           (vln-one (seq2 seq1 seq1 seq1 seq2 seq1 seq1))
           (vla (seq4 seq3 seq4 seq2 seq1 seq1 seq1))
           (cel (seq2 seq2 seq2 seq1 seq2 seq1 seq1))))))

### The output

The `make-slippery-chicken` function allocates all of the musical data it generates to a global variable created from the first argument that it is passed. This makes it possible to generate the various forms of output separately, after the generation of the musical data, as is seen here.

More information on the various forms of output can be found on the output page.

#### MIDI

MIDI output can be generated by slippery chicken using the `midi-play` method. This method takes as its only required argument the global variable defined as the first argument to the `make-slippery-chicken` function. The other argument specified here, `:midi-file`, is the directory path and file name for the output to be generated (which defaults to "/tmp/sc.mid" if not specified). The file name should end with the suffix `.mid` for ease of opening after generation.

    (midi-play +primary-disposition+ :midi-file "/tmp/primary-disposition.mid")

See the User Guide entry for MIDI for more details on the other arguments to `midi-play`.

#### Common Music Notation

The first printable output option in this example is that of Common Music Notation using the `cmn-display` method. This method, too, takes as its first argument the variable defined as the first argument to the `make-slippery-chicken` function. The `:file` argument allows the user to specify the directory path and file name for the output generated. CMN produces encapsulated post-script files, so adding the `.eps` suffix to the file name will facilitate opening the file later.

    (cmn-display +primary-disposition+ :file "/tmp/primary-disposition.eps")

See the User Guide entry for CMN for more details on the other arguments to `cmn-display`.

#### LilyPond

On OSX with SBCL we can call `lp-display` to generate score PDFs via Lilypond. This itself is a wrapper for `write-lp-data-for-all`: after calling that method, `lp-display` calls Lilypond and then opens the PDF automatically. `lp-display` takes all the same arguments as `write-lp-data-for-all`. As that method works in all Lisps on all systems we will confine all of the Lilypond functionality documentation here and elsewhere to it.

The `write-lp-data-for-all` method produces all of the files LilyPond needs to typeset the given musical data. As with the other output methods, this method takes as its first argument the variable defined as the first argument to the `make-slippery-chicken` function. The `write-lp-data-for-all` method generates its output file names automatically based on the `title` slot of the given `slippery-chicken` object. Because of this, the method requires only the base directory path, and not the file name, if the output path is specified by the user.

NB: LilyPond can take a long time to render output, during which time it is unresponsive and may appear to have hung or frozen.

NB: See note above about Lilypond and instrument names.

    (write-lp-data-for-all +primary-disposition+ :base-path "/tmp/")

See the User Guide entry for LilyPond for more details on the other arguments to `write-lp-data-for-all`.

As long as CMN is installed and set up properly to interact with slippery chicken, both LilyPond files and CMN output, as well as a MIDI file, can be generated at the same time.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;;; EOF primary-disposition.lsp

### Processing the code and producing output

The code presented in this example must be processed ("evaluated") in order to generate the musical data and produce any desired output files. This can be done in a number of ways. The first way is to enter each fully-closed expression at the `SC>` prompt in the Lisp listener. However, this approach may be rather unwieldy for long passages of code.

The second approach assumes that the code is being written using the text-editing software Emacs and the SLIME Lisp-interaction mode. In this case, the cursor can be placed after the final parenthesis of each fully-closed expression and the key-command `C-x C-e` can be performed to evaluate each expression individually. More information on this approach can be found at the Emacs and SLIME websites.

The third and recommended approach is to enter and save the code into an ASCII-only text file with the suffix `.lsp`. It is important to be sure that the operating system is not automatically attaching and hiding a `.txt` or other suffix to your file. It is also important to use a text-only text editor such as WordPad or TextWrangler (or Emacs), as many text-editing applications include hidden markup commands that may prevent the code from evaluating properly.

    SC> (load "/path/to/primary-disposition.lsp")

More information on loading CMN, slippery chicken, and individual slippery chicken files can be found on the installation page.

### Conclusion

Depending on how slippery chicken was installed, running this code should produce at the very least a MIDI file. This is a Type 1 MIDI file (one channel per instrument), and can be imported into other sequencer or notation software.

LilyPond and CMN output will be created if the relevant code is uncommented in the downloaded file.

Should this have been done, slippery chicken should also have produced `.ly` files that can be open and rendered using LilyPond, resulting in a PDF of the score and/or parts.

Should CMN have been installed to interact with slippery chicken, and the corresponding code uncommented in the file, an `.eps` file should also have been produced. That file can be opened using Preview.app on a Macintosh (where it will be immediately converted to PDF), or, for example, Ghostscript with Ghostview or GSview on other platforms.