slippery chicken documentation - slippery chicken and clm

## slippery chicken and CLM

slippery chicken's `clm-play` method allows the user to generate sound files based on the data structures of a `slippery-chicken` object. The method takes one or more source sound files specified in the `sndfile-palette` and uses them (or segments of them) to create a new sound file based on the rhythms and certain aspects of the pitch material of a specified player or players within a given `slippery-chicken` object.

### + Setting the output directory

The user must first designate the output path for the new sound file to be generated. This is done by setting the `slippery-chicken` object's `snd-out-dir` slot:

    :snd-output-dir "/tmp/"

close

### + The sndfile-palette

The user must then define a `sndfile-palette` consisting of source sound files from which the new sound file will be created. The `sndfile-palette` takes a list containing at least one group, each of which in turn contains a list with the name of at least one source sound file. The different groups cannot be used in the same call to `clm-play`, but can be used in separate calls to the method to generate output files with the same rhythm and pitch characteristics but a different sound flavors (see the section on source sound file groups below.)

The list of groups is followed by a list of paths to the disk locations where the source sound files are stored. The source sound files can be located in any of the specified disk locations.

    :sndfile-palette '(((percussive-models-group
                         ((source-sndfile-1.aif)
                          (source-sndfile-2.aif)
                          (source-sndfile-3.aif)))
                        (sustained-pads-group
                         ((source-sndfile-4.aif)
                          (source-sndfile-5.aif)
                          (source-sndfile-6.aif))))
                       ("/path/to/source-sndfiles/")))))

close

### + The call to clm-play

In its most straightforward form, the `clm-play` method takes as its arguments a `slippery-chicken` object, the ID of the starting section in that `slippery-chicken` object on which the new sound file is to be based, the IDs of the players whose `events` are to be used as the structural basis for the new sound file, and the ID of the sound file group within the `sndfile-palette` that contains the source sound file or files from which the new sound file is to be generated:

    (clm-play +an-sc-object+ 1 '(player-one player-two) 'source-sndfile-grp-1)

If instead of a list of player IDs the user sets the third argument of the `clm-play` method to `NIL`, the `event` data will be drawn from all players in the ensemble.

    (clm-play +an-sc-object+ 1 nil 'source-sndfile-grp-1)

close

### + What it does

The `clm-play` method passes through the specified section (or sections, if more than one is indicated; see below), and for each attacked note in the parts of each of the players specified it triggers the playback of a source sound file from the specified group in the `sndfile-palette`.

The `clm-play` method begins its output with the first attacked note in the specified sequence. Thus, if the first event of a given sequence is an attacked note, the resulting new sound file will be exactly rhythmically synchronous with the parts of the specified players. This is especially audible if the source sound files are percussive in nature. (This synchronicity can be obscured, if desired, by methods such as setting the `inc-start` etc., described below.)

If the specified sequence begins with one or more rests, the method will ignore those rests, and the new sound file will begin with the first attacked event at 0.0 seconds. The resulting sound file in such cases will therefore be rhythmically synchronous to the given players' parts, but with a minor offset at the beginning.

The source sound files are triggered in cyclical sequence on a note-by-note, sequence-by-sequence, and player-by-player basis, following the order of the players as listed in the `ensemble`. Each consecutive note in the given player's part triggers the next source sound file from the specified group in the `sndfile-palette`. By default, the method begins at the top of the list of the source sound files in the specified group with each new `rthm-seq` and begins triggering them in sequence again. The method also returns to the top of the list if all of the source sound files have been triggered once before the end of the given `rthm-seq`. Once all of the notes have been processed for one player, the method moves to the next player.

The `clm-play` method does not process the source sound files it is given by any means other than shifting their pitch, assembling a sequence of sound files or file fragments for playback, and distributing the individual sound files or fragments amongst the channels for spatialized playback. There is no synthesis or filtering involved. Filtering or synthesis of the sound files to be used can be prepared in advance using third-party editors, such as Wavelab, Audition, or the open-source alternative Audacity, or through other sound file producing software such as Max/MSP, Common Music and Common Lisp Music, or SuperCollider.

The sound files generated by `clm-play` can be either be based on shorter, individual sections or sequences of the given `slippery-chicken` object, or on the full length of the object. In both instances, the user will most likely wish to generate several sound files that are then assembled and mixed in a third-party digital audio workstation, such as such as Logic, Cubase, or the open-source alternative Ardour

close

### + Start times, end times, and durations

Unless otherwise indicated, the `clm-play` method triggers the source sound files from their beginning and continues playback of the same source sound file until the next attacked note in the given player's part, ignoring rests. By default, if the given source sound file is longer than the duration between two attacked notes, playback of the source sound file will be interrupted at the next attacked note. If the source sound file is shorter than the duration between two attacked notes, it will play out in full.

#### clm-play arguments that affect start times, end times, and durations

Three optional keyword arguments are available to the `clm-play` method to modify this default behavior, namely `:inc-start`, `:duration-scaler`, and `:ignore-rests`. Three additional keyword arguments can be specified within the `sndfile-palette` that have a related effect, namely `:start`, `:end`, and `:duration`.

If the `:inc-start` argument is set to `T`, the `clm-play` method will automatically start playback of the source sound file from an increasingly later point in that file each time the file is triggered. The `:inc-start` argument is set to `NIL` by default.

The `:duration-scaler` argument instructs the `clm-play` method to scale the duration of each source sound file segment by a specified factor. If the argument is given a value less than `1.0`, the segments played back will end before the next attacked note, and if it is set to a value greater than `1.0`, the playback of the segments will not end until after the next attacked note (should they be long enough), causing the segments to overlap. Overlapping segments will only be generated for events within the same sequence, but will not overlap from one sequence to the next. The `:duration-scaler` argument only affects the duration of the segment played back, and does not alter pitch or implement time-stretching. This argument is set to `1.0` by default.

If the `:ignore-rests` argument is set to `NIL`, the `clm-play` method will stop playback of the source sound file segments to correspond with rests in the given player's part. This argument is set to `T` by default. Similar to the `:duration-scaler`, ignoring rests only has an effect within the same sequence. All sounds will end at the end of a sequence, even if the next sequence begins with rests.

    (clm-play +an-sc-object+ 1 'player-one 'source-sndfile-grp-1
              :inc-start t
              :duration-scaler 1.3
              :ignore-rests nil)

#### Specifying start and end times within the sndfile-palette

The user can indicate that only a specified segment of a given source sound file is to be played back using the `:start` and `:end` or `:duration` keyword arguments within the `sndfile-palette`. These arguments correspond to the identically named slots of the `sndfile` class. Each of these arguments takes either a single numerical value consisting of time in seconds, or a list of numbers indicating `(mins secs ms)`.

The same source sound file can be listed in the `sndfile-palette` multiple times with different `:start` and `:end` or `:duration` times (or with the same values to get a repeat). This has essentially the same effect as listing multiple separate source sound files, as the `clm-play` method will cycle through these in the same manner by which it cycles through separate sound files.

The `:duration` argument automatically determines the end time of the given segment by adding the specified number of seconds to the start time. The user should apply either the `:end` or `:duration` argument to a given source sound file, but not both.

If a `:start` time is indicated with no `:end` or `:duration` time, the end time will default to the end of the source sound file. Correspondingly, if only an `:end` or `:duration` time is specified, the segment will begin playback at the beginning of the source sound file.

    :sndfile-palette '(((sustained-pads-group
                         ((source-sndfile-1.aif :start 0.000 :end 2.308)
                          (source-sndfile-1.aif :start 2.274 :duration 0.1)
                          (source-sndfile-1.aif :start (0 4 748))
                          (source-sndfile-1.aif :end 7.255)
                          (source-sndfile-1.aif :duration 2.1))))
                       ("/path/to/source-sndfiles/"))

NB: The `:duration` argument within the `sndfile-palette` is only used to demarcate a segment within a source sound file; the actual duration played back will be decided by the rhythms of the corresponding player part and the values of the `:duration-scaler` and `:ignore-rests` arguments.

close

### + Base frequency

slippery chicken has two options concerning the speed (transposition via sample-rate conversion) at which it plays back the various source sound files. Both of these options make use of the `frequency` slot when determining these speeds. The `frequency` value can be defined for each source sound file within the `sndfile-palette`.

    :sndfile-palette '(((percussive-models-group
                         ((source-sndfile-1.aif :start 0.000 :end 2.308)
                          (source-sndfile-1.aif :start 2.274 :duration 0.1 :frequency 524)
                          (source-sndfile-1.aif :start 4.748 :frequency c3)
                          (source-sndfile-1.aif :end 7.255 :frequency c5)
                          (source-sndfile-1.aif :duration 2.1 frequency d4))))
                       ("/path/to/source-sndfiles/"))

The `frequency` slot is used to set the reference pitch for the sample-rate conversion (transposition) of the given source sound file when transposing. Some sounds have a prominent fundamental pitch which can be used as a reference for transposition. Setting the `frequency` slot to this fundamental pitch, either in the form of a real frequency or a note-name symbol, will determine the sample-rate conversion factor when transposing.

The first option available to the user regarding transposition, which is slippery chicken's default behavior, is to determine the sample-rate conversion in a rather general manner, based on the pitches of the current set. In this option, slippery chicken will not attempt to match the transpositions of the source sound files to the exact pitches in the parts of the given players.

In the second option, slippery chicken scales the playback speed of the source sound files to match the specific pitches of the given players' parts. The pitches in the resulting output file will only match those of the players' parts if the source sound file has a perceptible fundamental pitch and this has been defined accurately within the `sndfile-palette` using the `frequency` slot. This option will also result in chords from the players' parts being reflected in the sound file output.

The second option will only be applied if the `:pitch-synchronous` argument of the `clm-play` method is set to `T`.

    (clm-play +an-sc-object+ 1 'flt 'source-sndfile-grp-1
              :pitch-synchronous t)

The `frequency` slot can be an effective tool even for source sound files that have no perceptible fundamental pitch. In general, setting a higher `frequency` value will cause the source sound file to be played back at a lower pitch, whereas setting it lower will cause the source sound file to play back at a higher pitch.

If no pitch is specified for the `frequency` slot, the value defaults to `C4`.

Transposition by sample-rate conversion is a time-domain process, so as with changing the speed of a tape recorder or turntable, both pitch and timing of events is altered.

close

### + Source sound file groups

The `sndfile-palette` definition can consist of multiple groups of source sound files. However, the `clm-play` method is designed to only utilize one of these groups for any given output file (with the exception of the fibonacci-transition option described below). For this reason, one possible approach to the use of the `clm-play` method is to call it several times, specifying a different source sound file group for each call.

    (clm-play +an-sc-object+ 1 '(player-one player-two) 'source-sndfile-grp-1
              :duration-scaler 0.7
              :inc-start nil)
    (clm-play +an-sc-object+ 1 '(player-one player-two) 'source-sndfile-grp-2
              :duration-scaler 1.3
              :inc-start t)
    (clm-play +an-sc-object+ 1 '(player-three) 'source-sndfile-grp-3
              :ignore-rests nil)

The resulting sound files can then be combined and mixed using a third-party digital audio workstation, such as Logic, Cubase, or the open-source alternative Ardour.

#### Fibonacci-transitioning between two sound file groups

The one native option that slippery chicken has available for incorporating more than sound file group into the same output file consists of a `fibonacci-transition` between two groups in the same sndfile-palette. This is done by specifying the first group as usual and the second group as the value of the optional keyword argument `:sound-file-palette-ref2`.

    (clm-play +an-sc-object+ 1 '(player-one player-two) 'source-sndfile-grp-1
              :sound-file-palette-ref2 'source-sndfile-grp-2)

close

### + Other useful sndfile slots

Two other useful slots of the `sndfile` class that can be given values within the `sndfile-palette` are `amplitude` and `description`.

#### amplitude

The `amplitude` slot sets the relative amplitude scaler of the given source sound files (or segments of the given source sound file if using `:start` and `:end` or `:duration`). Since CLM automatically normalizes the new sound file to the highest sample value, this argument can take a number of any arbitrary value, and the amplitudes given will be scaled accordingly.

#### description

The `description` slot allows the user to add a comment about the given source sound file or segment defined. This value is not used for any purposes other than information.

    :sndfile-palette '(((percussive-models-group
                         ((source-sndfile-1.aif
                           :description "initial attack"
                           :start 0.000 :end 2.308 :frequency 524
                           :amplitude 0.1)
                          (source-sndfile-1.aif
                           :description "snap"
                           :start 2.274 :duration 0.1 :frequency e4
                           :amplitude 1.0))))
                       ("/path/to/source-sndfiles/"))

close

### + Other useful clm-play arguments

The `clm-play` method takes 4 mandatory arguments and has 36 optional keyword arguments. A description of each of these arguments can be found in the source code documentation for `clm-play`. A number of the more frequently used optional keyword arguments are given here in brief.

- `from-sequence` and `num-sequences`: These two arguments take numbers that indicate the first `rthm-seq` and number of subsequent `rthm-seqs` within the specified section from which to draw data for the basis of the new sound file. These arguments might be used, for example, if the user would like to generate several smaller sound files for compilation in a third-party digital audio workstation.

      (clm-play +sc-object+ 1 nil 'source-sndfile-grp-1
                :from-sequence 2
                :num-sequences 2)

- `num-sections`: The second mandatory argument to `clm-play` is the first section on which to base the structure of the new sound file. The `num-sections` argument can be used to indicate how many subsequent sections are also to be used.

      (clm-play +sc-object+ 2 nil 'source-sndfile-grp-1 :num-sections 2)

- `reset-snds-each-rs` and `reset-snds-each-player`: By default, slippery-chicken begins at the top of each list of source sound files at the beginning of each `rthm-seq` and with each new player it processes. This behavior can be changed by setting one or both of these arguments to `NIL`.

      (clm-play +sc-object+ 1 nil 'source-sndfile-grp-1
                :reset-snds-each-rs nil
                :reset-snds-each-player nil)

- `time-scaler`: The `time-scaler` argument takes a factor by which the durations of the segments in the new sound file will be scaled. The resulting sound file will have the same rhythmic structure as the players' parts on which it is based but at a slower or faster tempo, making it shorter or longer than the musical data generated. Use of this argument only affects durations; it does not apply pitch-shifting or time-stretching. The resulting sound file will no longer be synchronous with the events of the given `slippery-chicken` object.

      (clm-play +sc-object+ 1 nil 'source-sndfile-grp-1 :time-scaler 1.7)

- `src-scaler`: The `src-scaler` value will scale the playback speed of all individual sound file segments being written to the new sound file by the specified factor. This argument does not affect durations or apply time-stretching, nor does it modify the playback speed or duration of the new sound file as a whole.

      (clm-play +sc-object+ 1 nil 'source-sndfile-grp-1 :src-scaler 1.9)

- `rev-amt`: The `rev-amt` value indicates how much reverb is to be applied to the output file. The `clm-play` method uses the `nrev` reverb instrument, in which a value of `0.1` is already a lot of reverb.

      (clm-play +sc-object+ 1 nil 'source-sndfile-grp-1 :rev-amt 0.1)

close

### + clm-play arguments for output format

The `clm-play` method produces stereo sound files by default, with the header type, data format, and sample rate that are stored in CLM's global `*clm-header-type*`, `*clm-data-format*`, and `*clm-srate*` variables. CLM's default data format and sample rate are `16 bit signed integer` and `44100` kHz. The default header-type is dependent on the user's operating system. slippery chicken will automatically attach the sound file extension it determines to be best suited to the header type, though this parameter too can be specified by the user.

These attributes can be specified by providing values for the following keyword arguments:

- `channels`: The number of interleaved channels in the output file. The `clm-play` method will automatically distribute the source sound material across the channels in a manner reflecting a linear periphery of consecutively numbered loudspeakers. The number of output channels is only limited by the sound file output format used.
- `srate`: The sample rate of the new output file.
- `header-type:` The value given here is used to set CLM's global `*clm-header-type*` variable and must be preceded by the `clm::` package qualifier. Setting this to `mus-riff` will produce files in `.wav` format; `mus-aiff` will produce `.aiff` files.
- `data-format`: The value given here is used to set CLM's global `*clm-data-format*` variable and must be preceded by the `clm::` package qualifier. Setting this to `mus-lfloat` will produce audio files with a format of 32-bit little-endian floating-point. Setting it to `mus-l24int` produces little-endian 24-bit integer files. `mus-bshort` will produce 16-bit big-endian files, and `mus-bfloat` will produce 32-bit floating-point big-endian files. NB: AIFF and AIFC files are not compatible with little endian formats.
- `sndfile-extension`: The extension to be added to the new output file. If `NIL`, slippery chicken will automatically attach the extension that it determines to be best suited to the header type. NB: The extension does not determine the output sound file format; `header-type` does that.

    (clm-play +sc-object+ 1 nil 'source-sndfile-grp-1
              :channels 8
              :srate 44100
              :header-type clm::mus-aiff
              :data-format clm::mus-bshort
              :sndfile-extension ".aiff")

close

### + Creating tape parts with independent rhythmic structures

Since `clm-play` creates its output files based on the `events` of one or more players in the `ensemble`, if the user wishes to create an output file that is not synchronous in rhythmic structure to any of the instrumental parts, or if the user would like to create an electroacoustic composition with no instrumental players, "silent" computer-part players can be added to the `ensemble` (a corresponding `computer` instrument exists in the `+slippery-chicken-standard-instrument-palette+`). As the `computer` instrument is defined to encompass the full MIDI pitch range (C-1 to G9), use of `set-limits-high` and `-low` may be recommended for limiting transposition registers. Specific `rthm-seq` IDs can then be given for these players in the `rthm-seq-map`. These "silent" players can then be passed as the `player` argument to the `clm-play` method to generate that given tape part.

Adding a computer part to the `ensemble`:

    :ensemble '(((fl (flute :midi-channel 1))
                 (ob (oboe :midi-channel 2))
                 (cl (b-flat-clarinet :midi-channel 3))
                 (cp (computer))))

Setting the transposition register:

    :set-limits-high '((cp (0 c6 100 c6)))
    :set-limits-low '((cp (0 f3 100 f3)))

Defining a separate rhythmic structure for the computer part within the `rthm-seq-map`:

    :rthm-seq-map '((1 ((fl (1 2 3 1 3 2))
                        (ob (2 3 1 3 2 1))
                        (cl (3 1 3 2 1 2))
                        (cp (1 3 2 1 2 3)))))

Calling `clm-play` for just the `rhtm-seq-map` data of the `cp` part:

    (clm-play +sc-object+ 1 'cp 'source-sndfile-grp-1)

If this approach is chosen, the "silent" players of the ensemble can then be excluded from the MIDI output by specifying `voices` to the `midi-play` method, and excluded from printable score output by calling `cmn-display` or `write-lp-data-for-all` with the `players` argument.

Specifying only a selection of the players for the `midi-play` method (excluding the computer player):

    (midi-play +sc-object+ :voices '(fl ob cl) :midi-file "/tmp/output.mid")

Specifying only a selection of the players for the `cmn-display` and `write-lp-data-for-all` methods (excluding the computer player):

    (cmn-display +sc-object+ :players '(fl ob cl) :file "/tmp/output.eps")

    (write-lp-data-for-all +sc-object+ :players '(fl ob cl) :base-path "/tmp/")

close