csound/csound-p-fields-simple [ Functions ]

[ Top ] [ Functions ]

AUTHOR

 Ruben Philipp <ruben.philipp@folkwang-uni.de>

DATE

 2023-02-28, Essen

DESCRIPTION

 This function is intended to be used in conjunction with
 the write-csound-score method. It returns a list or -- when the given event
 is a chord -- a list of lists of p-values.

 The p-fields are allocated as follows:
 - p4: frequency
 - p5: amplitude

 N.B.: The event-num and cs-instrument arguments are mandatory as they
       are required by the write-csound-score method, even though they are
       not used in this function.

ARGUMENTS

 - An event object (most likely the event currently processed by
   write-csound-score).
 - A number referring as an index to the position in processing sequence.
 - A reference to a Csound-instrument (number or string).

RETURN VALUE

 Returns either a list (when the event is a pitch) or a list of lists
 (in case the event contains a chord) with p4- and p5-values (see
 above).

SYNOPSIS

(defun csound-p-fields-simple (event event-num cs-instrument)

sc/slippery-chicken [ Classes ]

[ Top ] [ Classes ]

NAME

 slippery-chicken
 
 File:             slippery-chicken.lsp

 Class Hierarchy:  named-object -> slippery-chicken

 Version:          1.1.0

 Project:          slippery chicken (algorithmic composition)

 Purpose:          Implementation of the slippery-chicken class.

 Author:           Michael Edwards: m@michael-edwards.org

 Creation date:    March 19th 2001

 $$ Last modified:  14:35:15 Mon Oct 28 2024 CET

slippery-chicken-edit/map-over-events-aux [ Functions ]

[ Top ] [ slippery-chicken-edit ] [ Functions ]

AUTHOR

 Daniel Ross (mr.danielross[at]gmail[dot]com) 

DATE

 3 September 2019, London

DESCRIPTION

 Auxilliary function for map-over-notes and map-over-events. Saves
 duplicating code.

ARGUMENTS

 - A slippery chicken object
 - A number that is the first bar to which the function should be
   applied. Default = NIL in which case 1 will be used. 
 - A number that is the last bar to which the function should be
   applied. Default = NIL in which case all bars will be processed. 
 - A list of the IDs of the players to whose parts the function should be
   applied. Can also be a single symbol. If NIL then all players will be
   processed.
 - T or NIL to indicate whether or not rests will be ignored.
   T = attacked notes only (i.e. no rests), NIL = include rests.
 - The method or function itself. This can be a user-defined function or the
   name of an existing method or function.  It should take at least one
   argument, an event, and any other arguments as supplied.  
 - Any additional argument values the specified method/function may
   take or require. See the thin method below for an example that uses
   additional arguments.

RETURN VALUE

 - A list containing the number of events changed per instrument

SYNOPSIS

(defun map-over-events-aux (sc start-bar end-bar players attacked-notes-only
                            function further-args)

slippery-chicken/auto-set-written [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Automatically set the WRITTEN-PITCH-OR-CHORD slot for all events where the
 player plays a transposing instrument (which can change of course).

ARGUMENTS

 - A slippery-chicken object. 

OPTIONAL ARGUMENTS

 keyword arguments:
 - :start-bar. NIL or an integer that is the first bar for which the written
   pitch/chord data is to be set. If NIL, start from bar 1. Default = NIL.
 - :end-bar. NIL or an integer that is the last bar for which the written
   pitch/chord data is to be set. If NIL, do all bars. Default = NIL.
 - :players. NIL, the ID or a list of IDs for the player(s) whose part(s)
   are to be affected. If NIL, all players' parts will be affected. 
   Default = NIL.

RETURN VALUE

 T

EXAMPLE

;;; Create a slippery-chicken object, set all the written-pitch-or-chord ;
;;; slots to NIL and print the results. Apply the method and print the results ;
;;; again to see the difference.        ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((hn (french-horn :midi-channel 1))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((hn (1 1 1 1 1))))))))
  (next-event mini 'hn nil 1)
  (loop for ne = (next-event mini 'hn)
     while ne
do (setf (written-pitch-or-chord ne) nil))
  (next-event mini 'hn nil 1)
  (print
   (loop for ne = (next-event mini 'hn)
      while ne
collect (written-pitch-or-chord ne)))
  (auto-set-written mini)
  (next-event mini 'hn nil 1)
  (print
   (loop for ne = (next-event mini 'hn)
      while ne
collect (data (written-pitch-or-chord ne)))))

=>
(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL
NIL NIL NIL NIL NIL NIL NIL) 
(C4 D4 E4 FS4 G4 C4 D4 E4 FS4 G4 C4 D4 E4 FS4 G4 C4 D4 E4 FS4 G4 C4 D4 E4
FS4 G4)

SYNOPSIS

(defmethod auto-set-written ((sc slippery-chicken) &key start-bar end-bar
                             players)

slippery-chicken/check-beams [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 See the description, with example, for check-beams in rthm-seq-bar.lsp. 
 Players can either be a single symbol, a list of symbols, or nil (whereby
 all players will be checked).

SYNOPSIS

(defmethod check-beams ((sc slippery-chicken) &key start-bar end-bar players
                        auto-beam print (on-fail #'warn))

slippery-chicken/check-ties [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Check that all ties are started and ended properly. If the optional
 argument <same-spellings> is set to T, all tied pitches will be forced to
 have the same enharmonic spellings. 

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 - T or NIL to indicate whether to force all tied pitches to have the same
   enharmonic spellings.
 - a function to call on error, or NIL for no action.

RETURN VALUE

 T if all tie data is ok, otherwise performs the on-fail function and
 returns NIL.

EXAMPLE

;;; Create a slippery-chicken object, manually create a problem with the ties,
;;; and call check-ties with a #'warn as the on-fail function.
(let* ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((cl (b-flat-clarinet :midi-channel 1))))
         :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
         :set-map '((1 (1)))
         :rthm-seq-palette '((1 ((((4 4) { 3 tq tq tq } +q e (s) s)))))
         :rthm-seq-map '((1 ((cl (1)))))))
       (e4 (get-event mini 1 4 'cl)))
  (setf (is-tied-to e4) nil)
  (check-ties mini nil #'warn))

=> WARNING: slippery-chicken::check-ties: bad tie, CL bar 1

SYNOPSIS

(defmethod check-ties ((sc slippery-chicken)
                       &optional same-spellings (on-fail #'error))

slippery-chicken/check-time-sigs [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 28-Jan-2011

DESCRIPTION

 Check every bar in the given slippery-chicken object to see if all players
 have the same time signature. Drops into the debugger with an error if not.

ARGUMENTS

 - A slippery-chicken object.

RETURN VALUE

 T if all players have the same time signature at the same time, otherwise
 drops into the debugger with an error.

EXAMPLE

;; A successful test                    ;
(let* ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((vn (violin :midi-channel 1))
                      (va (viola :midi-channel 2))
                      (vc (cello :midi-channel 3))))
         :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
         :set-map '((1 (1 1 1)))
         :rthm-seq-palette '((1 ((((4 4) { 3 tq tq tq } +q e (s) s)))))
         :rthm-seq-map '((1 ((vn (1 1 1))
                             (va (1 1 1))
                             (vc (1 1 1))))))))
  (check-time-sigs mini))

=> T

;; A failing test                       ;
(let* ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((vn (violin :midi-channel 1))
                      (va (viola :midi-channel 2))
                      (vc (cello :midi-channel 3))))
         :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
         :set-map '((1 (1 1 1)))
         :rthm-seq-palette '((1 ((((4 4) { 3 tq tq tq } +q e (s) s)))))
         :rthm-seq-map '((1 ((vn (1 1 1))
                             (va (1 1 1))
                             (vc (1 1 1))))))))
  (setf (time-sig (get-bar mini 1 'vn)) '(3 4))
  (check-time-sigs mini))

=>
slippery-chicken::check-time-sigs: time signatures are not the same at bar 1
[Condition of type SIMPLE-ERROR]

SYNOPSIS

(defmethod check-time-sigs ((sc slippery-chicken))

slippery-chicken/check-tuplets [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Check the qualities of the tuplet brackets in a given slippery-chicken
 object to make sure they are all formatted properly (i.e. each starting
 tuplet bracket has a closing tuplet bracket etc.). If an error is found,
 the method will try to fix it, then re-check, and only issue an error then
 if another is found.

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 - The function to use if something is not ok with the tuplets. This
   defaults to #'error, but could also be #'warn for example

RETURN VALUE

 T if all tuplets brackets are ok, otherwise performs the on-fail function
 and returns NIL.

EXAMPLE

;;; Create a slippery-chicken object, manually add an error to the tuplet data ;
;;; and call check-tuplets with #'warn as the on-fail function. ;
(let* ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((cl (b-flat-clarinet :midi-channel 1))))
         :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
         :set-map '((1 (1)))
         :rthm-seq-palette '((1 ((((4 4) { 3 tq tq tq } +q e (s) s)))))
         :rthm-seq-map '((1 ((cl (1)))))))
       (e1 (get-event mini 1 1 'cl)))
  (setf (bracket e1) nil)
  (check-tuplets mini #'warn))

=> rthm-seq-bar::check-tuplets: Can't close non-existent bracket.

SYNOPSIS

(defmethod check-tuplets ((sc slippery-chicken) &optional (on-fail #'error))

slippery-chicken/clm-play [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Using the sound files (samples) defined for the given reference (group ID)
 in the sndfile-palette slot of the slippery-chicken object, use CLM to
 generate a new sound file using the pitch and timing information of one or
 more players' parts from the slippery-chicken object.

 NB: The sound file will begin with the first sounding event in the section
     at 0.0 seconds. If there are any leading rests in the player's part,
     these will be omitted in the output file.

 By grouping sound files in the sndfile-palette slot, the user can generate
 a CLM sound file version of the piece in various 'flavours'; perhaps, for
 example, using exclusively source sound files consisting of string samples,
 or percussion sounds, or a variety of sounds, as desired. See below for an
 example of a sndfile-palette.
 
 By default, as :pitch-synchronous defaults to NIL (see below) this method
 does not attempt to match the pitches of the output sound file to those
 generated for the slippery-chicken object, rather, it generates its own
 sequence of pitches based on pitches from the current set. Instead of using
 the pitches of the specified players' parts--which might produce extreme
 sound file transpositions both upwards and downwards--it accesses each note
 of the current set (assigned by the set-map to each rthm-seq) from the
 bottom up, one voice after another. If do-src is T, transposition will then
 be calculated such that the frequency of the sound file (defaults to C4 in
 the sndfile object) will be shifted to the pitch of the given pitch of the
 set. When the set changes it will play the same respective note number of
 that set, etc. This means that, in effect, any given voice will retain the
 same pitch for the duration of the rthm-seq (set) but as the sound files
 cycle around, and these often have quite different pitch/spectral content,
 there's not necessarily a sense of pitch repetition. If you find that this
 transposition process still yields some extreme transpositions, the
 :note-number keyword can be specified to indicate an index into the current
 set of pitches to serve as the lowest voice. If you increase :note-number
 the transpositions will get higher. If the number of voices plus this index
 exceeds the number of pitches in the set, the method will wrap around to
 the lowest pitch of the set. Bear in mind then that when :pitch-synchronous
 is NIL, the pitch-seq curves given in the rthm-seq-palette--and therefore
 all the carefully chosen pitches in the piece--will be ignored in favour of
 representing the transpositions and therefore intervals present in the
 set. That might seem like a strange thing to (want to) do, but it's served
 me (Michael Edwards) very well on many occasions, so it's still the
 default.

 If instead of the above method the user would like the pitches in the
 resulting sound file to be transposed to match the pitches of the
 players' notes, the keyword argument :pitch-synchronous can be set
 to T (and do-src should be left set to T as well). This will also work with
 chords.

 See also make-sfp-from-wavelab-marker-file in sndfile-palette.lsp for
 automatically creating a sndfile-palette from markers in a Steinberg
 Wavelab marker file.

 Event amplitudes are as yet unused by this method.

 NB: CLM's nrev instrument must be loaded before calling this method. If
 you're using the slippery-chicken app, then this is done for you at
 startup. 

ARGUMENTS

 - A slippery chicken object.
 - The ID of the starting section.
 - The IDs of the player(s) whose events are to be used to obtain the
   rhythmic structure (and optionally, pitch content) of the resulting sound
   file. This can be a single symbol for an individual player, a list of
   player IDs, or NIL. If NIL, the event from all players' parts will be
   reflected in the output file. Default = NIL.
 - The ID of the sound file group in the sndfile-palette slot of the
   slippery-chicken object that contains the source sound files from which
   the new sound file is to be generated.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :num-sections. An integer or NIL to indicate how many sections should be
   generated, including the starting section. If NIL, sound file data will
   be generated for all sections of the piece. NB If there are sub-sections
   this will include them in the total, i.e., if section 1 has 3 subsections
   and :num-sections is 2, we'll generate data from the first two
   subsections of section 1, not all subsections of main sections 1 and
   2. Default = NIL. 
 - :from-sequence. An integer that is the number of the first sequence
   within the specified starting section to be used to generate the output
   file. This argument can only be used when num-sections = 1. Default = 1. 
 - :num-sequences. NIL or an integer that indicates how many sequences are
   to be generated, including that specified by :from-sequence. If NIL, all
   sequences will be played. This argument can only be used when
   num-sections = 1 and the section has no subsections. Default = NIL.
 - :srate. A number that is the sampling rate of the output file
   (independent of the input file). This and the following two arguments
   default to the CLM package globals. See clm.html for more options.
   Default = clm::*clm-srate*.
 - :header-type: A CLM package header-type specification to designate the
   output sound file format. For example, clm::mus-riff will produce .wav
   files, clm::mus-aiff will produce .aiff files. The value of this argument
   defaults to the CLM package globals. See clm.html for more
   options. Default = clm::*clm-header-type*.
 - :data-format. A CLM package data-format specification to designate the
   output sound file sample data format. For example, clm::mus-float will
   produce a 32-bit little-endian floating-point format; clm::mus-l24int
   will produce little-endian 24-bit integer; 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. The value of this argument defaults to the CLM package
   globals. See clm.html for more options. 
   Default = clm::*clm-data-format*.
 - :sndfile-extension. NIL or a string that will be the extension of the
   output sound file (e.g. ".wav", ".aif"). If NIL, the method will
   determine the extension auto matically based on the header-type. NB: The
   extension does not determine the output sound file format; that is
   determined by :header-type. Default = NIL.
 - :channels. An integer that is the number of channels in the output sound
   file, limited only by the sound file format specified. Note that both
   stereo and mono sounds from the palette will be randomly panned between
   any two adjacent channels. Default = 2.
 - :rev-amt. A number that determines the amount of reverberation for the
   resulting sound file, passed to CLM's nrev. 
   NB: 0.1 is a lot. Default = 0.0.
 - time-offset. A number that is an offset time in seconds. This produces a
   lead time of a specified number of seconds of silence prior to the sound
   output. 
 - :play. T or NIL to indicate whether CLM should play the output file
   automatically immediately after it has been written. 
   T = play. Default = NIL.
 - :inc-start. T or NIL to indicate whether playback of the source sound
   files is to begin at incrementally increasing positions in those files or
   at their respective 0.0 positions every time. If T, the method will
   increment the position in the source sound file from which playback is
   begun such that it reaches the end of the source sound file the last time
   it is 'played'. T = increment start times. Default = NIL.
 - :ignore-rests. T or NIL to indicate whether silence should be
   incorporated into the resulting sound file to correspond with rests in
   the player's parts. If T, the sound files will play over the duration of
   rests. However, this is only true on a bar-by-bar basis; i.e., notes at
   the end of one bar will not be continued over into a rest in the next
   bar. This implies that rests at the start of a bar will not be turned
   into sounding notes. T = ignore resets. Default = T.
 - :sound-file-palette-ref2. The ID of a sound file group in the given
   slippery-chicken object's sndfile-palette slot. If this reference is
   given, the method will invoke fibonacci-transitions to transition from
   the first specified group of source sound files to this one. If NIL, only
   one group of source sound files will be used. Default = NIL.
 - :do-src. T, NIL, a number, or a note-name pitch symbol to indicate whether
   transposition of the source sound files for playback will be calculated
   such that the perceived fundamental frequencies of those sound files are
   shifted to match the pitches of the current set. If do-src is a number
   (frequency in Hertz) or a note-name pitch symbol, the method will use
   only that pitch instead of the sound files' frequencies when transposing
   to the events' pitches. NB Whichever is used, after being converted to a
   sample rate conversion factor, this is always multiplied by the
   src-scaler (see below). T = match sound files' frequencies to set
   pitches. NIL means no transposition will be performed. Default = T.
 - :pitch-synchronous: T or NIL to indicate whether the source sound files
   are to be transposed to match the pitches of the events in the given
   players' part. This will only be effective if the given source sound file
   has a perceptible frequency that has been specified using the sndfile
   object's :frequency slot in the sndfile-palette. :do-src must also be T
   for this to work. T = match pitches. Default = NIL.
 - :reset-snds-each-rs. T or NIL to indicate whether to begin with the first
   source sound file of the specified group at the beginning of each
   rthm-seq. T = begin with the first sound file. Default = T.
 - :reset-snds-each-player. T or NIL to indicate whether to begin with the
   first source sound file of the specified group for the beginning of each
   player's part. T = begin with the first sound file. Default = T. 
 - :play-chance-env. A list of break-point pairs that determines the chance
   that a given event from the source player's part will be reflected in the
   new sound file. It is determined by random selection but uses a fixed
   seed that is re-initialized each time clm-play is called. The following
   default ensures every note will play: '(0 100 100 100).
 - :play-chance-env-exp. A number that will be applied as the exponent to
   the play-chance-env's y values to create an exponential interpolation
   between break-point pairs. Default = 0.5.
 - :max-start-time. A number that is the last time-point in seconds for
   which events will be processed for the output file. If a maximum start
   time is specified here (in seconds), events after this will be
   skipped. The default value of 99999999 seconds (27778 hours) will result
   in all events being reflected in the sound file.
 - :time-scaler. A number that will be the factor by which all start times
   are scaled for the output file (in effect a tempo scaler). If
   :ignore-rests is T, this will also have an indirect effect on
   durations. This argument should not be confused with
   :duration-scaler. Default = 1.0.
 - :duration-scaler. A number that is the factor by which the duration of
   all  events in the output sound file will be scaled. This does not alter
   start times, and will therefore result in overlapping sounds if greater
   than 1.0. This is not to be confused with :time-scaler. 
   Instead of a simple number, :duration-scaler can also be an envelope 
   (a list of break-point pairs). This means you could smoothly transition
   from staccato-like to overlapping sounds in a single clm-play call.
   Default = 1.0.
 - :normalise. A decimal number that will be the maximum amplitude of the
   resulting output file; i.e., to which the samples will be scaled. Can
   also be NIL, whereupon no normalisation will be performed. 
   Default = 0.99
 - :amp-env. A list of break-point pairs that will govern the amplitude
   envelope applied to all source-sound files as it is being written to the
   new output file. NB: If the user wants to maintain the original attack of
   the source sound file and is not employing the :inc-start option, this
   should be set to '(0 1 ...). If :inc-start is T, the resulting sound file
   will probably contain clicks from non-zero crossings. 
   Default = '(0 0 5 1 60 1 100 0).
 - :src-width. An integer that reflects the accuracy of the sample-rate
   conversion. The higher the value, the more accurate the transposition,
   but the slower the processing. Values of 100 might be useful for very low
   transpositions. Default = 20.
 - :src-scaler: A number that is the factor by which all sample-rate
   conversion values will be scaled (for increasing or decreasing the
   transposition of the overall resulting sound file). 
   Instead of a simple number, :src-scaler can also be an envelope 
   (a list of break-point pairs), similar to :duration-scaler. Default = 1.0.
 - :note-number. A number that is an index, representing the the nth pitch
   of the current set or chord (from the bottom) to be used for the lowest
   player. Default = 0.
 - :duration-run-over. T or NIL to indicate whether the method will allow a
   sound file event to extend past the end of specified segment boundaries
   of a sound file in the sndfile-palette. T = allow. Default = NIL.
 - :short-file-names. T or NIL to indicate whether abbreviated output file
   names will be automatically created instead of the usually rather long
   names. T = short. Default = NIL.
 - :output-name-uniquifier. A user-specified string that will be
   incorporated into the file name, either at the end or the beginning
   depending on whether short-file-names is T or NIL. Default = "".
 - :check-overwrite. T or NIL to indicate whether to query the user before
   overwriting existing sound files. T = query. Default = T.
 - :print-secs. T or NIL to indicate whether CLM should print the seconds
   computed as it works. T = print. Default = NIL.
 - :simulate. T or NIL to indicate whether only the sound file sequencing
   information should be calculated and printed for testing purposes,
   without generating a sound file. T = simulate. Default = NIL.
 - :sndfile-palette. NIL or a file name including path and extension that
   contains an external definition of a sndfile-palette. This will replace
   any sndfile-palette defined in the slippery-chicken object. If NIL, the
   one in the slippery-chicken object will be used. Default = NIL.
 - :chords. NIL or a list of lists consisting of note-name symbols to be
   used as the pitches for the resulting sound file in place of the pitches
   from the set-map. There must be one chord specified for each sequence. If
   NIL, the pitches from the set-map will be used. Default = NIL.
 - :chord-accessor. Sometimes the chord stored in the palette is not a
   simple list of data so we need to access the nth of the chord
   list. Default = NIL.
 - :clm-ins. The CLM instrument that should be called to generate sound file
   output. This must accept required and keyword arguments like samp5 (see
   src/samp5.lsp or more simply src/sine.lsp) but can of course choose to
   ignore them. Remember that your CLM instruments will (most probably) be
   in the CLM package so you'll need the clm:: qualifer. Default =
   #'clm::samp5. 
 - :clm-ins-args. This should be a list of keyword arguments and values to
   pass to each CLM instrument call (e.g. '(:cutoff-freq 2000 :q .6)) or a
   function which takes two arguments (the current event and the event
   number) and returns a list of keyword arguments perhaps based on
   those. Default = NIL.
 - :pan-min-max. Each event is panned randomly between any two adjacent
   channels in the output sound file. The values used are chosen from the
   following list of degrees: (15 25 35 45 55 65 75). However, these can be
   scaled to be within new limits by passing a two-element list to
   :pan-mix-max. E.g. '(40 50) would limit most values to the middle area of
   stereo space. NB if stereo soundfiles are used as input the original
   panning will generally be retained. See samp5.lsp for details of how such
   files are handled. Default = NIL (i.e. use the list given above).
 - :pan-fun. If you want to take charge of selecting pan positions yourself,
   pass a function via this keyword. The function must take one argument: the
   current event, though of course, it can ignore it completely if
   preferred. The function should return a degree value: a number between 0
   and 90. Bear in mind if using samp5 with more than 2 output channels that
   this will still result in the sound moving around multichannel space as
   all you would be setting is the pan value between any two adjacent
   channels. If this isn't your cup of tea, pass a new instrument entirely
   via :clm-ins. See example below. Default = NIL.
 - :snd-selector. By default the sound files in the given group are cycled
   through, one after the other, returning to the beginning when the end is
   reached. This can be changed by passing a function to :snd-selector. This
   function must take three arguments: the circular-sclist object that
   contains the group's sndfile objects (the sndfiles are in a simple list
   in the data slot); the pitch of the current event (if the event happens
   to be a chord, each pitch of the chord will be handled separately
   i.e. the :snd-selector function will be called for each pitch); and the
   event object. Of course any of these arguments may be ignored by the
   :snd-selector function; indeed it is imagined that the event object will
   be mostly ignored and the pitch object used instead, but it is
   nevertheless passed for completeness. For example, the following
   function, declared on-the-fly using lambda rather than separately with
   defun, makes clm-play act as a traditional sampler would: Assuming our
   sndfile-palette group has a list of sound files whose frequencies really
   correspond to their perceived fundamentals (e.g. see the
   set-frequency-from-filename method, and the kontakt-to-sfp function) we
   choose the nearest sound file in the group to the frequency of the
   current event's pitch:

            :snd-selector #'(lambda (sflist pitch event)
                              (declare (ignore event))
                              (get-nearest-by-freq
                               (frequency pitch) (data sflist)))

   NB If :pitch-synchronous is NIL, then the pitch-or-chord slot of the event
   will be the pitch selected from the current set, rather than the actual
   pitch of the instrument in question.
   Default = NIL i.e. use the circular selection method.
 - :decay-time. Reverb decay time. Default = 3 seconds.
 - :snd-transitions. Set the transition from sound-file-ref to sound-file-ref
   over the course of the call to clm-play using a custom envelope instead of
   the default fibonacci-transitions method, e.g. '(0 0 100 1). x-axis is
   arbitrary, y-axis should range from 0 to 1. When reading, y-values will be
   rounded. 

RETURN VALUE

 Total events generated (integer).

EXAMPLE

;;; An example using some of the more frequent arguments
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (hn (french-horn :midi-channel 2))
                     (vc (cello :midi-channel 3))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1 1 1))
                   (2 (1 1 1 1 1 1 1))
                   (3 (1 1 1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                :pitch-seq-palette ((1 (2) 3))))
                            (2 ((((4 4) (q) e (s) s h))
                                :pitch-seq-palette ((1 2 (3)))))
                            (3 ((((4 4) e (s) s h (q)))
                                :pitch-seq-palette ((2 3 3))))
                            (4 ((((4 4) (s) s h (q) e))
                                :pitch-seq-palette ((3 (1) 2)))))
        :rthm-seq-map '((1 ((cl (2 3 2 4 1 3 1))
                            (hn (2 4 1 2 3 1 3))
                            (vc (1 2 2 3 4 1 3))))
                        (2 ((cl (4 2 1 3 3 1 2))
                            (hn (2 1 4 3 2 1 3))
                            (vc (2 3 4 3 1 2 1))))
                        (3 ((cl (3 1 2 4 3 1 2))
                            (hn (3 4 2 1 3 2 1))
                            (vc (3 2 3 1 4 2 1)))))
        :snd-output-dir (get-sc-config 'default-dir)
        :sndfile-palette '(((sndfile-grp-1
                             ((test-sndfile-1.aiff)
                              (test-sndfile-2.aiff)
                              (test-sndfile-3.aiff)))
                            (sndfile-grp-2
                             ((test-sndfile-4.aiff :frequency 834)
                              (test-sndfile-5.aiff)
                              (test-sndfile-6.aiff))))
                           ("/path/to/sndfiles-dir-1"
                            "/path/to/sndfiles-dir-2")))))
  (clm-play mini 2 '(cl vc) 'sndfile-grp-1
            :num-sections 1
            :srate 48000
            :header-type clm::mus-aiff
            :data-format clm::mus-b24int
            :rev-amt 0.05
            :inc-start t
            :ignore-rests nil
            :sound-file-palette-ref2 'sndfile-grp-2
            :pitch-synchronous t
            :reset-snds-each-rs nil
            :reset-snds-each-player nil))

;;; A minimal working example demonstrating envelope-arguments 
;;; to duration-scaler and src-scaler
(let* ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((vn (violin :midi-channel 1))))
         :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
         :set-map '((1 (1 1 1)))
         :rthm-seq-palette '((1 ((((2 4) (s) (s) e e e))
                                 :pitch-seq-palette ((1 2 3)))))
         :rthm-seq-map '((1 ((vn (1 1 1)))))
         :snd-output-dir "/tmp/"
         :sndfile-palette '(((sndfile-grp-1
                              ((test-sndfile-1.aiff)
                               (test-sndfile-2.aiff)
                               (test-sndfile-3.aiff))))
                            ("/path/to/sndfiles-dir-1")))))
  (clm-play mini 1 'vn 'sndfile-grp-1
            :src-scaler '(0 .5  80 1  100 2)
            :do-src 500
            :src-width 5
            :duration-scaler '(0 .1  80 1  100 2)
            :check-overwrite nil
            :play nil :header-type clm::mus-riff))

;;; if you don't want amplitude panning, rather a random placement of each sound
;;; in one channel only, then this should work (no matter how many channels
;;; there are in your output file):

    :pan-fun #'(lambda (event)
                 (declare (ignore event))
                 (nth (random-rep 2) '(0 90)))

SYNOPSIS

#+clm
(defmethod clm-play ((sc slippery-chicken) section players 
                     sound-file-palette-ref 
                     &key 
                     sound-file-palette-ref2
                     (play-chance-env '(0 100 100 100))
                     (max-start-time 99999999)
                     (play-chance-env-exp 0.5)
                     (time-scaler 1.0)
                     (normalise .99)
                     scaled-by
                     (simulate nil)
                     (from-sequence 1)
                     (num-sequences nil)
                     (num-sections nil)
                     (ignore-rests t)
                     (time-offset 0.0)
                     (chords nil)
                     (chord-accessor nil)
                     (note-number 0)
                     (play nil)
                     (amp-env '(0 0 5 1 60 1 100 0))
                     (inc-start nil)
                     (src-width 20)
                     ;; either a number or an envelope
                     (src-scaler 1.0)
                     (do-src t)
                     (pitch-synchronous nil)
                     (rev-amt 0.0)
                     ;; either a number or an envelope
                     (duration-scaler 1.0)
                     (short-file-names nil)
                     (check-overwrite t)
                     (reset-snds-each-rs t)
                     (reset-snds-each-player t)
                     (duration-run-over nil)
                     (channels 2)
                     (srate clm::*clm-srate*)
                     (header-type clm::*clm-header-type*)
                     (data-format clm::*clm-data-format*)
                     (print-secs nil)
                     (output-name-uniquifier "")
                     (sndfile-extension nil)
                     (sndfile-palette nil)
                     ;; MDE Sat Oct  3 18:45:28 2015 -- for Cameron!
                     pan-fun
                     ;; MDE Thu Oct  1 21:03:59 2015 
                     (pan-min-max nil)  ; actually '(15 75) by default below
                     ;; MDE Thu Oct  1 19:13:49 2015
                     snd-selector 
                     ;; MDE Mon Nov 4 10:10:35 2013 -- the following were
                     ;; added so we could use instruments other than samp5 MDE
                     ;; Thu Mar 21 15:42:53 2024, Heidhausen -- now defaults to
                     ;; nil because samp5 fun is not available until it's
                     ;; compiled and this happens within clm-play now rather
                     ;; than in advance
                     (clm-ins nil)    ;#'clm::samp5)
                     ;; either a list or a function (see above)
                     clm-ins-args
                     ;; DJR Thu 22 Aug 2019 15:08:39 BST
                     ;; clm::with-sound let's us set this, so why doesn't 
                     ;; clm-play? Voila!
                     (decay-time 3)
                     ;; DJR Mon 16 Sep 2019 01:26:11 BST
                     ;; We can now set snd-transitions with a custom envelope,
                     ;; e.g. '(0 0 100 1). x-values are arbitrary, y-values
                     ;; are from 0 (for sound-file-palette-ref) and 1 (for
                     ;; sound-file-palette-ref2).
                     snd-transitions)

slippery-chicken/clone [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Copy (clone) the specified instance and all data associated with the
 slippery-chicken object.

ARGUMENTS

 - A slippery-chicken object.

RETURN VALUE

 A slippery-chicken object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :instrument-palette +slippery-chicken-standard-instrument-palette+
        :ensemble '(((fl (flute :midi-channel 1))))
        :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1)))
        :rthm-seq-palette '((1 ((((4 4) - e e e e - - e e e e -)))))
        :rthm-seq-map '((1 ((fl (1))))))))
  (clone mini))

SYNOPSIS

(defmethod clone ((sc slippery-chicken))

slippery-chicken/cmn-display [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Write the data stored in a given slippery-chicken object to disk as an EPS
 (Encapsulated Postscript) file using CMN. 

 Several of the keyword arguments for this method are passed directly to CMN
 and therefore have identical names to CMN functions.

 NB: This might fail if LilyPond files are generated first. If this happens,
     re-evaluate the slippery-chicken object and call cmn-display again.

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :file. A string that is the directory path with file name and extension
   for the .eps file to be created. Default = "cmn.eps" in the directory
   (get-sc-config 'default-dir) (default "/tmp/") 
 - :players. NIL or a list of player IDs to indicate whether all players'
   parts should be printed to the score. If NIL, all players' parts will be
   written to the score. If a single symbol or a list of player IDs, only
   the parts of those players will be written to the score. Default = NIL.
 - :in-c. T or NIL to indicate whether the output should be printed at
   sounding pitch (in C) or at written pitch. NB: If in C, piccolo and
   double bass maintain their usual octave transpositions.
   T = print at sounding pitch. Default = NIL.
 - :respell-notes. T, a list of player IDs paired with a sequence of bar and
   note numbers, or NIL to indicate whether to the cmn-display method should
   call the respell-notes method to the pitches contained in the
   slippery-chicken object according to slippery chicken's enharmonics
   algorithm. If T, the all of the pitches in the object will be considered
   and slippery chicken will convert a number of the pitches to their
   enharmonic equivalents to create more sensible linear pitch progression
   within bars. If a list of player IDs paired with a sequence of bar and
   event numbers is passed, in the form 
   '((vln (13 2) (14 3)) (cl (14 3 t))), only the specified pitches are
   changed; e.g., (13 2) = bar 13 note 2 (1-based and counting tied notes
   but not rests). If an additional T is included after the bar number and
   event number (as in the cl example above), only the spelling of the
   written pitch for that event will be changed (the default is to change
   the sounding note spelling only). Chords are not respelled by the default
   algorithm, so if these need to be respelled, this should be indicated by
   sub-grouping the note number portion of the given bar/note pair into a
   2-item sublist, in which the first number is the position of the chord in
   among the attacked notes of that bar and the second number is the
   position of the desired pitch within the chord, counted from the bottom
   up, e.g. (vln (13 (2 1))). If NIL, no changes will be made. Default = T.
 - :auto-clefs. T or NIL to indicate whether the cmn-display method should
   call the auto-clefs method, which automatically insert clef changes into
   the parts of those instruments that use more than one clef. 
   T = automatically place clef changes. Default = T.
 - :start-bar. An integer that indicates the first bar of the object to be
   written to the resulting .eps file. NIL = the first bar. Default = NIL.
 - :end-bar. The last bar to be written to the resulting .eps file. NIL =
   the last bar of the slippery-chicken object. Default = NIL.
 - :title. T, a string, or NIL to indicate whether to write the title of the
   given slippery-chicken object to the resulting .eps file. If T, the TITLE
   slot of the slippery-chicken object will be used. If a string, the
   specified string will be used instead. If NIL, no title will be included
   in the output. Default = T.
 - :size. A number to indicate the overall size of the symbols in the CMN
   output. Default = 15.
 - :page-nums. T or NIL to indicate whether page numbers are to be written. 
   T = write page numbers. Default = T.
 - :empty-staves. T or NIL to indicate whether an empty staff should be
   displayed under each instrument. This can be useful for making editing
   notes by hand. T = print empty staff. Default = NIL.
 - :display-sets. T or NIL to indicate whether to print the set of pitches
   used for each rthm-seq on a separate treble-bass grand staff at the
   bottom of each system in the score. T = print. Default = NIL.
 - :write-section-info. T or NIL to indicate whether to write the section ID
   into the score. NB: This might not work without first regenerating the
   slippery-chicken object. T = write section IDs. Default = NIL.
 - :display-time. T or NIL to indicate whether the elapsed time in
   (mins:secs) should printed above each measure in the resulting score. 
   T = print time. Default = NIL.
 - :staff-separation. A number that governs the amount of white space to be
   placed between staves, measured in CMN's units. Default = 3.
 - :line-separation. A number that governs the amount of white space to be
   placed between systems (i.e. not groups, but a line of music for the
   whole ensemble), measured in CMN's units. Default = 5.
 - :group-separation. A number that governs the amount of white space placed
   between groups in a system, measured in CMN's units. Default = 2.
 - :system-separation. An indication for how CMN determines the amount of
   white space between systems. If cmn::page-mark, only one system will be
   written per page. Default cmn::line-mark.
 - :page-height. A number to indicate the height of the page in centimeters.
   Default = 29.7.
 - :page-width. A number to indicate the width of the page in
   centimeters. Default = 21.0. 
 - :all-output-in-one-file. T or NIL to indicate whether to write a separate
   file for each page of the resulting score. T = write all pages to the
   same multi-page file. Default = T.
 - :one-line-per-page. T or NIL to indicate whether to write just one line
   (system) to each page. T = one line per page. Default = NIL.
 - :start-bar-numbering. An integer that indicates the number to be given as
   the first bar number in the resulting EPS file. The bars will be numbered
   every five bars starting from this number. NB: The value of this argument
   is passed directly to a CMN function. If a value is given for this
   argument, slippery chicken's own bar-number writing function will be
   disabled. NB: It is recommended that a value not be passed for this
   argument if a value is given for :auto-bar-nums. NIL = bar 1. Default =
   NIL.
 - :auto-bar-nums. An integer or NIL to indicate a secondary bar numbering
   interval. This is separate from and in addition to the bar-number written
   in every part every 5 bars. It corresponds to CMN's
   automatic-measure-numbers. If set to e.g. 1, a bar number will be printed
   for every measure at the top of each system, or if :by-line, a bar number
   will be printed at the start of each line. NB: The value of this argument
   is passed directly to a CMN function. If a value is given for this
   argument, slippery chicken's own bar-number writing function will be
   disabled. NB: It is recommended that a value not be passed for this
   argument if a value is given for :start-bar-numbering. NIL = no secondary
   bar numbering. Default = T.
 - :rehearsal-letters-all-players. T or NIL to indicate whether rehearsal
   letters should be placed above the staves of all instruments in a score
   (this can be useful when generating parts). If NIL, rehearsal letters are
   only placed above the staves of the instruments at the top of each
   group. T = place rehearsal letters above all instruments. Default = NIL.
 - :tempi-all-players. T or NIL to indicate whether to print the tempo above
   all players' parts in the score. T = print above all players' parts. 
   Default = NIL.
 - :process-event-fun. A user-defined function that takes one argument,
   namely an event object. The specified function will then be called for
   each event in the piece. This could be used, for example, to
   algorithmically add accents, dynamics, or change the colour of notes,
   etc. If NIL, no function will be applied. Default = NIL.
 - :automatic-octave-signs. T or NIL to indicate whether ottava signs should
   be inserted automatically when notes would otherwise need many ledger
   lines. T = automatically insert. Default = NIL.
 - :multi-bar-rests. T or NIL to indicate whether multiple bars of wrests
   should be consolidated when writing parts. T = consolidate. NIL = write
   each consecutive rest bar separately. Default = NIL.
 - :display-marks-in-part. T or NIL to indicate whether to print the marks
   stored in the MARKS-IN-PART slot of each rhythm object in the score. If
   NIL, the indications stored in the MARKS-IN-PART slot are added to parts
   only. T = also print to score. Default = NIL.
 - :add-postscript. NIL or postscript code to be added to the .eps file
   after it has been generated. See the add-ps-to-file function for details.
   Default = NIL.
 - :auto-open. Whether to open the .EPS file once written. Currently only
    available on OSX with SBCL and CCL. Uses the default app for .EPS
    files, as if opened with 'open' in the terminal. Default = Value of
    (get-sc-config cmn-display-auto-open).

RETURN VALUE

 Always T.

EXAMPLE

;;; The simplest usage
(let ((mini
       (make-slippery-chicken
        '+mini+
        :title "mini"
        :ensemble '(((vn (violin :midi-channel 1))))
        :tempo-map '((1 (q 60)))
        :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1)))
        :rthm-seq-palette '((1 ((((2 4) (s) (s) e e e))
                                :pitch-seq-palette ((1 2 3)))))
        :rthm-seq-map '((1 ((vn (1))))))))
  (cmn-display mini :file "/tmp/mini.eps"))

;;; Used with some of the more frequently implemented keyword arguments
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (hn (french-horn :midi-channel 2))
                     (vc (cello :midi-channel 3))))
        :tempo-map '((1 (q 60)))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5)))
                       (2 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5)))
                       (3 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (2 2 2 2 2))
                   (3 (3 3 3 3 3)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5))))
                            (2 ((((4 4) q e s s h))
                                :pitch-seq-palette ((1 2 3 4 5))))
                            (3 ((((4 4) e s s h q))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((cl (1 3 2 1 2))
                            (hn (3 1 1 2 2))
                            (vc (1 1 3 2 2))))
                        (2 ((cl (3 1 1 2 2))
                            (hn (1 3 1 2 2))
                            (vc (3 2 2 1 1))))
                        (3 ((cl (1 1 3 2 2))
                            (hn (2 1 1 2 3))
                            (vc (3 1 1 2 2))))))))
  (cmn-display mini 
               :file "/tmp/cmn.eps"
               :players '(cl vc)
               :in-c nil
               :respell-notes nil
               :auto-clefs nil
               :start-bar 8
               :end-bar 13
               :title "CMN Fragment"
               :size 13
               :page-nums nil
               :empty-staves t
               :display-sets t
               :write-section-info t
               :display-time t
               :staff-separation 2
               :line-separation 3))

=> T

SYNOPSIS

(defmethod cmn-display ((sc slippery-chicken) 
                        &key
                        (respell-notes t)
                        (start-bar nil)
                        (start-bar-numbering nil)
                        (end-bar nil)
                        ;; MDE Fri Apr  6 13:27:08 2012 
                        (title t)
                        (file (format nil "~a~a.eps"
                                      (get-sc-config 'default-dir)
                                      (filename-from-title (title sc))))
                        (all-output-in-one-file t)
                        (one-line-per-page nil)
                        (staff-separation 3)
                        (line-separation 5)
                        (empty-staves nil)
                        (write-section-info nil)
                        (group-separation 2)
                        (system-separation #+cmn cmn::line-mark)
                        (process-event-fun nil)
                        (display-sets nil)
                        (rehearsal-letters-all-players nil)
                        (display-marks-in-part nil)
                        (tempi-all-players nil)
                        (players nil)
                        (page-height 29.7)
                        (page-width 21.0)
                        (size 15)
                        (auto-bar-nums t)
                        (page-nums t)
                        (in-c nil)
                        (auto-clefs t)
                        (multi-bar-rests nil)
                        (automatic-octave-signs nil)
                        (display-time nil)
                        (auto-open (get-sc-config 'cmn-display-auto-open))
                        (add-postscript nil))

slippery-chicken/count-microtones [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 January 30th 2017 

DESCRIPTION

 Count the number of microtonal pitches in the slippery-chicken object. 

ARGUMENTS

 - the slippery-chicken object

OPTIONAL ARGUMENTS

 keyword arguments:
 - :players. the players for whom the count should be executed; either a
   single player symbol or a list of symbols
 - :start-bar. The bar number in which the counting should begin. Default =
   1
 - :end-bar. The bar number in which counting should end. Default = NIL
   which means count through the final bar.

RETURN VALUE

 Four values: the number of microtones, the number of non-microtones, the
 total number of pitches, the percentage of microtonal pitches.

 Note that the total number of pitches will almost certainly be different
 from the number of events as some events will be rests, others single pitch
 notes, yet others chords.

EXAMPLE

(count-microtones +jitterbug+)
1420
2312
3732
38.049305

SYNOPSIS

(defmethod count-microtones ((sc slippery-chicken) &key players (start-bar 1)
                                                     end-bar)

slippery-chicken/count-notes [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Returns the number of notes between start-bar and end-bar (both
 inclusive). 

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the first bar in which notes will be counted. If NIL,
   then 1 
 - An integer that is the last bar in which notes will be counted. If NIL,
   then the last bar of the piece.

OPTIONAL ARGUMENTS

 - T or NIL to indicate whether to count just the number of attacked notes
   (not including ties) or the number of note events (including ties). 
   T = just attacked notes. Default = NIL.
   NB: A chord counts as one note only. 
 - NIL or a list of one or more IDs of the players whose notes should be
   counted. This can be a single symbol or a list of players. If NIL, the
   notes in all players' parts will be counted. Default = NIL.

RETURN VALUE

 An integer that is the number of notes.

EXAMPLE

;;; Using defaults
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s)
                                 (q (e) s +s h)
                                 ((e) s (s) (q) h))
                                :pitch-seq-palette ((1 2 3 4 5 1 3 2)))))
        :rthm-seq-map '((1 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (2 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (3 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))))))
  (count-notes mini 2 11))

=> 62

;;; Counting all notes just for player 'vc ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s)
                                 (q (e) s +s h)
                                 ((e) s (s) (q) h))
                                :pitch-seq-palette ((1 2 3 4 5 1 3 2)))))
        :rthm-seq-map '((1 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (2 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (3 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))))))
  (count-notes mini 2 11 nil 'vc))

=> 31

;;; Counting just the attacked notes for player 'vc ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s)
                                 (q (e) s +s h)
                                 ((e) s (s) (q) h))
                                :pitch-seq-palette ((1 2 3 4 5 1 3 2)))))
        :rthm-seq-map '((1 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (2 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (3 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))))))
  (count-notes mini 2 11 t 'vc))

=> 27

SYNOPSIS

(defmethod count-notes ((sc slippery-chicken) start-bar end-bar 
                        &optional just-attacks players)

slippery-chicken/csound-play [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 2023-03-02, Essen

DESCRIPTION

 This method outputs a soundfile from a slippery-chicken object by
 generating a Csound-score via write-csound-score and calling the Csound
 command with a given Csound-Orchestra as an additional argument. Hence,
 this method's arguments resemble those of write-csound-score, except for
 the argument indicating the orchestra file and a few keyword-arguments
 which primarily deal with the soundfile output.

 In order to work properly, please make sure to have Csound properly
 installed on your system and set the value of 'csound-command via
 (set-sc-config ...) according to your system's configuration.

ARGUMENTS

 - A slippery chicken object.
 - The ID(s) of the player(s) whose events are used to obtain the
   rhythmic structure of the score events. This must be a list with one or
   more symbols. See write-csound-score for more detail.
 - The ID(s) (number) or name(s) (string) of the Csound instruments
   according to the resp. instrument definition in the Csound orchestra.
   This must be a list with one or more values. See write-csound-score for
   more information.
 - The path to the Csound-orchestra file (.orc) to be used for rendering
   the output soundfile. Make sure that it contains instrument definitions
   for all Csound-instruments set in the preceding argument. This must be
   a string.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :csound-flags. A list of strings containing the flags, for the Csound
   command. Altering these might be useful e.g. to change the output format
   of the soundfile. N.B.: The "-o" argument, usually preceding the output
   soundfile name, is already set per default and should not be included in
   this list. For a full list of available arguments, see the Csound-manual.
   Default = '("-d" "-W" "-f")
 - :sndfile-suffix. A string to be added just before the file-extension of
   the generated soundfile. Will be overridden when manually setting the
   sndfile-path via :sndfile. Default = "".
 - :sndfile-extension. A string specifying the file extension of the
   soundfile to be generated by the Csound command. This might be altered
   in case the output format is changed e.g. via :csound-flags. Will be
   overridden when manually setting the sndfile-path via :sndfile.
   Default = ".wav".
 - :sndfile. A string indicating the path and filename to the soundfile to be
   generated with this method. Please bear in mind to alter the suffix if you
   change the format via :csound-flags. Default is a filename extracted from
   the title of the sc piece, placed in the (get-sc-config 'default-dir)
   directory (per default /tmp).
 - The other keyword arguments are exactly the same as write-csound-score.
   Please see write-csound-score for detailed documentation.

RETURN VALUE

 Returns the path of the soundfile written, as a string.

EXAMPLE

;;; An example using the csound-p-fields-simple function.
;;; The Csound orchestra might consist of two instruments producing
;;; tones based on simple waveforms (sines, square waves etc.)
(let ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((pno (piano :midi-channel 1))
                      (vln (violin :midi-channel 2))))
         :set-palette '((1 ((f3 g3 as3 a3 bf3 b3 c4 d4 e4 f4 g4 a4 bf4 cs5))))
         :set-map '((1 (1 1 1 1 1 1 1))
                    (2 (1 1 1 1 1 1 1))
                    (3 (1 1 1 1 1 1 1)))
         :tempo-map '((1 (q 60)))
         :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                 :pitch-seq-palette ((1 (2) 3))))
                             (2 ((((4 4) (q) e (s) s h))
                                 :pitch-seq-palette ((1 2 3))))
                             (3 ((((4 4) e (s) s h (q)))
                                 :pitch-seq-palette ((2 3 3))))
                             (4 ((((4 4) (s) s h (q) e))
                                 :pitch-seq-palette ((3 1 (2))))))
         :rthm-seq-map '((1 ((pno (1 2 1 2 1 2 1))
                             (vln (1 2 1 2 1 2 1))))
                         (2 ((pno (3 4 3 4 3 4 3))
                             (vln (3 4 3 4 3 4 3))))
                         (3 ((pno (1 2 1 2 1 2 1))
                             (vln (1 2 1 2 1 2 1))))))))
  (csound-play mini
               '(pno vln)
               '(1 2)
               "mini-orchestra.orc"
               :comments nil))

SYNOPSIS

(defmethod csound-play (sc
                        players
                        csound-instruments
                        ;; RP  Thu Mar  2 21:17:59 2023
                        ;;; unique to csound-play
                        orchestra-file
                        &key
                          ;; RP  Thu Mar  2 19:10:21 2023
                          ;; specific to csound-play
                          (csound-flags '("-d" "-W" "-f"))
                          ;; add something just before the
                          ;; sndfile-extension?
                          (sndfile-suffix "")
                          ;; choose the right file extension
                          ;; according to your format!
                          (sndfile-extension ".wav")
                          (sndfile (format nil "~a~a~a~a"
                                      (get-sc-config 'default-dir)
                                      (filename-from-title (title sc))
                                      sndfile-suffix
                                      sndfile-extension))
                        ;; RP  Thu Mar  2 19:32:09 2023
                        ;; analogous to write-csound-score
                          (start-section 1)
                          (offset 0)
                          (suffix "")
                          (csound-file
                           (format nil "~a~a~a.sco"
                                   (get-sc-config 'default-dir)
                                   (filename-from-title (title sc))
                                   suffix))
                          (comments t)
                          (delimiter #\space)
                          (from-sequence 1)
                          (num-sequences nil)
                          (chords t)
                          (p-fields #'csound-p-fields-simple)
                          (num-sections nil))

slippery-chicken/empty-bars? [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Test whether players have rest/empty bars within a given range.

ARGUMENTS

 - the slippery-chicken object
 - the start bar (integer, inclusive)
 - the end bar (integer, inclusive)

OPTIONAL ARGUMENTS

 - the players we want to test. Either a list of player IDs, a single ID, or
   nil if all players should be tested. Default = NIL = all players.
 - T or NIL to indicate whether a bar of only rests (instead of a full bar
   rest) should be considered empty. Default = NIL.

RETURN VALUE

 T if all players have rest bars within the given range, NIL if no.

SYNOPSIS

(defmethod empty-bars? ((sc slippery-chicken) start-bar end-bar
                        &optional players all-rests)

slippery-chicken/event-list-to-csound-score [ Functions ]

[ Top ] [ slippery-chicken ] [ Functions ]

AUTHOR

 Ruben Philipp <me@rubenphilipp.com>

 CREATED
 2023-05-07

DESCRIPTION

 This function generates a Csound-score file (.sco) from an event-list.
 Its structure is very similar to write-csound-score except that the
 allocation process between players and Csound-instruments ist structured
 differently. This function uses the event-list's MIDI-channels for
 allocating the data to Csound-instruments (if desired).
 NB: The function events-update-time might be useful in this context (also
 refer to event-list-to-midi-file).

ARGUMENTS

 - A list of event objects.
 - The MIDI-channel(s) to take into account for generating the score.
   This must be a list with one or more symbols or NIL. When NIL, all
   MIDI-channels present in the event-list will be used. When a list,
   only the MIDI-channels contained in this list will be used as a basis
   for the rhythmic structure of the Csound-score. 
 - The ID(s) (as a number) or name(s) (as a string) of the Csound instruments
   according to the resp. instrument definition in the Csound orchestra as
   list of one or more items.
   Each MIDI-channel of the second argument of this method needs to be
   assigned to one Csound-instrument. Thus, the length of this list must
   be exactly the same as the previous list, except when using NIL in the
   MIDI-channels list. In the latter case, the Csound instruments defined
   in this list will be allocated cyclically to the available MIDI-channels
   in ascending order of the MIDI-channels.
   E.g.: When the MIDI-channels 1, 2, 3, and 10 are present in the
   event-list, and this argument is set to '("ins1" "ins2"), the value of
   this slot will internally be changed to '("ins1" "ins2" "ins1" "ins2").

OPTIONAL ARGUMENTS

 keyword-arguments:
 - :suffix. A string to be added just before the .sco of the generated
   csound score-file. Will be overridden when manually setting the path
   via :csound-file. Default = "".
 - :csound-file. A string indicating the path and filename to the .sco-file
   to be generated with this method. Default is "tmp.suffix.sco", placed
   in the (get-sc-config 'default-dir) directory (per default /tmp).
 - :offset. An integer or floating point value to indicate the global
   offset of all score events (in seconds). Default = 0.
 - :comments. A boolean indicating whether additional comments should be
   included into the generated score. Default = T.
 - :delimiter. A character which separates each score statement. Csound
   recommends using spaces, though #\tab does also work an might, in some
   cases, improve legibility. Default = #\space.
 - :chords. Either a boolean or an integer which determines how to deal with
   chords in events. When T, all notes of a chord are parsed as
   i-statements in the Csound-score. When NIL, chords will be ignored and
   treated like rests (i.e. nothing will be generated). When an integer is
   given, the number determines the max. amount of pitches being parsed as i-
   statements. They are chosen chronologically from the given chord.
   Default = T.
 - :p-fields. This should be either NIL, a list of lists or a function used
   to generate the p-fields starting from p4. Cf. the documentation of
   write-csound-score for more detail.
   Default: #'csound-p-fields-simple.

RETURN VALUE

 Returns the path of the file written, as a string.

EXAMPLE

(let* ((notes '(c4 d4 e4 f4 g4))
       (notes-len (length notes))
       (rthms '(q e s))
       (rthms-len (length rthms))
       (events (loop repeat 20
                     collect
                     (make-event (nth (random notes-len) notes)
                                 (nth (random rthms-len) rthms)
                                 :midi-channel (1+ (random 3))))))
  (events-update-time events)
  (event-list-to-csound-score events
                              nil ;; use all midi-channels
                              '(1 2)
                              :csound-file "/tmp/example.sco"))

;; => /tmp/example.sco

SYNOPSIS

(defun event-list-to-csound-score (event-list
                                   ;; when NIL, use all available
                                   ;; midi-channels and allocate them
                                   ;; to the given csound instruments
                                   ;; in a cyclical order
                                   midi-channels
                                   csound-instruments
                                   &key
                                     ;; add something just before .sco?
                                     (suffix "")
                                     (csound-file
                                      (format nil "~atmp~a.sco"
                                              (get-sc-config 'default-dir)
                                              suffix))
                                     ;; offset in seconds
                                     (offset 0)
                                     ;; add a comments section?
                                     (comments t)
                                     (delimiter #\space)
                                     (chords t)
                                     (p-fields #'csound-p-fields-simple))

slippery-chicken/find-boundaries [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 This methods tries to find structural boundaries (i.e section starts) in a
 complete piece. It does so by looking purely at event densities across bars
 and groups of bars; when these change sharply, a section change is noted.

ARGUMENTS

 - the slippery-chicken object to analyse

OPTIONAL ARGUMENTS

 - when looking at groups of bars, how many bars at a time? Default = 3
 - when looking at the sharpness of the envelope, what percentage change in
   number of events per bar (based in the min/max in the overall envelope)
   is considered a steep enough change. Default = 50 (%)

RETURN VALUE

 A list of bar numbers

SYNOPSIS

(defmethod find-boundaries ((sc slippery-chicken) &optional
                            (sum-bars 3) (jump-threshold 50))

slippery-chicken/find-end-tie [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 November 8th 2018, Heidhausen

DESCRIPTION

 Find the event which is the last in a group of tied notes.

ARGUMENTS

 - the slippery-chicken object
 - the event object at the start or in the middle of a the group of tied
   notes  

OPTIONAL ARGUMENTS

 - the function, generally some kind of error, to call if the given event is
   not tied from. Default = #'error.

RETURN VALUE

 the last event object which is tied to or NIL if the given event is not tied
 from. 

SYNOPSIS

(defmethod find-end-tie ((sc slippery-chicken) (e event)
                         &optional (on-fail #'error))

slippery-chicken/find-note [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 09-Apr-2011

DESCRIPTION

 Print to the Listener the numbers of all bars in a specified player's part
 of a given slippery-chicken object in which the specified pitch is
 found. Note that pitch symbols rather than objects are searched for so
 that small microtonal variations are be ignored. 

ARGUMENTS

 - A slippery-chicken object.
 - A player ID.
 - A note-name pitch symbol or a list of note-name pitch symbols for the
   pitch to be sought. If a list, this will be handled as a chord.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :written. T or NIL to indicate whether to look for the specified pitch as
   as a written note only. T = as written only. Default = NIL.
 - :start-bar. An integer that is the first bar in which to search for the
   given pitch. This number is inclusive. Default = 1.
 - :end-bar. An integer that is the last bar in which to search for the
   given pitch. This number is inclusive. Default = number of bars in the
   given slippery-chicken object.

RETURN VALUE

 Returns a list of all corresponding event objects found. Prints the bar
 numbers of the results directly to the Lisp listener.

EXAMPLE

;;; Prints the bar number for all occurrences in the entire piece by default ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s)
                                 (q (e) s +s h)
                                 ((e) s (s) (q) h))
                                :pitch-seq-palette ((1 2 3 4 5 1 3 2)))))
        :rthm-seq-map '((1 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (2 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (3 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))))))
  (find-note mini 'vc 'f4))

=>
bar 1
bar 3
bar 4
bar 6
bar 7
bar 9
bar 10
bar 12
bar 13
bar 15
bar 16
bar 18
bar 19
bar 21
bar 22
bar 24
bar 25
bar 27
bar 28
bar 30
bar 31
bar 33
bar 34
bar 36
bar 37
bar 39
bar 40
bar 42
bar 43
bar 45

;;; Examples of use specifying the optional arguments ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s)
                                 (q (e) s +s h)
                                 ((e) s (s) (q) h))
                                :pitch-seq-palette ((1 2 3 4 5 1 3 2)))))
        :rthm-seq-map '((1 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (2 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (3 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))))))
  (find-note mini 'cl 'f3)
  (find-note mini 'cl 'f3 :written t)
  (find-note mini 'vc 'f4 :start-bar 3 :end-bar 17))

SYNOPSIS

(defmethod find-note ((sc slippery-chicken) player note &key (written nil)
                      start-bar end-bar)

slippery-chicken/find-rehearsal-letters [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return in list form the numbers of bars in the given slippery-chicken
 object that have rehearsal letters.

ARGUMENTS

 - A slippery-chicken object.

RETURN VALUE

 A list of numbers.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((vn (violin :midi-channel 1))))
        :tempo-map '((1 (q 60)))
        :rehearsal-letters '(2 5 7)
        :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((2 4) (s) (s) e e e))
                                :pitch-seq-palette ((1 2 3)))))
        :rthm-seq-map '((1 ((vn (1 1 1 1 1 1 1))))))))
  (find-rehearsal-letters mini))

=> (2 5 7)

SYNOPSIS

(defmethod find-rehearsal-letters ((sc slippery-chicken))

slippery-chicken/get-all-events [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 August 22nd 2013 (Edinburgh)

DESCRIPTION

 Return a flat list containing all the events of a slippery-chicken object
 fo the given player.

ARGUMENTS

 - The slippery-chicken object
 - The player (symbol)

RETURN VALUE

 A list of event objects

SYNOPSIS

(defmethod get-all-events ((sc slippery-chicken) player)

slippery-chicken/get-all-section-refs [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return all section IDs as a list of lists. Subsection IDs will be contained 
 in the same sublists as their enclosing sections.

ARGUMENTS

 - A slippery-chicken object.

RETURN VALUE

 A list of lists.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax (alto-sax :midi-channel 1))))
        :set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
        :set-map '((1 (1 1 1))
                   (2 (1 1 1))
                   (3 ((a (1 1 1))
                       (b ((x (1 1 1))
                           (y (1 1 1))))))
                   (4 ((a (1 1 1))
                       (b (1 1 1))
                       (c (1 1 1 1))))
                   (5 (1 1 1))
                   (6 (1 1 1))
                   (7 (1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1))))
                        (2 ((sax (1 1 1))))
                        (3 ((a ((sax (1 1 1))))
                            (b ((x ((sax (1 1 1))))
                                (y ((sax (1 1 1))))))))
                        (4 ((a ((sax (1 1 1))))
                            (b ((sax (1 1 1))))
                            (c ((sax (1 1 1 1))))))
                        (5 ((sax (1 1 1))))
                        (6 ((sax (1 1 1))))
                        (7 ((sax (1 1 1))))))))
  (get-all-section-refs mini))

=> ((1) (2) (3 A) (3 B X) (3 B Y) (4 A) (4 B) (4 C) (5) (6) (7))

SYNOPSIS

(defmethod get-all-section-refs ((sc slippery-chicken))

slippery-chicken/get-bar [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get the rthm-seq-bar object located at a specified bar number within a
 given player's part.

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the number of the bar within the overall piece for
   which the rthm-seq-bar object is sought.
 - The ID of the player from whose part the rthm-seq-bar object is
   sought. If this is passed as NIL, the method will return the rthm-seq-bar
   objects for all players in the ensemble at the specified bar number. 
   NB: Although listed as an optional argument, the player ID is actually
   required. It is listed as optional due to method inheritance.

OPTIONAL ARGUMENTS

 - (see the comment on the <player> argument above.

RETURN VALUE

 A rthm-seq-bar object (or objects).

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s)
                                 (q e s s h)
                                 (e s s q h))
                                :pitch-seq-palette ((1 2 3 4 5 
                                                       1 3 2 4 5 
                                                       3 5 2 4 1))))) 
        :rthm-seq-map '((1 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (2 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (3 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))))))
  (get-bar mini 17 'cl))

=>
RTHM-SEQ-BAR: time-sig: 2 (4 4), time-sig-given: NIL, bar-num: 17, 
old-bar-nums: NIL, write-bar-num: NIL, start-time: 64.000, 
start-time-qtrs: 64.0, is-rest-bar: NIL, multi-bar-rest: NIL, 
show-rest: T, notes-needed: 5, 
tuplets: NIL, nudge-factor: 0.35, beams: NIL, 
current-time-sig: 2, write-time-sig: NIL, num-rests: 0, 
num-rhythms: 5, num-score-notes: 5, parent-start-end: NIL, 
missing-duration: NIL, bar-line-type: 0, 
player-section-ref: (2 CL), nth-seq: 0, nth-bar: 1, 
rehearsal-letter: NIL, all-time-sigs: (too long to print) 
sounding-duration: 4.000, 
rhythms: (
[...]

SYNOPSIS

(defmethod get-bar ((sc slippery-chicken) bar-num &optional player)

slippery-chicken/get-bar-from-ref [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return a rthm-seq-bar object from the piece by specifying its section,
 sequence number, bar number, and the player. Sequenz-num and bar-num are
 1-based.

ARGUMENTS

 - A slippery-chicken object.
 - A section ID (number or list).
 - A player ID.
 - An integer that is the number of the sequence in the section from which
   the bar is to be returned (1-based).
 - An integer that is the number of the bar within the given sequence
   (1-based). 

RETURN VALUE

 A rthm-seq-bar object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s)
                                 (q e s s h)
                                 (e s s q h))
                                :pitch-seq-palette ((1 2 3 4 5 
                                                       1 3 2 4 5 
                                                       3 5 2 4 1))))) 
        :rthm-seq-map '((1 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (2 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))
                        (3 ((cl (1 1 1 1 1))
                            (vc (1 1 1 1 1))))))))
  (get-bar-from-ref mini 2 'vc 3 2))
=>
RTHM-SEQ-BAR: time-sig: 2 (4 4), time-sig-given: NIL, bar-num: 23, 
old-bar-nums: NIL, write-bar-num: NIL, start-time: 88.000, 
start-time-qtrs: 88.0, is-rest-bar: NIL, multi-bar-rest: NIL, 
show-rest: T, notes-needed: 5, 
tuplets: NIL, nudge-factor: 0.35, beams: NIL, 
current-time-sig: 2, write-time-sig: NIL, num-rests: 0, 
num-rhythms: 5, num-score-notes: 5, parent-start-end: NIL, 
missing-duration: NIL, bar-line-type: 0, 
player-section-ref: (2 VC), nth-seq: 2, nth-bar: 1, 
rehearsal-letter: NIL, all-time-sigs: (too long to print) 
sounding-duration: 4.000, 
rhythms: (
[...]

SYNOPSIS

(defmethod get-bar-from-ref ((sc slippery-chicken) section player
                             sequenz-num bar-num)

slippery-chicken/get-bar-num-from-ref [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get the bar number of a given rthm-seq-bar object by specifying the
 section, sequenz, and number of the bar within that sequenz.

ARGUMENTS

 - A slippery-chicken object.
 - The ID of the section in which the given rthm-seq-bar object is located. 
 - An integer that is the number of the sequence within that section in
   which the rthm-seq-bar object is located.
 - The number of the bar within the given rthm-seq-bar object for which the
   overall bar number (within the entire piece) is sought.

RETURN VALUE

 An integer.

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((cl (b-flat-clarinet :midi-channel 1))
(vc (cello :midi-channel 2))))
:set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
:set-map '((1 (1 1 1 1 1))
(2 (1 1 1 1 1))
(3 (1 1 1 1 1)))
:rthm-seq-palette '((1 ((((4 4) h q e s s)
(q e s s h)
(e s s q h))
:pitch-seq-palette ((1 2 3 4 5 
1 3 2 4 5 
3 5 2 4 1))))) 
:rthm-seq-map '((1 ((cl (1 1 1 1 1))
(vc (1 1 1 1 1))))
(2 ((cl (1 1 1 1 1))
(vc (1 1 1 1 1))))
(3 ((cl (1 1 1 1 1))
(vc (1 1 1 1 1))))))))
(get-bar-num-from-ref mini 2 4 3))

=> 27

SYNOPSIS

(defmethod get-bar-num-from-ref ((sc slippery-chicken) section
                                 sequenz-num bar-num)

slippery-chicken/get-clef [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 11-Apr-2011

DESCRIPTION

 Get the clef symbol attached to a specified event. 

 NB: The very first clef symbol in the very first measure of a given
     player's part is determined by the corresponding instrument object and
     attached to differently; as such, it cannot be retrieved using this
     method. 
 NB: All clef symbols after the starting clef are added using the auto-clefs
     method, either directly or by default in the cmn-display or
     write-lp-data-for-all methods.

ARGUMENTS

 - A slippery-chicken object.
 - (NB: The optional arguments are actually required.)

OPTIONAL ARGUMENTS

 NB: The optional arguments are actually required.
 - An integer that is the number of the bar from which to return the clef
   symbol.
 - An integer that is the number of the event object within that bar from
   which to retrieve the clef symbol.
 - The ID of the player from whose part the clef symbol is to be returned. 

RETURN VALUE

 A clef symbol.

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((vc (cello :midi-channel 1))))
:tempo-map '((1 (q 96)))
:set-palette '((1 ((g2 f4 e5))))
:set-map '((1 (1 1 1)))
:rthm-seq-palette '((1 ((((5 4) e e e e e e e e e e))
:pitch-seq-palette ((1 1 2 2 2 2 3 3 3 1))))) 
:rthm-seq-map '((1 ((vc (1 1 1))))))))
(auto-clefs mini)
(get-clef mini 1 3 'vc))

=> TENOR

SYNOPSIS

(defmethod get-clef ((sc slippery-chicken) &optional bar-num event-num player)

slippery-chicken/get-current-instrument-for-player [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get the currently active instrument for a given player in a specified
 sequence of a slippery-chicken object, as defined in the
 instrument-change-map.

ARGUMENTS

 - The ID of the section from which to retrieve the current instrument for
   the specified player. This can also be a reference, e.g. in the form 
   '(2 1).
 - The ID of the player for whom the current instrument is sought. 
 - The number of the sequence from which to retrieve the current
   instrument. This is a 1-based number. A slippery-chicken object.

RETURN VALUE

 An instrument object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax ((alto-sax tenor-sax) :midi-channel 1))
                     (db (double-bass :midi-channel 2))))
        :instrument-change-map '((1 ((sax ((1 alto-sax) (3 tenor-sax)))))
                                 (2 ((sax ((2 alto-sax) (5 tenor-sax))))))
        :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))
                        (2 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))))))
  (get-current-instrument-for-player 2 'sax 3 mini))

=> 
INSTRUMENT: lowest-written: BF3, highest-written: FS6
lowest-sounding: CS3, highest-sounding: A5
starting-clef: TREBLE, clefs: (TREBLE), clefs-in-c: (TREBLE)
prefers-notes: NIL, midi-program: 66
transposition: EF, transposition-semitones: -9
score-write-in-c: NIL, score-write-bar-line: NIL
chords: NIL, chord-function: NIL, 
total-bars: 5 total-notes: 25, total-duration: 20.000
total-degrees: 2920, microtones: T
missing-notes: (BQF3 BQF4), subset-id: NIL
staff-name: alto saxophone, staff-short-name: alt sax,
                  
largest-fast-leap: 999, tessitura: BQF3
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: ALTO-SAX, tag: NIL, 
data: NIL

SYNOPSIS

(defmethod get-current-instrument-for-player (section player sequence
                                              (sc slippery-chicken))

slippery-chicken/get-event [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Retrieve a specified event object from a slippery-chicken object, giving
 bar number, event number, and player.

 NB: This counts returns event objects, regardless of whether they are notes
     or rests.

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the number of the bar from which the event object is
   to be returned.
 - An integer that is the number of the event object to be returned from
   that bar. This number is 1-based and counts all events, including notes,
   rests, and tied notes.
 - A symbol name for the player.

OPTIONAL ARGUMENTS

 - T or NIL to indicate whether an error should be signalled if the event
   doesn't exist. 

RETURN VALUE

 An event object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((vn (violin :midi-channel 1))
                     (vc (cello :midi-channel 2))))
        :tempo-map '((1 (q 60)))
        :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1)))
        :rthm-seq-palette '((1 ((((2 4) (e) e+e. 32 (32)))
                                :pitch-seq-palette (((1) 2)))))
        :rthm-seq-map '((1 ((vn (1 1 1))
                            (vc (1 1 1))))))))
  (get-event mini 2 4 'vn))

=> 
EVENT: start-time: 3.750, end-time: 3.875, 
duration-in-tempo: 0.125, 
compound-duration-in-tempo: 0.125, 
amplitude: 0.700 
bar-num: 2, marks-before: NIL, 
tempo-change: NIL 
instrument-change: NIL 
display-tempo: NIL, start-time-qtrs: 3.750, 
midi-time-sig: NIL, midi-program-changes: NIL, 
8va: 0
pitch-or-chord: 
PITCH: frequency: 293.665, midi-note: 62, midi-channel: 1 
pitch-bend: 0.0 
degree: 124, data-consistent: T, white-note: D4
nearest-chromatic: D4
src: 1.122462, src-ref-pitch: C4, score-note: D4 
qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,  
micro-tone: NIL, 
sharp: NIL, flat: NIL, natural: T, 
octave: 4, c5ths: 0, no-8ve: D, no-8ve-no-acc: D
show-accidental: T, white-degree: 29, 
accidental: N, 
accidental-in-parentheses: NIL, marks: NIL
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: D4, tag: NIL, 
data: D4
**************

written-pitch-or-chord: NIL
RHYTHM: value: 32.000, duration: 0.125, rq: 1/8, is-rest: NIL, 
score-rthm: 32.0, undotted-value: 32, num-flags: 3, num-dots: 0, 
is-tied-to: NIL, is-tied-from: NIL, compound-duration: 0.125, 
is-grace-note: NIL, needs-new-note: T, beam: NIL, bracket: NIL, 
rqq-note: NIL, rqq-info: NIL, marks: NIL, marks-in-part: NIL, 
letter-value: 32, tuplet-scaler: 1, grace-note-duration: 0.05
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: 32, tag: NIL, 
data: 32

SYNOPSIS

(defmethod get-event ((sc slippery-chicken) bar-num event-num player
                      &optional (error t))

slippery-chicken/get-events-from-to [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 22-Jul-2011 (Pula)

DESCRIPTION

 Return a list of event objects for a given player, specifying the region by
 bar and event number.

ARGUMENTS

 - A slippery-chicken object.
 - A player ID.
 - An integer (1-based) that is the first bar from which to return events.
 - An integer (1-based) that is the first event object in the start-bar to
   return.
 - An integer (1-based) that is the last bar from which to return events. 

OPTIONAL ARGUMENTS

 - An integer (1-based) that is the last event within the end-bar to
   return. 

RETURN VALUE

 A flat list of event objects.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax ((alto-sax tenor-sax) :midi-channel 1))
                     (db (double-bass :midi-channel 2))))
        :instrument-change-map '((1 ((sax ((1 alto-sax) (3 tenor-sax)))))
                                 (2 ((sax ((2 alto-sax) (5 tenor-sax))))))
        :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))
                        (2 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))))))
  (get-events-from-to mini 'sax 3 2 5 3))

=>
(
EVENT: start-time: 10.000, end-time: 11.000, 
duration-in-tempo: 1.000, 
compound-duration-in-tempo: 1.000, 
amplitude: 0.700 
bar-num: 3, marks-before: NIL, 
tempo-change: NIL 
instrument-change: NIL 
display-tempo: NIL, start-time-qtrs: 10.000, 
midi-time-sig: NIL, midi-program-changes: NIL, 
8va: 0
pitch-or-chord: 
PITCH: frequency: 164.814, midi-note: 52, midi-channel: 1 
pitch-bend: 0.0 
degree: 104, data-consistent: T, white-note: E3
nearest-chromatic: E3
src: 0.62996054, src-ref-pitch: C4, score-note: E3 
qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,  
micro-tone: NIL, 
sharp: NIL, flat: NIL, natural: T, 
octave: 3, c5ths: 0, no-8ve: E, no-8ve-no-acc: E
show-accidental: T, white-degree: 23, 
accidental: N, 
accidental-in-parentheses: NIL, marks: NIL
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: E3, tag: NIL, 
data: E3
**************

written-pitch-or-chord: 
PITCH: frequency: 369.994, midi-note: 66, midi-channel: 1 
pitch-bend: 0.0 
degree: 132, data-consistent: T, white-note: F4
nearest-chromatic: FS4
src: 1.4142135, src-ref-pitch: C4, score-note: FS4 
qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,  
micro-tone: NIL, 
sharp: T, flat: NIL, natural: NIL, 
octave: 4, c5ths: 1, no-8ve: FS, no-8ve-no-acc: F
show-accidental: T, white-degree: 31, 
accidental: S, 
accidental-in-parentheses: NIL, marks: NIL
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: FS4, tag: NIL, 
data: FS4
**************

RHYTHM: value: 4.000, duration: 1.000, rq: 1, is-rest: NIL, 
score-rthm: 4.0, undotted-value: 4, num-flags: 0, num-dots: 0, 
is-tied-to: NIL, is-tied-from: NIL, compound-duration: 1.000, 
is-grace-note: NIL, needs-new-note: T, beam: NIL, bracket: NIL, 
rqq-note: NIL, rqq-info: NIL, marks: NIL, marks-in-part: NIL, 
letter-value: 4, tuplet-scaler: 1, grace-note-duration: 0.05
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: Q, tag: NIL, 
data: Q
**************

        
EVENT: start-time: 11.000, end-time: 11.500, 
[...]

SYNOPSIS

(defmethod get-events-from-to ((sc slippery-chicken) player start-bar
                               start-event end-bar &optional end-event)

slippery-chicken/get-events-sorted-by-time [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get all the events of all players between the given bars and then order
 them by ascending time.

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :start-bar. An integer that is the first bar in which the function is to
   be applied to event objects. Default = 1.
 - :end-bar. NIL or an integer that is the last bar for which the event
   objects should be returned. If NIL, the last bar of the  
   slippery-chicken object is used. Default = NIL. 

RETURN VALUE

 A list of event objects.

SYNOPSIS

(defmethod get-events-sorted-by-time ((sc slippery-chicken)
                                      &key (start-bar 1) end-bar)

slippery-chicken/get-instrument-for-player-at-bar [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 09-Feb-2011

DESCRIPTION

 Get the current instrument for a specified player at a specified bar number
 in a slippery-chicken object, as defined in the instrument-change-map.

ARGUMENTS

 - The ID of a player in the slippery-chicken object.
 - An integer that is the number of the bar from which to get the current
   instrument.
 - A slippery-chicken object.

RETURN VALUE

 An instrument object.

EXAMPLE

(let* ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((sax ((alto-sax tenor-sax) :midi-channel 1))
                      (db (double-bass :midi-channel 2))))
         :instrument-change-map '((1 ((sax ((1 alto-sax) (3 tenor-sax)))))
                                  (2 ((sax ((2 alto-sax) (5 tenor-sax))))))
         :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
         :set-map '((1 (1 1 1 1 1))
                    (2 (1 1 1 1 1)))
         :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                 :pitch-seq-palette ((1 2 3 4 5)))))
         :rthm-seq-map '((1 ((sax (1 1 1 1 1))
                             (db (1 1 1 1 1))))
                         (2 ((sax (1 1 1 1 1))
                             (db (1 1 1 1 1))))))))
  (get-instrument-for-player-at-bar 'sax 3 mini))
=> 
INSTRUMENT: lowest-written: BF3, highest-written: FS6
lowest-sounding: AF2, highest-sounding: E5
starting-clef: TREBLE, clefs: (TREBLE), clefs-in-c: (BASS TREBLE)
prefers-notes: NIL, midi-program: 67
transposition: BF, transposition-semitones: -14
score-write-in-c: NIL, score-write-bar-line: NIL
chords: NIL, chord-function: NIL, 
total-bars: 5 total-notes: 25, total-duration: 20.000
total-degrees: 2710, microtones: T
missing-notes: (FQS3 FQS4), subset-id: NIL
staff-name: tenor sax, staff-short-name: ten sax,
                  
largest-fast-leap: 999, tessitura: FS3
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: TENOR-SAX, tag: NIL, 
data: NIL

SYNOPSIS

(defmethod get-instrument-for-player-at-bar (player bar (sc slippery-chicken))

slippery-chicken/get-last-bar [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 September 28th 2020, Heidhausen

DESCRIPTION

 Get the last bars for each of the players

ARGUMENTS

 - the slippery-chicken object

RETURN VALUE

 a list of rthm-seq-bar objects

SYNOPSIS

(defmethod get-last-bar ((sc slippery-chicken))

slippery-chicken/get-last-event [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 September 28th 2020, Heidhausen

DESCRIPTION

 Get the last events (of the last bars) for each of the players

ARGUMENTS

 - the slippery-chicken object

RETURN VALUE

 a list of event objects

SYNOPSIS

(defmethod get-last-event ((sc slippery-chicken))

slippery-chicken/get-nearest-event [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Find the nearest event by time to <reference-event> in the <search-player>.  

ARGUMENTS

 - the slippery-chicken object
 - the reference event object that we want to find the nearest event to in
   another player 
 - the player we want to find the nearest event in (symbol).

OPTIONAL ARGUMENTS

 - if T only return sounding events (pitches/chords) otherwise return the
   nearest rest or sounding event.
 - if T only return struck events i.e. ignore those that are tied to

RETURN VALUE

 An event object.

SYNOPSIS

(defmethod get-nearest-event ((sc slippery-chicken) reference-event
                              search-player &optional 
                              (ignore-rests t)
                              (ignore-tied t))

slippery-chicken/get-note [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get a numbered event from a specified bar of a given player's part within a
 slippery-chicken object.
 
 NB: Slippery-chicken doesn't have 'note' and 'rest' classes, rather both of
     these are events. The nomenclature 'note' and 'rest' are thus used here
     and elsewhere merely for convenience, to distinguish between sounding
     and non-sounding events.

 See also rthm-seq-bar methods for accessing notes by other means.

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the number of the bar from which to get the note
   (counting from 1). 
 - An integer that is the number of the note to get within that bar,
   counting tied notes (counting from 1). This can also be a list of numbers
   if accessing pitches in a chord (see below).
 - The ID of the player from whose part the note is to be retrieved.

OPTIONAL ARGUMENTS

 - T or NIL to indicate whether, when accessing a pitch in a chord, to
   return the written or sounding pitch. T = written. Default = NIL.

RETURN VALUE

 An event object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((vn (violin :midi-channel 1))))
        :tempo-map '((1 (q 60)))
        :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1)))
        :rthm-seq-palette '((1 ((((2 4) (e) e+e. 32 (32)))
                                :pitch-seq-palette (((1) 2)))))
        :rthm-seq-map '((1 ((vn (1))))))))
  (print (data (get-rest mini 1 2 'vn)))
  (print (data (get-note mini 1 2 'vn)))
  (print (data (get-note mini 1 '(2 1) 'vn)))
  (print (data (get-note mini 1 '(2 2) 'vn)))
  (print (is-tied-from (get-note mini 1 1 'vn))))

=>
32 
"E." 
C4 
A4
T

SYNOPSIS

(defmethod get-note ((sc slippery-chicken) bar-num note-num player 
                     &optional written)

slippery-chicken/get-num-sections [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return the number of sections in the given slippery-chicken object, as
 defined in e.g. in the set-map. N.B. If the object has subsections these
 are counted also, unless the optional argument is NIL.

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 - count-subsections: if T (default) count all sections and subsections. If
 NIL just the top-level sections.

RETURN VALUE

 An integer that is the number of section.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax (alto-sax :midi-channel 1))))
        :set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
        :set-map '((1 ((a (1 1 1 1))
                       (b (1 1 1 1))))
                   (2 (1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((a ((sax (1 1 1 1))))
                            (b ((sax (1 1 1 1))))))
                        (2 ((sax (1 1 1))))
                        (3 ((sax (1 1 1 1 1))))))))
  (get-num-sections mini))

=> 4

SYNOPSIS

(defmethod get-num-sections ((sc slippery-chicken)
                             &optional (count-subsections t))

slippery-chicken/get-phrases [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 This returns lists of events that make up phrases. Its notion of phrases
 is very simplistic but hopefully useful all the same: it's any sequence of
 sounding notes surrounded by rests.

ARGUMENTS

 - the slippery-chicken object
 - a single symbol or list of symbols representing the players from the
 ensemble. If nil all players will be processed.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :start-bar. An integer bar number where the process should start. If
 NIL we'll default to 1. Default = NIL. 
 - :end-bar. An integer bar number where the process should end. If
 NIL we'll default to the last bar. Default = NIL.
 - :pad. If a phrase starts or ends mid-bar, pad the first bar with leading
 rests and the last bar with trailing rests to ensure we have full bars.  

RETURN VALUE

 A list of sublists, one for each requested player. Each player sublist
 contains sublists also, with all the events in each phrase.

SYNOPSIS

(defmethod get-phrases ((sc slippery-chicken) players
                        &key start-bar end-bar pad)

slippery-chicken/get-pitch-symbols-for-player [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 April 27th 2022, Heidhausen

DESCRIPTION

 Get a list of all the pitches (as symbols) used in a piece on a
 player-by-player basis.

ARGUMENTS

 - the slippery-chicken object
 - the player (symbol) or list of players we want the pitches for. NB if nil,
 pitches for all players will be returned.

OPTIONAL ARGUMENTS

 - start bar number. If nil, this will be 1. Default = NIL.
 - end bar number. If nil, this will be the last bar. Default = NIL.
 - whether written as opposed to sounding note symbols should be
   returned. Default = NIL.

RETURN VALUE

 A nested list: each element is itself a two-element list where the first
 element is the player symbol and the second is an ascending ordered list of
 the pitches, with enharmonic equivalents removed.

EXAMPLE

(get-pitch-symbols-for-player +percussion+ 'perc)
((PERC
  (B4 C5 DF5 D5 DS5 E5 F5 GF5 G5 AF5 A5 BF5 B5 C6 CS6 D6 EF6 E6 F6 FS6 G6 AF6
   A6 BF6)))

SYNOPSIS

(defmethod get-pitch-symbols-for-player ((sc slippery-chicken) player
                                         &optional start-bar end-bar
                                           written)

slippery-chicken/get-player [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return the player object for the specified player.

ARGUMENTS

 - A slippery-chicken object.
 - A player ID.

RETURN VALUE

 A player object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((fl (flute :midi-channel 1))
                     (tp (b-flat-trumpet :midi-channel 2))
                     (vn (violin :midi-channel 3))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((fl (1 1 1 1 1))
                            (tp (1 1 1 1 1))
                            (vn (1 1 1 1 1))))))))
  (get-player mini 'vn))
=> 
PLAYER: (id instrument-palette): SLIPPERY-CHICKEN-STANDARD-INSTRUMENT-PALETTE 
doubles: NIL, cmn-staff-args: NIL, total-notes: 25, total-degrees: 3548, 
total-duration: 20.000, total-bars: 5, tessitura: B4
LINKED-NAMED-OBJECT: previous: (TP), this: (VN), next: NIL
NAMED-OBJECT: id: VN, tag: NIL, 
data: 
INSTRUMENT: lowest-written: G3, highest-written: C7
...

SYNOPSIS

(defmethod get-player ((sc slippery-chicken) player)

slippery-chicken/get-rest [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Retrieve the event object that contains the specified rest in a
 slippery-chicken object by giving bar number, rest number and player.

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the number of the bar from which to retrieve the rest
   event object.
 - An integer that is the number of the rest (not the number of the event)
   within that bar, counting from 1.
 - The ID of the player from whose part to retrieve the rest object.

RETURN VALUE

 An event object.

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((vn (violin :midi-channel 1))
(vc (cello :midi-channel 2))))
:tempo-map '((1 (q 60)))
:set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
:set-map '((1 (1 1 1)))
:rthm-seq-palette '((1 ((((2 4) (e) e+e. 32 (32)))
:pitch-seq-palette (((1) 2)))))
:rthm-seq-map '((1 ((vn (1 1 1))
(vc (1 1 1))))))))
(get-rest mini 2 1 'vc))

=> 
EVENT: start-time: 2.000, end-time: 2.500, 
duration-in-tempo: 0.500, 
compound-duration-in-tempo: 0.500, 
amplitude: 0.700 
bar-num: 2, marks-before: NIL, 
tempo-change: NIL 
instrument-change: NIL 
display-tempo: NIL, start-time-qtrs: 2.000, 
midi-time-sig: NIL, midi-program-changes: NIL, 
8va: 0
pitch-or-chord: NIL
written-pitch-or-chord: NIL
RHYTHM: value: 8.000, duration: 0.500, rq: 1/2, is-rest: T, 
score-rthm: 8.0, undotted-value: 8, num-flags: 1, num-dots: 0, 
is-tied-to: NIL, is-tied-from: NIL, compound-duration: 0.500, 
is-grace-note: NIL, needs-new-note: NIL, beam: NIL, bracket: NIL, 
rqq-note: NIL, rqq-info: NIL, marks: NIL, marks-in-part: NIL, 
letter-value: 8, tuplet-scaler: 1, grace-note-duration: 0.05
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: E, tag: NIL, 
data: E

SYNOPSIS

(defmethod get-rest ((sc slippery-chicken) bar-num rest-num player)

slippery-chicken/get-section [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return the section object with the specified reference ID.

ARGUMENTS

 - A slippery-chicken object.
 - A reference ID.

RETURN VALUE

 A section object.

EXAMPLE

(let ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((sax (alto-sax :midi-channel 1))
                      (db (double-bass :midi-channel 2))))
         :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
         :set-map '((1 (1 1 1 1 1))
                    (2 (1 1 1 1 1)))
         :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                 :pitch-seq-palette ((1 2 3 4 5)))))
         :rthm-seq-map '((1 ((sax (1 1 1 1 1))
                             (db (1 1 1 1 1))))
                         (2 ((sax (1 1 1 1 1))
                             (db (1 1 1 1 1))))))))
  (get-section mini 2))
=> 
SECTION: 
RECURSIVE-ASSOC-LIST: recurse-simple-data: NIL
num-data: 2
linked: T
full-ref: (2)
ASSOC-LIST: warn-not-found NIL
CIRCULAR-SCLIST: current 0
SCLIST: sclist-length: 2, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
BAR-HOLDER: 
start-bar: 6
end-bar: 10
num-bars: 5
start-time: 20.0
end-time: 40.0
start-time-qtrs: 0
end-time-qtrs: 40.0
num-notes (attacked notes, not tied): 50
num-score-notes (tied notes counted separately): 50 
num-rests: 0
duration-qtrs: 20.0 
duration: 20.0 (20.000)

SYNOPSIS

(defmethod get-section ((sc slippery-chicken) reference &optional (warn t))

slippery-chicken/get-section-bar-nums [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

AUTHOR

 Daniel Ross (mr.danielross[at]gmail[dot]com) 

DATE

 Mon 13 Jan 2020 15:23:17 GMT

DESCRIPTION

 Get the start and end bar numbers of each section of a slippery chicken
 piece, handlily formatted in an assoc list.

ARGUMENTS

 A slippery chicken object

OPTIONAL ARGUMENTS

 Keyword args:
 :start - the first section to look at. (Default = 1)
 :end - the last section to look at. (Default = nil, look to the end.)

RETURN VALUE

 An assoc list where each key is a section number and its data is a list
 containing the start and end bar numbers of that section.

EXAMPLE

(let ((mini
         (make-slippery-chicken
          '+mini+
          :ensemble '(((sax (alto-sax :midi-channel 1))))
          :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
          :set-map '((1 (1 1 1 1 1))
                     (2 (1 1 1 1 1))
                     (3 (1 1 1 1 1)))
          :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                  :pitch-seq-palette ((1 2 3 4 5)))))
          :rthm-seq-map '((1 ((sax (1 1 1 1 1))))
                          (2 ((sax (1 1 1 1 1))))
                          (3 ((sax (1 1 1 1 1))))))))
      (get-section-bar-nums mini))

=> 
ASSOC-LIST: warn-not-found T
CIRCULAR-SCLIST: current 0
SCLIST: sclist-length: 3, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, 
                     this: NIL, 
                     next: NIL
NAMED-OBJECT: id: SECTION-BAR-NUMS, tag: NIL, 
data: (
NAMED-OBJECT: id: 1, tag: NIL, 
data: (1 5)
**************

       
NAMED-OBJECT: id: 2, tag: NIL, 
data: (6 10)
**************

       
NAMED-OBJECT: id: 3, tag: NIL, 
data: (11 15)
**************
)
**************

SYNOPSIS

(defmethod get-section-bar-nums ((sc slippery-chicken)
                                 &key (start 1) (end nil)
                                   (assoc-list-id 'section-bar-nums))

slippery-chicken/get-section-refs [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 07-May-2012

DESCRIPTION

 Return the reference IDs for all section and subsections of a given
 slippery-chicken object.

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the first top-level section for which to return the
   reference IDs. As this number refers to the number of top-level sections
   only, any subsections will be contained in these and only count as 1.
 - An integer that is the number of consecutive sections to return section
   reference IDs.

RETURN VALUE

 A list of lists containing the section reference IDs of the specified
 range in the slippery-chicken object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax (alto-sax :midi-channel 1))))
        :set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
        :set-map '((1 (1 1 1))
                   (2 (1 1 1))
                   (3 ((a (1 1 1))
                       (b ((x (1 1 1))
                           (y (1 1 1))))))
                   (4 ((a (1 1 1))
                       (b (1 1 1))
                       (c (1 1 1 1))))
                   (5 (1 1 1))
                   (6 (1 1 1))
                   (7 (1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1))))
                        (2 ((sax (1 1 1))))
                        (3 ((a ((sax (1 1 1))))
                            (b ((x ((sax (1 1 1))))
                                (y ((sax (1 1 1))))))))
                        (4 ((a ((sax (1 1 1))))
                            (b ((sax (1 1 1))))
                            (c ((sax (1 1 1 1))))))
                        (5 ((sax (1 1 1))))
                        (6 ((sax (1 1 1))))
                        (7 ((sax (1 1 1))))))))
  (get-section-refs mini 2 4))

=> ((2) (3 A) (3 B X) (3 B Y) (4 A) (4 B) (4 C) (5))

SYNOPSIS

(defmethod get-section-refs ((sc slippery-chicken) start-section num-sections)

slippery-chicken/get-sequenz-from-section [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get the sequenz object specified by the section, player and sequenz number
 given. 

ARGUMENTS

 - a slippery-chicken object
 - the player (symbol)
 - the sequenz number, counting from 1

RETURN VALUE

 the respective sequenz object

SYNOPSIS

(defmethod get-sequenz-from-section ((sc slippery-chicken)
                                     section-ref player-ref seq-num) ; 1-based

slippery-chicken/get-set-for-bar-num [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 July 11th 2020, Heidhausen

DESCRIPTION

 Get the complete-set object from the set-palette that was used in the
 generation of a specific bar.

ARGUMENTS

 - the slippery-chicken object
 - the bar number (integer)

RETURN VALUE

 a complete-set object or NIL if the bar doesn't exist or the first event of
 the bar has no set-ref slot value, for any of the players, for some reason
 (e.g. not initialized by make-slippery-chicken)

SYNOPSIS

(defmethod get-set-for-bar-num ((sc slippery-chicken) bar-num)

slippery-chicken/get-starting-ins [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return the instrument object that is the first instrument object used by a
 specified player in a given slippery-chicken object.

ARGUMENTS

 - A slippery-chicken object.
 - A player ID.

RETURN VALUE

 An instrument object.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax ((alto-sax tenor-sax) :midi-channel 1))
                     (db (double-bass :midi-channel 2))))
        :instrument-change-map '((1 ((sax ((1 alto-sax) (3 tenor-sax)))))
                                 (2 ((sax ((2 alto-sax) (5 tenor-sax))))))
        :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))
                        (2 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))))))
  (get-starting-ins mini 'sax))

=> 
INSTRUMENT: lowest-written: BF3, highest-written: FS6
lowest-sounding: CS3, highest-sounding: A5
starting-clef: TREBLE, clefs: (TREBLE), clefs-in-c: (TREBLE)
prefers-notes: NIL, midi-program: 66
transposition: EF, transposition-semitones: -9
score-write-in-c: NIL, score-write-bar-line: NIL
chords: NIL, chord-function: NIL, 
total-bars: 5 total-notes: 25, total-duration: 20.000
total-degrees: 2920, microtones: T
missing-notes: (BQF3 BQF4), subset-id: NIL
staff-name: alto saxophone, staff-short-name: alt sax,

largest-fast-leap: 999, tessitura: BQF3
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: ALTO-SAX, tag: NIL, 
data: NIL

SYNOPSIS

(defmethod get-starting-ins ((sc slippery-chicken) player) ; symbol

slippery-chicken/get-tempo [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return the tempo object in effect for a specified bar of a given
 slippery-chicken object.

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the number of a bar within that slippery-chicken
   object. 

RETURN VALUE

 A tempo object.

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((sax (alto-sax :midi-channel 1))))
:tempo-map '((1 (q 60)) (5 (e 72)) (7 (q. 176 "prestissimo")))
:set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
:set-map '((1 (1 1 1 1 1 1 1 1)))
:rthm-seq-palette '((1 ((((4 4) h q e s s))
:pitch-seq-palette ((1 2 3 4 5)))))
:rthm-seq-map '((1 ((sax (1 1 1 1 1 1 1 1))))))))
(get-tempo mini 6))

=> 
TEMPO: bpm: 72, beat: E, beat-value: 8.0, qtr-dur: 1.6666666 
qtr-bpm: 36.0, usecs: 1666666, description: NIL
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: NIL, tag: NIL, 
data: 72

SYNOPSIS

(defmethod get-tempo ((sc slippery-chicken) bar-num)

slippery-chicken/get-time-sig [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get the time-sig object associate with a specified bar number in a given
 slippery-chicken object.

ARGUMENTS

 - A slippery-chicken object.
 - An integer that is the number of the bar for which to the time-sig object
   is to be returned. NB: Although this argument is listed as optional in
   the method definition (due to inheritance), it is actually required.

OPTIONAL ARGUMENTS

 - (see above).

RETURN VALUE

 A time-sig object.

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((sax (alto-sax :midi-channel 1))))
:set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
:set-map '((1 (1 1 1)))
:rthm-seq-palette '((1 ((((4 4) h q e s s)
((5 8) q e s s e)
((3 16) s e))
:pitch-seq-palette ((1 2 3 4 5 1 2 3 4 5 1
2))))) 
:rthm-seq-map '((1 ((sax (1 1 1))))))))
(get-time-sig mini 2))

=> 
TIME-SIG: num: 5, denom: 8, duration: 2.5, compound: NIL, midi-clocks: 24, num-beats: 5
SCLIST: sclist-length: 2, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: "0508", tag: NIL, 
data: (5 8)

SYNOPSIS

(defmethod get-time-sig ((sc slippery-chicken) &optional bar-num)

slippery-chicken/get-transposition-at-bar [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 24-Mar-2011

DESCRIPTION

 Return the number of semitones difference between the sounding pitches and
 written pitches of a given player's part in a specified bar within a
 slippery-chicken object; e.g. bass clarinet = -14.

ARGUMENTS

 - The ID of the player for whom the transposition value is sought.
 - An integer which is the number of the bar for which the transposition
   value is sought.
 - A slippery-chicken object.

RETURN VALUE

 An integer.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax (alto-sax :midi-channel 1))))
        :set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
        :set-map '((1 (1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1))))))))
  (get-transposition-at-bar 'sax 2 mini))

=> -9

SYNOPSIS

(defmethod get-transposition-at-bar (player bar (sc slippery-chicken))

slippery-chicken/lp-display [ Functions ]

[ Top ] [ slippery-chicken ] [ Functions ]

DESCRIPTION

 This function has exactly the same arguments as write-lp-data-for all and
 only differs from that method in that after writing all the Lilypond text
 files for the score, it calls Lilypond to render the PDF, which is then
 opened automatically from within Lisp (if the value of 
 (get-sc-config 'lp-display-auto-open) is T).
 
 In order to work properly, you'll need to make sure the value of the
 'lilypond-command configuration parameter is set via (set-sc-config ...) to
 the full path of your Lilypond command (not the app: it's usually
 /path/to/Lilypond.app/Contents/Resources/bin/lilypond on OSX).
 
 NB Only available with CCL and SBCL on OSX. With SBCL on OSX the output
 from Lilypond is only printed once the process has exited, so it may take a
 while until you see anything.

ARGUMENTS

 See write-lp-data-for-all

RETURN VALUE

 An integer: the shell's exit code for the PDF open command, usually 0 for
 success. Second returned value is the patch to the PDF file.

SYNOPSIS

(defun lp-display (&rest args)

slippery-chicken/make-slippery-chicken [ Functions ]

[ Top ] [ slippery-chicken ] [ Functions ]

DESCRIPTION

 Make a slippery-chicken object using the specified data. This is the
 function that will be used most often to "put it all together", and many of
 its slots require full objects of other classes rather than just straight
 data. These objects, such as rthm-seq-palette, rthm-seq-map etc, are also
 documented in detail elsewhere in the robodoc and the user's manual.

 NB Usually, when no set pitches are available for an instrument, an error
 will be signalled. As of October 2018, you can instead allocate an 'empty
 sequence' (rests) in such cases by setting the following before calling
 make-slippery-chicken:
 (set-sc-config 'pitch-seq-no-pitches-error nil)

ARGUMENTS

 - A symbol that is the name/ID of the object. The value passed to this
   argument will be made into a global variable, so that the newly created
   slippery-chicken object and the data it contains remain in memory and can
   be accessed and modified after the object is generated.

OPTIONAL ARGUMENTS

 keyword arguments:
 NB: Although these arguments are technically optional, the slippery-chicken
     object will only be complete and make musical sense if many of the core
     elements are present.
 - :title. A string that will be used as the title of the piece. The value
   given for this object will be used as both the header for the printable
   output as well as the base for any file names generated by the
   write-lp-data-for-all method. Default = "slippery-chicken-piece".
 - :subtitle. A string that will be used as the subtitle of the piece. Works
   in Lilypond scores only. 
 - :instrument-palette. An instrument-palette object. This will be the
   palette of instrument objects available to the players of in the given
   slippery-chicken object's ensemble slot. 
   Default = +slippery-chicken-standard-instrument-palette+.
 - :ensemble. A recursive association list that will be used as the data to
   create an ensemble object populated with player objects within the
   slippery-chicken object. The format of this list will be a list of
   user-defined player IDs each coupled with a list of instrument object IDs
   from the current instrument-palette and various player object
   parameters. See the user's manual and robodoc entries on the ensemble and
   player classes for more detail.
 - :set-palette. A recursive association list that will be used as the data
   to create a set-palette object within the slippery-chicken object. This
   object is where the collections of possible pitches for any given
   sequence are defined. The format of this list will be a list of IDs for
   each set of pitches, each coupled with a list of note-name symbols for
   the pitches that will be used to make that set. See the user's manual and
   the robodoc entry on the set-palette class for more detail.
 - :set-map. A recursive association list that will be used as the data to
   create a set-map object within the slippery-chicken object. This is where
   the order in which the pitch collections defined in the set-palette will
   be used in the piece. The format of this list will be a list of IDs from
   the given slippery-chicken object's structure coupled with a list of IDs
   from those given to the sets in the set-palette. There must be an equal
   number of sections in this list as there are in the rthm-seq-map, and
   they must have identical names. There must be an equal number of
   individual set IDs in each list paired with the section IDs as there are
   in the corresponding lists of the rthm-seq-map. See the user's manual and
   the robodoc entries for the set-map and sc-map for more detail.
 - :rthm-seq-palette. A recursive association list that will be used as the
   data to create a rthm-seq-palette object within the slippery-chicken
   object. This object is where the collections of possible rhythm sequences
   for any given sequence in the piece are defined. This list will take the
   format of a list of IDs paired with a list of data for individual
   rthm-seq objects. These in turn will consist of one or more lists of
   rhythm data for rthm-seq-bar objects, as well pitch-seq-palettes and
   marks data for the individual rthm-seq objects to be created. See the
   user's manual as well as the robodoc entries for rthm-seq-palette,
   rthm-seq, rthm-seq-bar, rhythm, and pitch-seq-palette for more detail.
 - :rthm-seq-map. A recursive association list that will be used as the data
   to create a rthm-seq-map object within the slippery-chicken object. This
   is where the order in which the rhythm sequences defined in the
   rthm-seq-palette will be used in the piece. It will take the format of a
   list of section IDs, of which there must be an equal number as are given
   in the set-map, each coupled with a list of player IDs, as defined in the
   ensemble slot of the given slippery-chicken object. The player IDs in
   turn are coupled with a list of IDs for rthm-seq objects, as defined in
   the rthm-seq-palette. Each of these lists must contain the same number of
   elements as are contained in each of the set-map sections. See the user's
   manual and robodoc entries for rthm-seq-map and sc-map for more details.
 - :snd-output-dir. A string that will be used as the directory path for any
   output generated by clm-play in conjunction with sound files listed in
   the sndfile-palette (see below). Default = (get-sc-config 'default-dir).
 - :sndfile-palette. A recursive association list that will be used as the
   data to create a sndfile-palette object within the slippery-chicken
   object. This is where the list is defined that contains all possible
   source sound files which may be used in conjunction with output generated
   by clm-play. This list will take the format of a list of IDs for
   sound-file groups, coupled with lists of file names and various other
   parameters associated with the sndfile class. The list of sound-file
   groups is followed by a list of directory paths where the given sound
   files are located and an optional list of file extensions. See the user's
   manual and the robodoc entries on sndfile-palette, sndfile, and clm-play
   for more detail.
 - :tempo-map. A recursive association list that will be used as the data to
   create tempo objects within the slippery-chicken object. This is one of
   two options for specifying the sequence of tempo changes for a given
   piece (also see tempo-curve below). The format will be a list of integers
   that are measure numbers within the piece, each coupled with tempo
   indications in the form (beat-unit bpm). See the user's manual as well as
   the robodoc entry for tempo-map for more detail. NB: This slot cannot be
   used together with :tempo-curve.
 - :tempo-curve. A list of data that will be used to create tempo objects
   within the slippery-chicken object, based on an interpolated list of
   break-point pairs. This is one of two options for specifying the
   sequence of tempo changes for a given piece (also see tempo-map above.)
   The first item in the list will be the number of bars between each new
   tempo object. The second item is the beat basis for the tempo objects
   made. The third and final argument is the list of break-point pairs, of
   which the first is a value on an arbitrary x-axis and the second is a
   number of beats-per-minute. See the user's manual and the robodoc entry
   for tempo-curve for more detail. NB: This slot cannot be used together
   with :tempo-map.
 - :staff-groupings. A list of integers that indicate the placement of group
   brackets for the printable output. Each number represents a consecutive
   number of players, in the order they appear in the ensemble object, that
   will be included in each consecutive group. The sum of the numbers in
   this list must be equal to the number of players in the ensemble. See the
   user's manual for more detail.
 - :instrument-change-map. A recursive association list that will be used as
   the data to create an instrument-change-map object within the
   slippery-chicken object. This will be used to indicate where those
   players in the ensemble that play multiple instruments will change
   instruments. The format will be a list of section IDs coupled with a list
   of player IDs, each of which in turn is coupled with a list of 2-item
   lists consisting of a sequence number paired with the ID (name) of one of
   the instrument objects assigned to that player in the ensemble
   object. See the user's manual and the robodoc entries for
   instrument-change-map for more detail.
 - :set-limits-high. A recursive association list that will be used to limit
   the uppermost pitches of either the parts of individual players or of the
   entire ensemble. The format will be a list of player IDs, as defined in
   the ensemble object, each paired with a list of break-point pairs that
   consist of a value on an arbitrary x-axis paired with a note-name pitch
   symbol. These break-point envelopes are applied to the entire duration of
   the piece. See the user's manual for more detail.
 - :set-limits-low. A recursive association list that will be used to limit
   the lowermost pitches of either the parts of individual players or of the
   entire ensemble. The format will be a list of player IDs, as defined in
   the ensemble object, each paired with a list of break-point pairs that
   consist of a value on an arbitrary x-axis paired with a note-name pitch
   symbol. These break-point envelopes are applied to the entire duration of
   the piece. See the user's manual for more detail.
 - :fast-leap-threshold. A number that is the longest duration of a note in
   seconds that can be followed by a leap of a large interval, as defined in
   the largest-fast-leaps slot of the instrument objects. Default = 0.125.
 - :instruments-hierarchy. A list of player IDs from the given
   slippery-chicken object's ensemble that will specify the order in which
   slippery chicken's pitch selection algorithm will choose pitches for the
   instruments. By default (when NIL) this order follows the order in which
   the instrument objects appear in the ensemble object. See the user's
   manual for more detail. Default = NIL.
 - :rehearsal-letters. A list of numbers that are measure numbers at which
   consecutive rehearsal letters will be placed. Since rehearsal letters are
   technically actually place on the right-hand bar line of the previous
   measure, measure 1 cannot be entered here. Slippery chicken automatically
   proceeds consecutively through the alphabet, so only numbers are required
   here. See the user's manual for more detail. If NIL, no rehearsal letters
   will be added to the score. Default = NIL.
 - :avoid-melodic-octaves. T or NIL to indicate whether two linearly
   consecutive pitches in the part of a given player may be of the same
   pitch class but a different octave. T = avoid melodic octaves. 
   Default = T.
 - :instruments-write-bar-nums. A list of player IDs above whose parts in
   the score bar numbers should be written. If NIL, bar numbers will be
   written above the top player in each group. NB: This slot affects CMN
   output only. Default = NIL.
 - :pitch-seq-index-scaler-min. A decimal number that affects the likelihood
   that slippery-chicken's pitch selection algorithm will choose pitches for
   an instrument that have also already been assigned to other players. In
   general terms, the higher this number is, the more likely it will be that
   instruments may be assigned the same pitches, though this will of course
   also be dependent on other factors, such as the characteristics of those
   instruments and the pitches in the current set. See the user's manual on
   pitches and the robodoc entries for pitch-seq for more detail. 
   Default = 0.5.
 - :bars-per-system-map. A list of 2-item lists, each of which consists of a
   measure number coupled with a number of measures to be placed in each
   system starting at that measure number. NB: This list only affects CMN
   output. See the user's manual on score layout for more details.
 - :composer. A string that will be used for the composer portion of the
   header on the score's first page in LilyPond output. If NIL, no
   composer's name will appear in the score. Default = NIL.
 - :year. A string that will be concatenated with the composer portion of the
   header on the score's first page in LilyPond output. If NIL, no
   year will appear in the score. Default = NIL.
 - :rthm-seq-map-replacements. A list of lists in the format 
   '(((1 2 va) 3 2) ((2 3 vn) 4 3)) that indicate changes to individual
   elements of lists within the given rthm-seq-map object. Each such list
   indicates a change, the first element of the list being the reference
   into the rthm-seq-map (the vla player of section 1, subsection 2 in the
   first example here), the second element is the nth of the data list for
   this key to change, and the third is the new data. If NIL, no changes
   will be made. See the robodoc entries for rthm-seq-map for more
   detail. Default = NIL.
 - :set-map-replacements. A list of lists in the format 
   '((1 2 2) (3 3 1)) that indicate changes to individual elements of lists
   within the given set-map object. Each such list indicates a change, the
   first element of the list being the reference into the set-map (the
   section, followed by a subsection if any exist), the second element being
   the nth of the data list for to change, and the third being the new
   data. If NIL, no changes will be made. See the robodoc entries for sc-map
   for more detail. Default = NIL.
 - :key-sig. A two-element list indicating starting key signature for the
   piece, e.g. '(ef minor). Usual note name symbols apply (e.g. ds = d
   sharp, bf - b flat). Implies nothing beyond the signature, i.e. no
   conformity to tonality expected. Default '(c major) i.e. no key
   signature.
 - :transposition-curve. An envelope describing over the duration of the
   piece (but using any arbitrary x-axis range) what transpositions in
   semitones should be applied to the sets. Default = (0 0 100 0) 
 (- :warn-ties. This slot is now obsolete, but is left here for backwards
    compatibility with pieces composed with earlier versions of
    slippery-chicken. Default = T.)

RETURN VALUE

 T

EXAMPLE

;;; An example using all slots
(let ((mini
       (make-slippery-chicken
        '+mini+
        :title "A Little Piece"
        :composer "Joe Green"
        :ensemble '(((fl ((flute piccolo) :midi-channel 1))
                     (cl (b-flat-clarinet :midi-channel 2))
                     (hn (french-horn :midi-channel 3))
                     (tp (b-flat-trumpet :midi-channel 4))
                     (vn (violin :midi-channel 5))
                     (va (viola :midi-channel 6))
                     (vc (cello :midi-channel 7))))
        :set-palette '((1 ((fs2 b2 d4 a4 d5 e5 a5 d6)))
                       (2 ((b2 fs2 d4 e4 a4 d5 e5 a5 d6)))
                       (3 ((cs3 fs3 e4 a4 e5 a5 e6))))
        :set-map '((1 (2 1 2 3 1 3 1))
                   (2 (1 1 3 2 2 3 1))
                   (3 (2 3 1 3 1 1 2)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                :pitch-seq-palette ((1 2 3))))
                            (2 ((((4 4) (q) e (s) s h))
                                :pitch-seq-palette ((2 1 3))))
                            (3 ((((4 4) e (s) s h (q)))
                                :pitch-seq-palette ((3 2 1)))))
        :rthm-seq-map '((1 ((fl (2 3 3 1 1 1 2))
                            (cl (3 2 1 1 2 1 3))
                            (hn (1 2 3 1 1 3 2))
                            (tp (2 1 1 3 3 2 1))
                            (vn (3 1 3 2 1 1 2))
                            (va (2 1 1 1 3 2 3))
                            (vc (1 2 3 1 3 2 1))))
                        (2 ((fl (3 1 3 2 2 1 1))
                            (cl (1 1 2 3 1 3 2))
                            (hn (1 3 2 1 3 1 2))
                            (tp (1 1 1 3 3 2 2))
                            (vn (2 1 3 1 3 1 2))
                            (va (2 2 3 1 1 3 1))
                            (vc (1 3 1 2 2 1 3))))
                        (3 ((fl (1 1 3 2 1 3 2))
                            (cl (2 1 2 3 3 1 1))
                            (hn (3 2 1 1 1 3 2))
                            (tp (3 3 1 1 2 1 2))
                            (vn (3 1 3 2 1 1 2))
                            (va (3 2 1 1 3 2 1))
                            (vc (1 3 2 1 2 3 1)))))
        :snd-output-dir "/tmp"
        :sndfile-palette '(((sndfile-grp-1
                             ((test-sndfile-1.aiff :start 0.021 :end 0.283)
                              (test-sndfile-2.aiff)
                              (test-sndfile-3.aiff)))
                            (sndfile-grp-2
                             ((test-sndfile-4.aiff :frequency 834)
                              (test-sndfile-5.aiff)
                              (test-sndfile-6.aiff))))
                           ("/path/to/test-sndfiles-dir-1"
                            "/path/to/test-sndfiles-dir-2"))
        ;; :tempo-map '((1 (q 84)) (9 (q 72))) ; ; ;
        :tempo-curve '(5 q (0 40 25 60 50 80 75 100 100 120))
        :staff-groupings '(2 2 3)
        :instrument-change-map '((1 ((fl ((1 flute) (3 piccolo) (5 flute))))))
        :set-limits-low '((fl (0 c5 50 g5 100 c5))
                          (cl (0 c4 50 f4 100 c4))
                          (hn (0 f3 50 c4 100 f3))
                          (tp (0 c4 50 f4 100 c4))
                          (vn (0 e5 50 a5 100 e5))
                          (va (0 c3 50 f3 100 c3))
                          (vc (0 c2 50 f3 100 c2)))
        :set-limits-high '((fl (0 d6 50 a6 100 d6))
                           (cl (0 c5 50 a5 100 c5))
                           (hn (0 f4 50 c5 100 f4))
                           (tp (0 f5 50 c5 100 f5))
                           (vn (0 c6 50 e6 100 c6))
                           (va (0 g4 50 d5 100 g4))
                           (vc (0 c4 50 f4 100 c4)))
        :fast-leap-threshold 0.5
        :instruments-hierarchy '(fl vn cl tp va hn vc)
        :rehearsal-letters '(3 11 19)
        :avoid-melodic-octaves nil
        :instruments-write-bar-nums '(fl cl hn tp)
        :pitch-seq-index-scaler-min 0.1
        :bars-per-system-map '((1 1) (2 2) (3 3) (7 4) (11 5))
        :rthm-seq-map-replacements '(((1 va) 3 1) ((2 fl) 4 3))
        :set-map-replacements '((1 2 2) (3 3 1)))))
  (midi-play mini :midi-file "/tmp/mini.mid")
  (cmn-display mini)
  (write-lp-data-for-all mini))

SYNOPSIS

(defun make-slippery-chicken (name &key 
                                     rthm-seq-palette 
                                     rthm-seq-map
                                     set-palette 
                                     set-map 
                                     sndfile-palette 
                                     tempo-map 
                                     tempo-curve 
                                     (snd-output-dir (get-sc-config
                                                      'default-dir))
                                     instrument-change-map 
                                     instruments-write-bar-nums
                                     bars-per-system-map
                                     staff-groupings
                                     rthm-seq-map-replacements
                                     set-map-replacements
                                     set-limits-low 
                                     set-limits-high
                                     instrument-palette 
                                     ensemble 
                                     rehearsal-letters 
                                     (fast-leap-threshold 0.125)
                                     instruments-hierarchy 
                                     (title "slippery chicken piece") 
                                     subtitle
                                     composer year
                                     (avoid-melodic-octaves t)
                                     (avoid-used-notes t)
                                     (pitch-seq-index-scaler-min 0.5) 
                                     defer
                                     ;; MDE Mon Jul  2 16:08:42 2012
                                     (key-sig '(c major))
                                     ;; MDE Thu Sep  6 14:34:14 2018
                                     (transposition-curve '(0 0 100 0))
                                     (warn-ties t))

slippery-chicken/midi-play [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Generate a MIDI file from the data of the specified slippery-chicken
 object. Note that for events that contain chords, the event's amplitude slot
 will be used for all pitches unless each individual pitch object in the
 chord has its amplitude slot set to a number (in which case the event's
 amplitude slot will be ignored.)  

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :midi-file. The name of the MIDI file to produce, including directory
   path and extension. Default is a filename extracted from the title of the
   sc piece, placed in the (get-sc-config 'default-dir) directory (default
   /tmp). 
 - :voices. NIL or a list of player IDs indicating which of the players'
   parts are to be included in the resulting MIDI file. If NIL, all players'
   parts will be included. Default = NIL.
 - :players. A synonym for voices. This is the preferred keyword as it aligns
   better with other classes, but :voices is retained for older code
   compatibility. 
 - :start-section. An integer that is the number of the first section for
   which the MIDI file is to be generated. Default = 1.
 - :num-sections. An integer that is the number of sections to produce MIDI
   data for in the MIDI file. If NIL, all sections will be written. 
   Default = NIL.
 - :from-sequence. An integer that is the number of the sequence within the
   specified section from which to start generating MIDI data. NB: This
   argument can only be used when the num-sections = 1. Default = 1.
 - :num-sequences. An integer that is the number of sequences for which MIDI
   data is to be generated in the resulting MIDI file, including the
   sequence specified in from-sequence. If NIL, all sequences will be
   written. NB: This argument can only be used when the num-sections = 1.
   Default = NIL.
 - :update-amplitudes. T or NIL to indicate whether events should have their
   amplitude slots updated to ensure that any dynamic marks that have been
   added (and therefore amplitude slots updated as a side-effect) reflect
   the subsequent events' amplitudes also. This will override any amplitude
   slots that have been changed other than by (setf (amplitude ...)) or
   (add-mark ... 'some-dynamic). Also, if T, then hairpins (cresc, dim) will
   result in increasing/decreasing amplitudes over their extent (but this
   will only work if the amplitude/dynamic of the hairpins' starting and
   ending events are correct, and in that case intervening events'
   amplitudes will be overwritten no matter how they've been set; also this
   won't handle cases where there's a hairpin end and a new hairpin
   beginning on the same event ). Default  = T
 - :force-velocity. Either: an integer between 0 and 127 (inclusive) that is
   the MIDI velocity value which will be given to all notes in the resulting
   MIDI file, or a function which takes an event object argument and
   returns a velocity from it (e.g. randomising the existing amplitude
   slightly). Default = NIL.
 - :auto-open. Whether to open the MIDI file once written. Currently only
    available on OSX with SBCL or CCL. Uses the default app for MIDI files,
    as if opened with 'open' in the terminal. Default = Value of
    (get-sc-config 'midi-play-auto-open).
 - :suffix. Add some text to the filename just before .mid?. Default = ""

RETURN VALUE

 Returns the path of the file written, as a string.

EXAMPLE

;;; An example with some typical values for the keyword arguments. ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (hn (french-horn :midi-channel 2))
                     (vc (cello :midi-channel 3))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1 1 1))
                   (2 (1 1 1 1 1 1 1))
                   (3 (1 1 1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                :pitch-seq-palette ((1 2 3))))
                            (2 ((((4 4) (q) e (s) s h))
                                :pitch-seq-palette ((1 2 3))))
                            (3 ((((4 4) e (s) s h (q)))
                                :pitch-seq-palette ((2 3 3))))
                            (4 ((((4 4) (s) s h (q) e))
                                :pitch-seq-palette ((3 1 2)))))
        :rthm-seq-map '((1 ((cl (1 2 1 2 1 2 1))
                            (hn (1 2 1 2 1 2 1))
                            (vc (1 2 1 2 1 2 1))))
                        (2 ((cl (3 4 3 4 3 4 3))
                            (hn (3 4 3 4 3 4 3))
                            (vc (3 4 3 4 3 4 3))))
                        (3 ((cl (1 2 1 2 1 2 1))
                            (hn (1 2 1 2 1 2 1))
                            (vc (1 2 1 2 1 2 1))))))))
  (midi-play mini 
             :midi-file "/tmp/md-test.mid"
             :voices '(cl vc)
             :start-section 2))

;;; An example that passes a (lambda) function to :force-velocity. Usually, by
;;; default, event amplitudes between 0.0 and 1.0 will map onto MIDI velocities
;;; of 0 to 127. Here we map them to velocities of 0 to 100 instead.
(midi-play +jitterbug+ :force-velocity
           #'(lambda (event)
               (floor (* (amplitude event) 100))))

SYNOPSIS

#+cm-2
(defmethod midi-play ((sc slippery-chicken)
                      &key 
                        ;; no subsection refs: use from-sequence instead
                        (start-section 1) 
                        ;; these voices are used to get the actual sequence
                        ;; orders i.e. each voice will be appended to <section>
                        ;; when calling get-data.
                        ;; if nil then all voices.
                        (voices nil)
                        ;; MDE Thu Oct 18 17:07:57 2018 -- players is a more
                        ;; appropriate keyword than voices but keep the latter
                        ;; for historical code and make the two equivalent
                        (players nil)
                        ;; add something to the filename just before .mid?
                        (suffix "")
                        (midi-file
                         (format nil "~a~a~a.mid"
                                 (get-sc-config 'default-dir)
                                 (filename-from-title (title sc))
                                 suffix))
                        (from-sequence 1)
                        (num-sequences nil)
                        ;; if nil we'll write all the sections
                        (num-sections nil)
                        ;; MDE Mon Jun 13 12:30:55 2016
                        (update-amplitudes t)
                        ;; MDE Tue Jun  4 19:06:11 2013
                        (auto-open (get-sc-config 'midi-play-auto-open))
                        ;; if this is a 7-bit number we'll use this for all
                        ;; notes  
                        (force-velocity nil))

slippery-chicken/next-event [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get the events from a specified player's part within a given
 slippery-chicken object one after the other (e.g. in a loop). This method
 must be called once with a bar number (or any other non-NIL value,
 whereupon we start at bar 1) first in order to reset the counter; doing
 this will return NIL. Once the counter has been reset, calling the method
 without a bar number will return the events in sequence.

ARGUMENTS

 - A slippery-chicken object.
 - A player ID.

OPTIONAL ARGUMENTS

 - T or NIL to indicate whether to return only events that consist of
   attacked notes (i.e., no ties or rests). T = return only events with
   attacked notes. Default = NIL.
 - T, NIL, or an integer to indicate the first bar from which events are to
   be retrieved. If T, the counter is reset to the first event of the
   player's part. This should be NIL after the first resetting call.
   Default = NIL
 - NIL or an integer to indicate the last bar from which events are to be
   retrieved. If NIL, all events will be retrieved from the starting point
   to the last event in the given slippery-chicken object. Default = NIL.
   NB This arg should be used in the second call to next-event.
   E.g.: (next-event sc player nil start-bar)
         (loop for ne = (next-event sc player nil nil end-bar)
               while ne
               etc...

RETURN VALUE

 An event object

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (hn (french-horn :midi-channel 2))
                     (vc (cello :midi-channel 3))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                :pitch-seq-palette ((1 2 3)))))
        :rthm-seq-map '((1 ((cl (1 1 1))
                            (hn (1 1 1))
                            (vc (1 1 1))))))))
  (next-event mini 'vc nil t)
  (loop for ne = (next-event mini 'vc)
     while ne
  collect (get-pitch-symbol ne)))

=> (E4 NIL F4 NIL G4 E4 NIL F4 NIL G4 E4 NIL F4 NIL G4)

SYNOPSIS

  (defmethod next-event ((sc slippery-chicken) player 
                         &optional
                         (attacked-notes-only nil)
                         ;; could be a number too, whereupon it's the bar
                         ;; number to start at  
                         (start-over nil)
                         (end-bar nil)) ; inclusive

slippery-chicken/note-count [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 May 20th 2022, Heidhausen

DESCRIPTION

 for statistical purposes, generate a list of the count of all the notes in
 the whole or part of a piece.

ARGUMENTS

 - the slippery-chicken object
 - the player: either a single symbol, a list of players, or if nil, all the
 players 

OPTIONAL ARGUMENTS

 - how to sort the result. Default = 'pitch meaning that the pitches will
 ascend irrespective of their counts. Anything else (e.g. nil) will print in
 the order of lowest to highest note count
 - the start bar number. Default = NIL = 1
 - the end bar number. Default = NIL = last bar
 - T or NIL to indicate sounding (nil) or written (t) pitches should be
 examined.  Default = NIL = sounding.

RETURN VALUE

 a list of (note count) pairs

SYNOPSIS

(defmethod note-count ((sc slippery-chicken) player
                       &optional (sort 'pitch) start-bar end-bar written)

slippery-chicken/num-bars [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return the number of bars in the piece.

ARGUMENTS

 - A slippery-chicken object.

RETURN VALUE

 An integer that is the number of bars.

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((fl (flute :midi-channel 1))
(tp (b-flat-trumpet :midi-channel 2))
(vn (violin :midi-channel 3))))
:set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
:set-map '((1 (1 1 1 1 1)))
:rthm-seq-palette '((1 ((((4 4) h q e s s))
:pitch-seq-palette ((1 2 3 4 5)))))
:rthm-seq-map '((1 ((fl (1 1 1 1 1))
(tp (1 1 1 1 1))
(vn (1 1 1 1 1))))))))
(num-bars mini))

=> 5

SYNOPSIS

(defmethod num-bars ((sc slippery-chicken))

slippery-chicken/num-notes [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Returns the number of attacked notes in a given slippery-chicken object;
 i.e., not including ties or rests.

ARGUMENTS

 - A slippery-chicken object.

RETURN VALUE

 An integer,

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((fl (flute :midi-channel 1))))
        :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1)))
        :rthm-seq-palette '((1 ((((4 4) - e e e e - - e e e e -)))))
        :rthm-seq-map '((1 ((fl (1))))))))
  (num-notes mini))

=> 8

SYNOPSIS

(defmethod num-notes ((sc slippery-chicken))

slippery-chicken/num-players [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Get the number of players in a slippery chicken object's ensemble object.

ARGUMENTS

 - A slippery chicken object

RETURN VALUE

 - An integer.

SYNOPSIS

(defmethod num-players ((sc slippery-chicken))

slippery-chicken/num-seqs [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return the number of sequences (which may contain multiple bars) in a
 specified section of a slippery-chicken object. 

 NB This will return the total number of seqs if there are sub-sections.

ARGUMENTS

 - A slippery-chicken object.
 - The ID of the section for which to return the number of sequences.

RETURN VALUE

 An integer.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax (alto-sax :midi-channel 1))))
        :set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
        :set-map '((1 (1 1 1 1))
                   (2 (1 1 1))
                   (3 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1 1))))
                        (2 ((sax (1 1 1))))
                        (3 ((sax (1 1 1 1 1))))))))
  (num-seqs mini 2))

=> 3

SYNOPSIS

(defmethod num-seqs ((sc slippery-chicken) section-ref)

slippery-chicken/player-ambitus [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 February 9th 2017

DESCRIPTION

 Find the highest and lowest events in the (given bars of the) piece,
 printing if requested.

ARGUMENTS

 - the slippery-chicken object
 - the player ID (generally symbol)

OPTIONAL ARGUMENTS

 keyword arguments:
 - :written. T or NIL to indicate if the written (as opposed to sounding)
   pitches of the events should be handled/returned/printed. Default = NIL =
   sounding pitches
 - :print. Whether to print results to the Lisp interpreter.
 - :start-bar. The bar number to start processing. Default = 1.
 - :start-bar. The bar number to stop processing (inclusive). Default = NIL =
   the last bar.
 - :attacked-only. Whether only to include attacked notes. Default = T.

RETURN VALUE

 two values: the lowest event and the highest event.

SYNOPSIS

(defmethod player-ambitus ((sc slippery-chicken) player &key written print
                                                          (start-bar 1) end-bar
                                                          (attacked-only t))

slippery-chicken/player-doubles [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 02-Apr-2012

DESCRIPTION

 Boolean test to check whether a specified player plays more than one
 instrument.

ARGUMENTS

 - A slippery-chicken object.
 - A player ID.

RETURN VALUE

 T if the player has more than one instrument, otherwise NIL>

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax ((alto-sax tenor-sax) :midi-channel 1))
                     (db (double-bass :midi-channel 2))))
        :instrument-change-map '((1 ((sax ((1 alto-sax) (3 tenor-sax)))))
                                 (2 ((sax ((2 alto-sax) (5 tenor-sax))))))
        :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
        :set-map '((1 (1 1 1 1 1))
                   (2 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))
                        (2 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))))))
  (player-doubles mini 'sax))

=> T

SYNOPSIS

(defmethod player-doubles ((sc slippery-chicken) player)

slippery-chicken/players [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Return a list of all player IDs from the given slippery-chicken object. 

ARGUMENTS

 - A slippery-chicken object.

RETURN VALUE

 A list of player IDs.

EXAMPLE

(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((cl (b-flat-clarinet :midi-channel 1))
                     (hn (french-horn :midi-channel 2))
                     (vc (cello :midi-channel 3))))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                :pitch-seq-palette ((1 2 3)))))
        :rthm-seq-map '((1 ((cl (1 1 1))
                            (hn (1 1 1))
                            (vc (1 1 1))))))))
  (players mini))

=> (CL HN VC)

SYNOPSIS

(defmethod players ((sc slippery-chicken))

slippery-chicken/players-ambitus [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 August 5th 2017

DESCRIPTION

 Call the player-ambitus method for each player in the slippery-chicken
 object. 

ARGUMENTS

 see player-ambitus method

RETURN VALUE

 the lowest and highest events of all the players

SYNOPSIS

(defmethod players-ambitus ((sc slippery-chicken)
                            &key written print (start-bar 1) end-bar)

slippery-chicken/quarter-duration [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 23rd August 2023

DESCRIPTION

 return the duration in quarter notes of a slippery-chicken piece

ARGUMENTS

 the slippery chicken object

OPTIONAL ARGUMENTS

 start-bar and end-bar, both integers or if nil will default to 1 and the
 number of bars in the piece 

RETURN VALUE

 a float: total number of quarters

SYNOPSIS

(defmethod quarter-duration ((sc slippery-chicken) &optional start-bar end-bar)

slippery-chicken/reaper-play [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Using the sound files (samples) defined for the given reference (group ID)
 in the sndfile-palette slot of the slippery-chicken object, write a reaper
 files using the pitch and timing information of one or more players' parts
 from the slippery-chicken object.

 See clm-play for details of these related methods.

 One significant difference between this and clm-play is that reaper offers
 the possibility of transposing sound files via playback rate (like clm) and
 by pitch shift. Set :do-src 'transposition for the latter.

ARGUMENTS

 - A slippery chicken object.
 - The ID of the starting section.
 - The IDs of the player(s) whose events are to be used to obtain the
   rhythmic structure (and optionally, pitch content) of the resulting sound
   file. This can be a single symbol for an individual player, a list of
   player IDs, or NIL. If NIL, the event from all players' parts will be
   reflected in the output file. Default = NIL.
 - The ID of the sound file group in the sndfile-palette slot of the
   slippery-chicken object that contains the source sound files from which
   the new sound file is to be generated.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :num-sections. An integer or NIL to indicate how many sections should be
   generated, including the starting section. If NIL, sound file data will
   be generated for all sections of the piece. NB If there are sub-sections
   this will include them in the total, i.e., if section 1 has 3 subsections
   and :num-sections is 2, we'll generate data from the first two
   subsections of section 1, not all subsections of main sections 1 and
   2. Default = NIL. 
 - :from-sequence. An integer that is the number of the first sequence
   within the specified starting section to be used to generate the output
   file. This argument can only be used when num-sections = 1. Default = 1. 
 - :num-sequences. NIL or an integer that indicates how many sequences are
   to be generated, including that specified by :from-sequence. If NIL, all
   sequences will be played. This argument can only be used when
   num-sections = 1 and the section has no subsections. Default = NIL.
 - :srate. A number that is the sampling rate of the reaper project file
   (independent of the input files). Default = 48000.
   lead time of a specified number of seconds of silence prior to the sound
   output. 
 - :inc-start. T or NIL to indicate whether playback of the source sound
   files is to begin at incrementally increasing positions in those files or
   at their respective 0.0 positions every time. If T, the method will
   increment the position in the source sound file from which playback is
   begun such that it reaches the end of the source sound file the last time
   it is 'played'. T = increment start times. Default = NIL.
 - :ignore-rests. T or NIL to indicate whether silence should be
   incorporated into the resulting sound file to correspond with rests in
   the player's parts. If T, the sound files will play over the duration of
   rests. However, this is only true on a bar-by-bar basis; i.e., notes at
   the end of one bar will not be continued over into a rest in the next
   bar. This implies that rests at the start of a bar will not be turned
   into sounding notes. T = ignore resets. Default = T.
 - :sound-file-palette-ref2. The ID of a sound file group in the given
   slippery-chicken object's sndfile-palette slot. If this reference is
   given, the method will invoke fibonacci-transitions to transition from
   the first specified group of source sound files to this one. If NIL, only
   one group of source sound files will be used. Default = NIL.
 - :do-src. T, NIL, 'transposition, a number, or a note-name pitch symbol to
   indicate whether transposition of the source sound files for playback will
   be calculated such that the perceived fundamental frequencies of those
   sound files are shifted to match the pitches of the current set or score
   note. If do-src is a number (frequency in Hertz) or a note-name pitch
   symbol, the method will use only that pitch instead of the sound files'
   frequencies when transposing to the events' pitches. If :do-src
   'transposition, then reaper's pitch-adjust will be used instead of
   playback rate (default). NB Whichever is used, after being converted to a
   sample rate conversion factor, this is always multiplied by the src-scaler
   (see below). T = match sound files' frequencies to set pitches or score
   pitches via playback rate (depending on :pitch-synchronous). NIL means no
   transposition will be performed. Default = T.
 - :pitch-synchronous: T or NIL to indicate whether the source sound files
   are to be transposed to match the pitches of the events in the given
   players' part. This will only be effective if the given source sound file
   has a perceptible frequency that has been specified using the sndfile
   object's :frequency slot in the sndfile-palette. :do-src must also be T
   for this to work. T = match pitches. Default = NIL.
 - :reset-snds-each-rs. T or NIL to indicate whether to begin with the first
   source sound file of the specified group at the beginning of each
   rthm-seq. T = begin with the first sound file. Default = T.
 - :reset-snds-each-player. T or NIL to indicate whether to begin with the
   first source sound file of the specified group for the beginning of each
   player's part. T = begin with the first sound file. Default = T. 
 - :play-chance-env. A list of break-point pairs that determines the chance
   that a given event from the source player's part will be reflected in the
   new sound file. It is determined by random selection but uses a fixed
   seed that is re-initialized each time reaper-play is called. The following
   default ensures every note will play: '(0 100 100 100).
 - :play-chance-env-exp. A number that will be applied as the exponent to
   the play-chance-env's y values to create an exponential interpolation
   between break-point pairs. Default = 0.5.
 - :max-start-time. A number that is the last time-point in seconds for
   which events will be processed for the output file. If a maximum start
   time is specified here (in seconds), events after this will be
   skipped. The default value of 99999999 seconds (27778 hours) will result
   in all events being reflected in the sound file.
 - :time-scaler. A number that will be the factor by which all start times
   are scaled for the output file (in effect a tempo scaler). If
   :ignore-rests is T, this will also have an indirect effect on
   durations. This argument should not be confused with
   :duration-scaler. Default = 1.0.
 - :duration-scaler. A number that is the factor by which the duration of
   all  events in the output sound file will be scaled. This does not alter
   start times, and will therefore result in overlapping sounds if greater
   than 1.0. This is not to be confused with :time-scaler. 
   Instead of a simple number, :duration-scaler can also be an envelope 
   (a list of break-point pairs). This means you could smoothly transition
   from staccato-like to overlapping sounds in a single reaper-play call.
   Default = 1.0.
 - :src-scaler: A number that is the factor by which all sample-rate
   conversion values will be scaled (for increasing or decreasing the
   transposition of the overall resulting sound file). 
   Instead of a simple number, :src-scaler can also be an envelope 
   (a list of break-point pairs), similar to :duration-scaler. Default = 1.0.
 - :note-number. A number that is an index, representing the the nth pitch
   of the current set or chord (from the bottom) to be used for the lowest
   player. Default = 0.
 - :duration-run-over. T or NIL to indicate whether the method will allow a
   sound file event to extend past the end of specified segment boundaries
   of a sound file in the sndfile-palette. T = allow. Default = NIL.
 - :short-file-names. T or NIL to indicate whether abbreviated output file
   names will be automatically created instead of the usually rather long
   names. T = short. Default = NIL.
 - :output-name-uniquifier. A user-specified string that will be
   incorporated into the file name, either at the end or the beginning
   depending on whether short-file-names is T or NIL. Default = "".
 - :check-overwrite. T or NIL to indicate whether to query the user before
   overwriting existing sound files. T = query. Default = T.
 - :sndfile-palette. NIL or a file name including path and extension that
   contains an external definition of a sndfile-palette. This will replace
   any sndfile-palette defined in the slippery-chicken object. If NIL, the
   one in the slippery-chicken object will be used. Default = NIL.
 - :chords. NIL or a list of lists consisting of note-name symbols to be
   used as the pitches for the resulting sound file in place of the pitches
   from the set-map. There must be one chord specified for each sequence. If
   NIL, the pitches from the set-map will be used. Default = NIL.
 - :chord-accessor. Sometimes the chord stored in the palette is not a
   simple list of data so we need to access the nth of the chord
   list. Default = NIL.
 - :pan-min-max. Each event is panned randomly between two channels. Pan
   values are in degrees where 0 is channel 1 (left in stereo files) and 90
   is channel 2 (right). The values used are chosen from the following list
   of degrees: (15 25 35 45 55 65 75). However, these can be scaled to be
   within new limits by passing a two-element list to
   :pan-mix-max. E.g. '(40 50) would limit most values to the middle area
   of stereo space. Note that no matter how many channels a sound file or
   channel has, the item's panner is set as if it were stereo. Also that,
   for convenience, :min-channels and :max-channels can set the tracks'
   channel count, it is up to the user to take care of routing and,
   eventuallay, panning depending on the number of sound file and track
   channels used in the mix. Default = '(5 85).
 - :pan-fun. If you want to take charge of selecting pan positions yourself,
   pass a function via this keyword. The function must take one argument: the
   current event, though of course, it can ignore it completely if
   preferred. The function should return a degree value: a number between 0
   and 90. Default = NIL.
 - :min-channels and :max-channels 4. Set the reaper tracks' minimum and
   maximum channel counts. See these named slots in the reaper-track class
   definition and the cond in create-tracks for details of how these are
   handled.
 - :snd-selector. By default the sound files in the given group are cycled
   through, one after the other, returning to the beginning when the end is
   reached. This can be changed by passing a function to :snd-selector. This
   function must take three arguments: the circular-sclist object that
   contains the group's sndfile objects (the sndfiles are in a simple list
   in the data slot); the pitch of the current event (if the event happens
   to be a chord, each pitch of the chord will be handled separately
   i.e. the :snd-selector function will be called for each pitch); and the
   event object. Of course any of these arguments may be ignored by the
   :snd-selector function; indeed it is imagined that the event object will
   be mostly ignored and the pitch object used instead, but it is
   nevertheless passed for completeness. For example, the following
   function, declared on-the-fly using lambda rather than separately with
   defun, makes reaper-play act as a traditional sampler would: Assuming our
   sndfile-palette group has a list of sound files whose frequencies really
   correspond to their perceived fundamentals (e.g. see the
   set-frequency-from-filename method, and the kontakt-to-sfp function) we
   choose the nearest sound file in the group to the frequency of the
   current event's pitch:

            :snd-selector #'(lambda (sflist pitch event)
                              (declare (ignore event))
                              (get-nearest-by-freq
                               (frequency pitch) (data sflist)))

   NB If :pitch-synchronous is NIL, then the pitch-or-chord slot of the event
   will be the pitch selected from the current set, rather than the actual
   pitch of the instrument in question.
   Default = NIL i.e. use the circular selection method.
 - :snd-transitions. Set the transition from sound-file-ref to sound-file-ref
   over the course of the call to reaper-play using a custom envelope instead
   of the default fibonacci-transitions method, e.g. '(0 0 100 1). x-axis is
   arbitrary, y-axis should range from 0 to 1. When reading, y-values will be
   rounded.
 - :file. reaper file name, if you don't want this to be auto-generated.
   Automatically generated file names will be placed in the default-dir as
   defined in the sc-config. A full path is expected. Default = NIL =
   automatic. 
 - :fade-in :fade-out. The fade times expressed as a percentage of the
   duration of any given event/item. Default = 10%
 - :tracks-per-player. How many reaper tracks to use per player. If > 1
   then the tracks will be used one after the other, in rotation, for each
   event. Particularly useful if there are lots of overlapping events due to
   e.g. :duration-scaler, or chords, of course. Default = 1.
 - :items-processor. A function to call to process the list of reaper-item
   objects just before writing the reaper file. This should take one
   argument, the list of reaper-items, and return a list of reaper-items that
   will be written to the file. Default = NIL = no processing.
 - :markers. Whether to write markers at sequenz and tempo changes. This
   should be a list of two booleans: whether to write sequenz and/or
   tempi. NB This only works (for now) if you're generating the whole
   piece. Default = '(t t) 

RETURN VALUE

 Total events generated (integer).

EXAMPLE

;;; using playback speed to effect the transpositions:
(reaper-play +second-law+ 1 nil 'source-sndfile-grp-1
             :check-overwrite nil :tracks-per-player 2
             :pitch-synchronous t)

;;; using reaper's pitch adjust and keeping playback speed implicitly to 1.0
(reaper-play +second-law+ 1 nil 'source-sndfile-grp-1
             :check-overwrite nil :tracks-per-player 2
             :pitch-synchronous t :do-src 'transposition)

SYNOPSIS

(defmethod reaper-play ((sc slippery-chicken) section players 
                        sound-file-palette-ref 
                        &key 
                        sound-file-palette-ref2
                        (play-chance-env '(0 100 100 100))
                        (max-start-time 99999999)
                        (play-chance-env-exp 0.5)
                        (time-scaler 1.0)
                        (from-sequence 1)
                        (num-sequences nil)
                        (num-sections nil)
                        (ignore-rests t)
                        (time-offset 0.0)
                        (chords nil)
                        (chord-accessor nil)
                        (note-number 0)
                        (fade-in 10)
                        (fade-out 10)
                        (inc-start nil)
                        ;; either a number or an envelope
                        (src-scaler 1.0)
                        (do-src t)
                        (pitch-synchronous nil)
                        ;; either a number or an envelope
                        (duration-scaler 1.0)
                        (short-file-names nil)
                        ;; by default we generate filenames according to players
                        ;; and other relevent data but if this is given then
                        ;; we'll use it instead 
                        (file nil)
                        (check-overwrite t)
                        (reset-snds-each-rs t)
                        (reset-snds-each-player t)
                        (duration-run-over nil)
                        (srate 48000)
                        (output-name-uniquifier "")
                        (sndfile-palette nil)
                        (tracks-per-player 1)
                        ;; MDE Sat Oct  3 18:45:28 2015 -- for Cameron!
                        pan-fun
                        ;; MDE Thu Oct  1 21:03:59 2015
                        (pan-min-max '(5 85))
                        ;; MDE Wed Feb 21 13:21:00 2024, Heidhausen
                        items-processor
                        ;; MDE Thu Feb 22 11:40:43 2024, Heidhausen
                        (markers '(t t))
                        ;; MDE Thu Oct  1 19:13:49 2015
                        snd-selector
                        (min-channels 2) (max-channels 4)
                        snd-transitions)

slippery-chicken/rebar [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Go through the vertically simultaneous sequences in all players of the
 given slippery-chicken object and rebar according to the first one that has
 the least number of bars (but following the player hierarchy).

 If rthm-seqs or sequenzes are created algorithmically and bundled into the
 slippery-chicken piece slot artificially, bypassing the usual generation
 structure, it might be difficult to end up with each instrument having the
 same metric structure when combined vertically. This method goes through
 the vertically combined sequences and rebars as described above.

 NB: See documentation in piece class method. Don't confuse this method with
     the re-bar method.

 NB: This method is used internally and not recommended for direct use. 

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 - A list of player IDs from the given slippery-chicken object, ordered in
   terms of importance i.e. which instrument's bar structure should take
   precedence.
 - NB: The rebar-fun is not yet used.

RETURN VALUE

 Always T.

SYNOPSIS

(defmethod rebar ((sc slippery-chicken) 
                  &optional instruments-hierarchy rebar-fun)

slippery-chicken/sc-init [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Explicitly initialize the slippery-chicken object. This is usually called
 implicitly by initialize-instance (i.e. when you call
 make-slippery-chicken) but there could be circumstances (e.g. in subclasses
 of slippery-chicken) where you'd like to defer initialization and call this
 method explicitly instead. In that case set :defer to t when making the
 slippery-chicken object. This can also be called with using :defer, to
 regenerate the piece after e.g. calling set-limits-by-section. 

ARGUMENTS

 - the slippery-chicken object

 OPTIONAL ARUGMENTS
 keyword arguments:
 - :regenerate-pitch-seq-map: the pitch-seq-map is generated here for each
 instrument using the pitch-seqs in the rthm-seq-palette. By setting this
 to T we can force regeneration (e.g. if the rthm-seq-palette has changed
 and we want to re-init the sc with different data). Default = T.

RETURN VALUE

 the now fully initialized slippery-chicken object

EXAMPLE

(let ((sc (make-slippery-chicken
           '+mini+
           :ensemble '(((vn (violin :midi-channel 1))))
           :set-palette '((1 ((gs4 af4 bf4))))
           :defer t
           :set-map '((1 (1 1 1)))
           :rthm-seq-palette '((1 ((((4 4) e e e e e e e e))
                                   :pitch-seq-palette ((1 2 1 1 1 1 1 1)))))
           :rthm-seq-map '((1 ((vn (1 1 1))))))))
  (sc-init sc))

SYNOPSIS

(defmethod sc-init ((sc slippery-chicken) &key (regenerate-pitch-seq-map t))

slippery-chicken/section-densities [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 January 12th 2019, Heidhausen

DESCRIPTION

 Calculate the densities of notes or rests in the sections of a
 slippery-chicken object. Density is the average number of notes/rests per
 bar across a section.

ARGUMENTS

 - a slippery-chicken object

OPTIONAL ARGUMENTS

 keyword arguments:
 - :slot. The section slot to use. 'num-score-notes is the default and makes
   sense in that ties indicate a higher level of density than just attacked
   notes by themselves, but further useful slots could be 'num-notes
   (attacks) or indeed 'num-rests
 - :percent. Whether to return values as percentages (where 0 would be the
   least dense section and 100 the most). If NIL the actual average notes per
   bar in each section would be returned. Default = T.

RETURN VALUE

 a list of density numbers, one per section/subsection.

SYNOPSIS

(defmethod section-densities ((sc slippery-chicken)
                              &key (slot 'num-score-notes) (percent t))

slippery-chicken/shorten-large-fast-leaps [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Modify the pitches of each part in a slippery-chicken object to avoid large
 melodic leaps at fast speeds, based on the largest-fast-leap slot of the
 given instrument object and the fast-leap-threshold slot of the
 slippery-chicken object. 

 This method is called automatically at init and as such will most likely
 seldom need to be directly accessed by the user.

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :threshold. A number that is the maximum duration in seconds between two
   consecutive notes in the slippery-chicken object for which linear
   intervals greater than the number specified in the given instrument
   object's largest-fast-leap slot will be allowed. This value is taken from
   the fast-leap-threshold slot of the given slippery-chicken object by
   default. 
 - :verbose. T or NIL to indicate whether to print feedback about the
   method's operations to the Lisp listener. T = print. Default = T.

RETURN VALUE

 Always T

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((vn (violin :midi-channel 1))))
:tempo-map '((1 (q 96)))
:set-palette '((1 ((g3 a5 b6))))
:set-map '((1 (1 1 1 1 1 1)))
:rthm-seq-palette '((1 ((((2 4) e s 32 64 64 e s 32 64 64))
:pitch-seq-palette ((1 5 1 5 1 5 1 5 1 5))))) 
:rthm-seq-map '((1 ((vn (1 1 1 1 1 1))))))))
(shorten-large-fast-leaps mini :threshold 0.25))

=>
******* section (1)
Getting notes for VN
Shortening short, fast leaps...
Shortened 23 large fast leaps
seq-num 0, VN, replacing B6 with G3
seq-num 0, VN, replacing B6 with G3
seq-num 0, VN, replacing B6 with G3
seq-num 0, VN, replacing B6 with G3
seq-num 0, VN, replacing G3 with B6
seq-num 0, VN, replacing G3 with B6
seq-num 0, VN, replacing G3 with B6
seq-num 1, VN, replacing G3 with B6
seq-num 1, VN, replacing B6 with G3
seq-num 1, VN, replacing B6 with G3
seq-num 1, VN, replacing B6 with G3
seq-num 1, VN, replacing B6 with G3
seq-num 1, VN, replacing G3 with B6
seq-num 1, VN, replacing G3 with B6
seq-num 1, VN, replacing G3 with B6
seq-num 2, VN, replacing G3 with B6
seq-num 2, VN, replacing B6 with G3
seq-num 2, VN, replacing B6 with G3
seq-num 2, VN, replacing B6 with G3
seq-num 2, VN, replacing B6 with G3
seq-num 2, VN, replacing G3 with B6
seq-num 2, VN, replacing G3 with B6
seq-num 2, VN, replacing G3 with B6
seq-num 3, VN, replacing G3 with B6
seq-num 3, VN, replacing B6 with G3
seq-num 3, VN, replacing B6 with G3
seq-num 3, VN, replacing B6 with G3
seq-num 3, VN, replacing B6 with G3
seq-num 3, VN, replacing G3 with B6
seq-num 3, VN, replacing G3 with B6
seq-num 3, VN, replacing G3 with B6
seq-num 4, VN, replacing G3 with B6
seq-num 4, VN, replacing B6 with G3
seq-num 4, VN, replacing B6 with G3
seq-num 4, VN, replacing B6 with G3
seq-num 4, VN, replacing B6 with G3
seq-num 4, VN, replacing G3 with B6
seq-num 4, VN, replacing G3 with B6
seq-num 4, VN, replacing G3 with B6
seq-num 5, VN, replacing G3 with B6
seq-num 5, VN, replacing B6 with G3
seq-num 5, VN, replacing B6 with G3
seq-num 5, VN, replacing B6 with G3
seq-num 5, VN, replacing B6 with G3
seq-num 5, VN, replacing G3 with B6
seq-num 5, VN, replacing G3 with B6
seq-num 5, VN, replacing G3 with B6

SYNOPSIS

(defmethod shorten-large-fast-leaps ((sc slippery-chicken) 
                                     &key threshold (verbose t))

slippery-chicken/statistics [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Print various information about the given slippery-chicken object to the
 Lisp listener or other specified stream.

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 - NIL or a stream to which the information should be printed. If NIL, the
   method will not print the information to any stream. T = print to the
   Lisp listener. Default = T.

RETURN VALUE

 A number of formatted statistics about the given slippery-chicken object. 

EXAMPLE

(let ((mini
(make-slippery-chicken
'+mini+
:ensemble '(((sax (alto-sax :midi-channel 1))))
:set-palette '((1 ((e3 fs3 b3 cs4 fs4 gs4 ds5 f5)))) 
:set-map '((1 (1 1 1))
(2 (1 1 1)))
:rthm-seq-palette '((1 ((((4 4) h q e s s))
:pitch-seq-palette ((1 2 3 4 5)))))
:rthm-seq-map '((1 ((sax (1 1 1))))
(2 ((sax (1 1 1))))))))
(statistics mini))

=>
+MINI+ 
"+MINI+-piece" 
start-bar: 1
end-bar: 6
num-bars: 6
start-time: 0.0
end-time: 24.0
start-time-qtrs: 0
end-time-qtrs: 24.0
num-notes (attacked notes, not tied): 30
num-score-notes (tied notes counted separately): 30 
num-rests: 0
duration-qtrs: 24.0 
duration: 24.0 (24.000)

SYNOPSIS

(defmethod statistics ((sc slippery-chicken) &optional (stream t))

slippery-chicken/transpose-events [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Transpose the pitches of event objects in a specified region and a
 specified player's part.

ARGUMENTS

 - A slippery-chicken object.
 - A player ID.
 - An integer that is the first bar in which to transpose events.
 - An integer that is the first event in that bar to transpose. 
 - An integer that is the last bar in which to transpose events.
 - An integer that is the last event in that bar to transpose.
 - A positive or negative number that is the number of semitones by which
   the pitches of the events in the specified region should be transposed. 

OPTIONAL ARGUMENTS

 keyword argument:
 - :destructively. T or NIL to indicate whether the pitches of the original
   event objects should be replaced. T = replace. Default = T.

RETURN VALUE

 Returns a list of events.

EXAMPLE

;;; Print the pitches before and after applying the method ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((sax (alto-sax :midi-channel 1))
                     (db (double-bass :midi-channel 2))))
        :set-palette '((1 ((c2 d2 g2 a2 e3 fs3 b3 cs4 fs4 gs4 ds5 f5 bf5)))) 
        :set-map '((1 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                :pitch-seq-palette ((1 2 3 4 5)))))
        :rthm-seq-map '((1 ((sax (1 1 1 1 1))
                            (db (1 1 1 1 1))))))))
  (print 
   (loop for e in (get-events-from-to mini 'sax 3 2 5 3)
      collect (get-pitch-symbol e)))
  (transpose-events mini 'sax 3 2 5 3 11)
  (print 
   (loop for e in (get-events-from-to mini 'sax 3 2 5 3)
      collect (get-pitch-symbol e))))

=>
(EF4 AF4 BF4 EF5 CS4 EF4 AF4 BF4 EF5 CS4 EF4 AF4) 
(D5 G5 A5 D6 C5 D5 G5 A5 D6 C5 D5 G5) 

SYNOPSIS

(defmethod transpose-events ((sc slippery-chicken) player start-bar
                             start-event end-bar end-event semitones
                             &key (destructively t))

slippery-chicken/update-instrument-slots [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 23rd August 2013

DESCRIPTION

 This will go through the generated slippery-chicken object's bar structure
 and update each players' instruments' total-bars, total-notes,
 total-duration, and total-degrees slots, for statistical purposes only.
 This might be called by the user after performing one of the editing
 routines that deletes or changes notes, etc.

ARGUMENTS

 - The slippery-chicken object.

RETURN VALUE

 T

SYNOPSIS

(defmethod update-instrument-slots ((sc slippery-chicken))

slippery-chicken/update-slots [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Called by initialize-instance and others. Updates timings of events and
 statistics. Not generally called by the user but can be useful if
 post-generation editing has changed something fundamental to the structure.

ARGUMENTS

 - A slippery-chicken object

OPTIONAL ARGUMENTS

 - A tempo-map object (not just as a list). If not given, then the tempo-map
   from the slippery-chicken object will be used. Default = NIL.
 - A number that is the start-time of the first event object in
   seconds. Default = 0.0.
 - A number that is the start-time of the first event, in 'quarters' (for
   MIDI timing). Default = 0.0.
 - A integer that is the number of the starting bar. Default = 1.
 - The reference of the current section (for internal recursive use in the
   bar-holder class). Default = NIL.
 - The nth sequence (for internal recursive use in the sequenz class).
   Default = NIL.
 - T or NIL to indicate whether to print a warning to the Lisp listener when
   ties are being used at the beginning of a sequence. This argument is now
   obsolete and ignored, but remains for some backward compatibility.
   Default = T.

RETURN VALUE

 The duration in seconds of the object; in this class: the whole generated
 piece.

EXAMPLE

;;; Create a slippery-chicken object and print the start time of one of its
;;; events; call update-slots with a start time of 10.0 and print the start
;;; time of that same event to see the difference
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((vn (violin :midi-channel 1))))
        :tempo-map '((1 (q 60)))
        :set-palette '((1 ((c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((2 4) (s) (s) e e e))
                                :pitch-seq-palette ((1 2 3)))))
        :rthm-seq-map '((1 ((vn (1 1 1 1 1))))))))
  (print (start-time (get-event mini 4 1 'vn)))
  (update-slots mini nil 10.0)
  (print (start-time (get-event mini 4 1 'vn))))

=
6.0 
16.0

SYNOPSIS

(defmethod update-slots ((sc slippery-chicken) 
                         &optional
                         (tempo-map nil)
                         (start-time 0.0)
                         (start-time-qtrs 0.0)
                         (start-bar 1)
                         (current-section nil)
                         (nth nil)
                         (warn-ties t)
                         (update-write-bar-nums nil))

slippery-chicken/write-antescofo [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Write an antescofo~ (Arshia Cont's/IRCAM's score follower MaxMSP external)
 score file. This allows you to specify a single player to follow (for now:
 no polyphonic following) and which players' events you'd like to be
 triggered along with this, in the form of MIDI notes (sent via antescofo's
 group action commands). Of course this doesn't imply that you have to use
 MIDI with antescofo, rather, that you have something that picks up midi
 note data and uses them (or ignores them) somehow or other. In any case,
 the MIDI notes sent consist of four messages: the MIDI note (in midi cents
 e.g. middle C = 6000), the velocity (taken as usual from the amplitude slot
 of the event), the channel, and the duration in beats. Each may be preceded
 by a delay, which will be relative to the previous NOTE or group MIDI note.

 Rehearsal letters already in the slippery-chicken piece will automatically
 be written into the antescofo~ file as labels/cues. E.g. if you have
 rehearsal letter A, it will show up in the antescofo~ file as "letter-A".
 Further labels/cues can be added to any slippery-chicken events and these
 will also be written into the antescofo~ file.

 Action messages can also be added to events and thus written into the
 antescofo~ file. You can push as many messages as you want into this list;
 they'll be reversed before writing out so that they occur in the order in
 which you added them. If you prefer you can call the event method
 add-antescofo-message. NB For the part we're following, we can add messages
 to rests but if it turns out we added messages to rests in other players'
 (i.e. group event parts) these won't be written to the antescofo~ file.

 Do remember to set the instruments-hierarchy slot of the slippery-chicken
 object so that the player you're going to follow is top of the list,
 otherwise some strange event ordering might occur in the antescofo~ file.
 
 Bear in mind that if you want to write antescofo~ files without having to
 work within the usual slippery chicken workflow, you could generate events
 by any method, then put them into rthm-seq-bar objects before then calling
 bars-to-sc in order to create a slippery-chicken object by brute force (as
 it were).
 
 A note about grace notes: For the voice we're following, antescofo~
 considers that grace notes are 'out of time' so have a duration of 0. But
 for group notes, which we're triggering, they have to have some duration;
 we default to the grace-note-duration of the event class (0.05 seconds by
 default, which will be written as a fraction of the beat at the current
 tempo, of course). Now this means our grace notes are not 'stealing' time
 from the previous note, as they do in performed music. This is not ideal,
 but if we've got a long group of grace notes, doing that might mean we end
 up with a negative duration for the previous note. So we simply make the
 grace notes short and allow/hope that the score follower catches up for us
 on the next recognised note.

ARGUMENTS

 - The slippery-chicken object
 - the player who we'll follow (single player for now, as a symbol)

OPTIONAL ARGUMENTS

 keyword arguments:
 - :group-players (list of symbols). The players for whom midi-note events
   will be written in the antescofo file as part of a "group" action. If
   NIL, then we'll write all players' events except for the player we're
   following. NB There's no reason why we couldn't include the player we're
   following in these group commands (for unison playing between live and
   digital instruments perhaps). The easist way to write group events for
   all players is to write something like 
   :group-players (players +your-sc-object+)
   Default = NIL.
 - :bar-num-receiver. The MaxMSP receiver name to which bar numbers will be
   sent for display other other purposes. Default = "antescofo-bar-num"
 - :midi-note-receiver. The MaxMSP receiver name to which midi notes will be
   sent. Default = "midi-note", so a typical group output event could be 
   0.0 midi-note 6500 12 4 0.6666667
 - :file. The name of the file to write. If NIL, then the file name will be
   created from the slippery-chicken title and placed in (get-sc-config
   'default-dir). Default = NIL. 
 - :group-duration-in-millisecs. Should we write the group notes (i.e. those
    we generate) as fractions of a beat (NIL) or have antescofo~ convert
    this to millisec duration according to the current tempo (T)? Default =
    NIL.
 - :warn. Issue a warning when we write labels on group (rather than NOTE)
    events?  (Because labels attached to group event notes can be written
    and read, but they won't show up in MaxMSP as cues which you can jump
    to.)  Default = T.
 - :messages-first. Write antescofo messages immediately before the note
    data sent to the midi-note-receiver (T), or after (NIL)? Default = NIL.
 - :round-tempi. Round tempo values to the nearest integer? (If you don't do
    this, then MIDI playback could become out of synch with
    antescofo). Default = T. 
 - :include-program-changes. If T, we write any programme changes attached
    to an event as "midi-program-change <programme> <channel>". If this is a
    symbol or string then that ID will be used instead of
    "midi-program-change". (Symbols will be made lowercase.) Default = T.
 - :makenote-compatible. If T, we'll write midi note information in the
    following order: midi note (rounded to nearest chromatic note i.e. no
    longer midi-cents), velocity, duration, channel. Default = NIL.

RETURN VALUE

 The number of NOTE plus action events we've written. We also print to the
 terminal the number of events and actions separately, which should
 then correspond to what Antescofo~ prints when it loads the score in MaxMSP.

EXAMPLE

;;; Follow the violin part and generate group events for all other parts ;
(let* ((mini
        (make-slippery-chicken
         '+mini+
         :title "antescofo test"
         :ensemble '(((vn (violin :midi-channel 1))
                      (va (viola :midi-channel 2))
                      (vc (cello :midi-channel 3))))
         :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
         :set-map '((1 (1 1 1)))
         :tempo-map '((1 60))
         :rthm-seq-palette '((1 ((((4 4) { 3 tq tq tq } +q e (s) s)))))
         :rthm-seq-map '((1 ((vn (1 1 1))
                             (va (1 1 1))
                             (vc (1 1 1))))))))
  ;; Adding a label (probably wouldn't need one in bar 1, but to illustrate) 
  (setf (asco-label (get-event mini 1 1 'vn)) "test-label")
  ;; start the (fictitious) vocoder when the first cello note in bar 2 is played 
  (push "max-receiver1 start-vocoder" (asco-msgs (get-event mini 2 1 'vc)))
  (write-antescofo mini 'vn :file "/tmp/asco-test.txt"))

-->
******* section (1)
Getting notes for VN
Getting notes for VA
Getting notes for VC
Shortening short, fast leaps...
Shortened 0 large fast leaps
"/tmp/asco-test.txt" 
Antescofo~ score written successfully with 15 events and 34 actions.
49

The generated file will begin something like this:

; antescofo~ score generated by slippery chicken version ;
; 1.0.4 (svn revision 4733 2014-01-15 11:27:10) ;
; at 12:02:06 on Thursday the 8th of May 2014 ;
BPM 60
antescofo-bar-num 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
NOTE 6200 0.6666667 test-label
group bar1.1 {
0.0 midi-note 6000 12 2 0.6666667 
0.0 midi-note 6400 12 3 0.6666667 
}
NOTE 6200 0.6666667 
group bar1.2 {
0.0 midi-note 6000 12 2 0.6666667 
0.0 midi-note 6400 12 3 0.6666667 
}
NOTE 6200 1.6666667 
group bar1.3 {
0.0 midi-note 6000 12 2 1.6666667 
0.0 midi-note 6400 12 3 1.6666667 
}
NOTE 6200 0.5 
group bar1.4 {
0.0 midi-note 6000 12 2 0.5 
0.0 midi-note 6400 12 3 0.5 
}
NOTE 0 0.25 
NOTE 6200 0.25 
group bar1.5 {
0.0 midi-note 6000 12 2 0.25 
0.0 midi-note 6400 12 3 0.25 
antescofo-bar-num 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
}
NOTE 6200 0.6666667 
group bar2.1 {
0.0 midi-note 6000 12 2 0.6666667 
0.0 midi-note 6400 12 3 0.6666667 
max-receiver1 start-vocoder
}
NOTE 6200 0.6666667 
...

SYNOPSIS

(defmethod write-antescofo ((sc slippery-chicken) follow-player
                            &key group-players file (warn t)
                              (group-duration-in-millisecs nil)
                              messages-first
                              ;; could be T, a string, or a symbol
                              ;; todo: include control changes also?
                              (include-program-changes t)
                              (round-tempi t)
                              makenote-compatible
                              (midi-note-receiver "midi-note")
                              (bar-num-receiver "antescofo-bar-num"))

slippery-chicken/write-csound-score [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

AUTHOR

 Ruben Philipp <ruben.philipp@folkwang-uni.de>

DATE

 2023-02-28, Essen

DESCRIPTION

 Generate a Csound-score file (.sco) from the data of the specified
 slippery-chicken object. 

ARGUMENTS

 - A slippery-chicken object.
 - The ID(s) of the player(s) whose events are used to obtain the
   rhythmic structure of the score events (i.e. the onset and duration
   values) and, dependent on the p-fields function, pitch content,
   amplitude etc. This must be a list with one or more symbols.
 - The ID(s) (number) or name(s) (string) of the Csound instruments
   according to the resp. instrument definition in the Csound orchestra.
   Each player of the second argument of this methods needs to be assigned
   one Csound instrument. This must be a list with one or more values.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :suffix. A string to be added just before the .sco of the generated
   csound score-file. Will be overridden when manually setting the path
   via :csound-file. Default = "".
 - :csound-file. A string indicating the path and filename to the .sco-file
   to be generated with this method. Default is a filename extracted from the
   title of the sc piece, placed in the (get-sc-config 'default-dir)
   directory (per default /tmp).
 - :start-section. An integer that is the number of the first section for
   which the Csound-score is to be generated. Default = 1.
 - :num-sections. An integer that is the number of sections to generate the
   score data. If NIL, all sections will be written. Default = NIL.
 - :from-sequence.  An integer that is the number of the first sequence
   within the specified starting section to be used to generate the output
   file. Default = 1.
 - :num-sequences. An integer that s the number of sequences for which
   event data is to be generated in the resulting .sco-file, including the
   sequence spiecified in from-sequence. If NIL, all sequences will be
   written. NB: This argument can only be used when the num-sections = 1.
   Default = NIL.
 - :chords. Either a boolean or an integer which determines how to deal with
   chords in events. When T, all notes of a chord are parsed as
   i-statements in the Csound-score. When NIL, chords will be ignored and
   treated like rests (i.e. nothing will be generated). When an integer is
   given, the number determines the max. amount of pitches being parsed as i-
   statements. They are chosen chronologically from the given chord.
   Default = T.
 - :offset. An integer or floating point value to indicate the global
   offset of all score events (in seconds). Default = 0.
 - :delimiter. A character which separates each score statement. Csound
   recommends using spaces, though #\tab does also work an might, in some
   cases, improve legibility. Default = #\space.
 - :p-fields. This should be either NIL, a list of lists or a function used
   to generate the p-fields starting from p4. The lists can be of arbitrary
   length and are solely limited by Csound's internal parsing restrictions.
   When NIL, no additional p-statements are added to any of the score-
   statements, regardless of the amount of included players (i.e. no further
   p-field is added to any of the players).
   When given a list of lists, each sublist contains a set of constant
   p-values for each player. NB: It is mandatory to pass a sub-list for
   each player chosen for score generation (cf. second argument). It is
   possible to pass an empty list (i.e. NIL) for a single player, if it is
   desired not to add any further p-fields other than instrument-name (p1),
   onset (p2), and duration (p3).
   When a function is given as argument, it will be used to generate the
   p-values based on the event-data and other arguments. This enables dynamic
   generation of score content dependent on the data contained in the
   specific event used for generating the i-statement (e.g. pitch or
   amplitude). The pfield-function needs to accept the following arguments:
   - event.         A sc event.
   - event-num.     An integer counting the event index of each player.
   - cs-instrument. The csound-instrument name as defined in the third
                    argument (see above). This comes in handy when the
                    csound instruments require different sets of p-values.
   NB: When chords should be able to be processed (see above), the function
       needs to be able to process events containing chords and return a list
       of the length of the chord (e.g. via is-chord).
       For further detail, take a look at csound-p-fields-simple.
 - :comments. A boolean indicating whether additional comments should be
   included into the generated score. The comments include the title,
   composer and generation date of the sc piece resp. the csound-score.
   Additionally, the score sections containing the instrument calls for
   each player will be preceded with a reference to the player ID
   according to the sc ensemble. Default = T.

RETURN VALUE

 Returns the path of the file written, as a string.

EXAMPLE

;;; An example using the csound-p-fields-simple function
(let ((mini
        (make-slippery-chicken
         '+mini+
         :ensemble '(((pno (piano :midi-channel 1))
                      (vln (violin :midi-channel 2))))
         :set-palette '((1 ((f3 g3 as3 a3 bf3 b3 c4 d4 e4 f4 g4 a4 bf4 cs5))))
         :set-map '((1 (1 1 1 1 1 1 1))
                    (2 (1 1 1 1 1 1 1))
                    (3 (1 1 1 1 1 1 1)))
         :tempo-map '((1 (q 60)))
         :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                 :pitch-seq-palette ((1 (2) 3))))
                             (2 ((((4 4) (q) e (s) s h))
                                 :pitch-seq-palette ((1 2 3))))
                             (3 ((((4 4) e (s) s h (q)))
                                 :pitch-seq-palette ((2 3 3))))
                             (4 ((((4 4) (s) s h (q) e))
                                 :pitch-seq-palette ((3 1 (2))))))
         :rthm-seq-map '((1 ((pno (1 2 1 2 1 2 1))
                             (vln (1 2 1 2 1 2 1))))
                         (2 ((pno (3 4 3 4 3 4 3))
                             (vln (3 4 3 4 3 4 3))))
                         (3 ((pno (1 2 1 2 1 2 1))
                             (vln (1 2 1 2 1 2 1))))))))
  (write-csound-score mini
               '(pno vln)
               '(1 "fmsynth")
               :chords 1
               :delimiter #\tab
               :comments t))

;;; An example that creates different sets of p-field for each
;;; individual player.
;;; - Player 'vln calls the (hypothetical) Csound instrument 1
;;;   which generates tone of frequency p4 and amplitude p5.
;;;   Here, the standard csound-p-fields-simple function is invoked.
;;; - Player 'vlc calls the Csound instrument 2, which is a simple
;;;   sampler capable of playing one out of ten pre-loaded soundfiles.
;;;   These are identified by an index (1 <= i <= 10) which is expected
;;;   to be p4. p5 determines the amplitude of the playback.
;;;   In this examples, the samples will be selected cyclically, while
;;;   each event of the player is allocated one of the ten samples.
;;;   As there is one soundfile per events, chords will be treated as
;;;   pitches, i.e. every chord results in a list instead of a list of
;;;   lists of p-fields.
(defun csound-p-fields-custom (event event-num cs-instrument)
  ;; generate different p-field sets depending on the
  ;; given Csound instrument-number
  (format t "~%ins: ~a; enum: ~a~%"
          cs-instrument
          event-num)
  (case cs-instrument
    (1 (csound-p-fields-simple event
                               event-num
                               cs-instrument))
    (2 (let* ((amplitude (get-amplitude event))
              ;; num of available samples in Csound
              ;; instrument definition / orchestra
              (num-samples 10)
              ;; get the id of the sample to be played
              ;; for this event
              (current-sample (1+ (mod (1- event-num)
                                       num-samples))))
         (list current-sample
               amplitude)))))

(let* ((mini
         (make-slippery-chicken
          '+mini+
          :ensemble '(((vln (violin :midi-channel 1))
                     (vlc (cello :midi-channel 2))))
          :tempo-map '((1 (q 60)))
          :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5)))
                         (2 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5)))
                         (3 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
          :set-map '((1 (1 1 1 1 1))
                     (2 (2 2 2 2 2))
                     (3 (3 3 3 3 3)))
          :rthm-seq-palette '((1 ((((4 4) h q e s s))
                                  :pitch-seq-palette ((1 2 3 4 5))))
                              (2 ((((4 4) q e s s h))
                                  :pitch-seq-palette ((1 2 3 4 5))))
                              (3 ((((4 4) e s s h q))
                                  :pitch-seq-palette ((1 2 3 4 5)))))
          :rthm-seq-map '((1 ((vln (1 3 2 1 2))
                              (vlc (3 1 1 2 2))))
                          (2 ((vln (3 1 1 2 2))
                              (vlc (1 3 1 2 2))))
                          (3 ((vln (1 1 3 2 2))
                              (vlc (2 1 1 2 3))))))))
  (write-csound-score mini
               '(vln vlc)
               '(1 2)
               :chords nil
               :delimiter #\tab
               :p-fields #'csound-p-fields-custom
               :comments t))

SYNOPSIS

(defmethod write-csound-score ((sc slippery-chicken)
                               players
                               csound-instruments
                               &key
                                 (start-section 1)
                               ;; offset in seconds
                                 (offset 0)
                               ;; add something just before .sco?
                                 (suffix "")
                                 (csound-file
                                  (format nil "~a~a~a.sco"
                                          (get-sc-config 'default-dir)
                                          (filename-from-title (title sc))
                                          suffix))
                               ;; add a comment sections?
                                 (comments t)
                                 (delimiter #\space)
                                 (from-sequence 1)
                                 (num-sequences nil)
                                 (chords t)
                               ;; either NIL, a list of lists, or a function
                               ;; cf. documentation
                                 (p-fields #'csound-p-fields-simple)
                               ;; when NIL, all sections are considered
                                 (num-sections nil))

slippery-chicken/write-lp-data-for-all [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DESCRIPTION

 Generate all of the .ly files required by the LilyPond application for
 printable output from the musical data stored in the given slippery-chicken
 object.

 This method produces .ly files for the score as well as the parts for all
 individual players in the ensemble (unless otherwise specified by the
 user). The files are automatically named based on the value passed to the
 TITLE slot of the given slippery-chicken object.
 
 NB: This method only produces the .ly files. These must be rendered by the
     LilyPond application separately for PDF output. See the slippery
     chicken installation web page and the manual page on Output for more
     detail. Bear in mind that SBCL and CCL users on OSX can use the
     lp-display macro to call Lilypond and display the resultant PDF
     automatically.

 NB: Many of the arguments for this method pass their values directly to
     LilyPond parameters. 

 NB: Clefs added to grace-note events will not be rendered in Lilypond.

ARGUMENTS

 - A slippery-chicken object.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :base-path. A string that is the directory path only for the resulting
   files. The method will automatically generate the file names and
   extensions. Default =  (get-sc-config 'default-dir).
 - :start-bar. An integer that is the first bar of the given
   slippery-chicken object for which output is to be generated. If NIL, the
   start-bar will be set to 1. Default = NIL.
 - :end-bar. An integer that is the last bar of the given slippery-chicken
   object for which output is to be generated. If NIL, all bars after the
   start bar will be generated. Default = NIL.
 - :start-bar-numbering: For bar counting in the score only: the bar number
   that the :start-bar will be counted as (integer). NIL = :start-bar. 
   Default =  NIL. 
 - :players. A list of player IDs or NIL to indicate which players' parts
   are to be generated and included in the resulting score. If NIL, all
   players' parts will be generated and included in the score. This can be
   handy, for example, for excluding the computer part of a piece for tape
   and instruments. Default = NIL.
 - :respell-notes. NIL, T or a list to indicate whether the method should
   also call the respell-notes method on the given slippery-chicken object
   before generating the output to undertake enharmonic changes. If a list,
   then these are the specific enharmonic corrections to be undertaken. If
   this is T, the method will process all pitches for potential
   respelling. If NIL, no respelling will be undertaken. See the
   documentation for the respell-notes method for more. Default = NIL.
 - :auto-clefs. T or NIL to indicate whether the auto-clefs method should be
   called to automatically place mid-measure clefs in the parts of
   instruments that use more than one clef. T = automatically place clefs.
   Default = T
 - :in-c. T or NIL to indicate whether the full score is to contain written
   pitches or sounding pitches. NB: Some transposing C instruments still
   transpose at the octave in C scores, such as double-bass and piccolo.
   NB: Parts will always be transposed. T = sounding pitches. Default = NIL.
 - :page-nums. T or NIL to indicate whether page numbers should
   automatically be added to each page (not including the start page) of the
   output. T = add page numbers. Default = T.
 - :rehearsal-letters-font-size. A number that indicates the font size of
   rehearsal letters in LilyPond output. Default = 18.
 - :rehearsal-letters-all-players. T or NIL to indicate whether rehearsal
   letters are to be placed in all parts generated. T = all parts. 
   Default = T. NB: This must be set to T when the user would like the
   rehearsal letters in all individual LilyPond parts, but printing with CMN
   thereafter will result in rehearsal letters in all parts as well.
 - :tempi-all-players. T or NIL to indicate whether tempo marks are to be
   placed in all parts generated. T = all parts. Default = T.
 - :all-bar-nums. T o NIL to indicate whether the corresponding bar number
   should be printed above every measure in the score (not including
   multi-bar rests). T = add a bar number to every measure. Default = NIL. 
 - :paper. A string to indicate the paper size for LilyPond output. Only
   LilyPond's predefined paper sizes are valid here. According to the
   LilyPond manual, these include: "a4, letter, legal, and 11x17... Many
   more paper sizes are supported... For details, see scm/paper.scm, and
   search for the definition of paper-alist." NB: This argument will only
   adjust paper size, but not margins or line widths, which are adjusted
   using the arguments below. Default = "a4"
 - :staff-size. An integer that indicates the size of the notes and staves
   in the resulting output. Standard for parts is 20. Default = 14.
 - :group-barlines. T or NIL to indicate whether bar lines should be drawn
   through the whole staff group or just one staff. T = through the whole
   staff group. Default = T.
 - :landscape. T or NIL to indicate whether the paper format should be
   landscape or portrait. T = landscape. NB: This argument will only adjust
   paper layout, but not margins or line widths, which are adjusted using
   the arguments below. Default = NIL.
 - :barline-thickness. A number that is the relative thickness of the bar
   lines. Default = 0.5.
 - :top-margin. A number that is the margin at the top of the page in
   millimeters. Default = 10.
 - :bottom-margin. A number that is the margin at the bottom of the page in
   millimeters. Default = 10.
 - :left-margin. A number that is the margin at the left of the page in
   millimeters. Default = 20.
 - :line-width. A number that is the width of each line in centimeters.
   Default = 17.
 - :page-turns. T or NIL to indicate if LilyPond should attempt to optimize
   page breaks for page turns in parts. T = optimize page breaks. 
   Default = NIL.
 - :min-page-turn. A two-item list indicating the minimum rest necessary for
   the method to automatically place a page turn, in a format similar to
   that of a time signature; i.e., '(2 1) would mean a minimum of 2 whole
   rests. Default = '(2 1))
 - :use-custom-markup. T or NIL. Set to T when using a number of marks that
   are specific to LilyPond, such as 'bartok or any of the marks that use
   eps graphics files (whereupon those graphics files would need to be in
   the same folder as your lilypond files). Default = T.
 - :lp-version. A string that will be added to each .ly file generated in
   conjunction with the LilyPond \version command. Default = "2.42.1". NB
   Lilypond syntax changes every now and then. If you get errors that can't
   be explained by a user error, please post an issue on GitHub, as it might
   be that we need to update the generated code to reflect Lilypond's new
   syntax.
 - :process-event-fun. NIL or a user-defined function that will be applied
   to every event object in the given slippery-chicken object. If NIL, no
   processes will be applied. Default = NIL.
 - :extend-hairpins. If you want hairpin (cresc/dim) to extend beyond the
    previous barline (or beyond the note) set to T. Default = NIL.
 - :min-hairpin. If you're getting Lilypond warnings about hairpins being too
   short (and then not showing up in the score, or dynamics overlapping), you
   can set this value to, e.g. 10.
 - :stemlet-length. NIL or a decimal number < 1.0 that indicates the scaled
   length of stems over rests in LilyPond output, should this feature be
   desired. 0.75 is a recommended value for this. NIL = no stems over
   rests. Default = NIL. NB: LilyPond can be instructed to extend beams over
   rests (without stemlets) simply by using the '-' in the definition of the
   rthm-seq-bar object, as is done with any other note; however,
   starting/ending a beam on a rest and then trying to generate a score with
   CMN will fail.
 - :footer. A string to add to the footer of every score page. Default = NIL.
 - :title. Usually T or NIL to include the title of the piece at the top of
   the score or not, but could also be a string to specify a new
   title. Default = T.
 - :indent. T or NIL to indicate whether the first system in the score
   should be indented or not. Default = T.
 - :force-bracket. T or NIL to indicate whether tuplet numbers on beams
   should be forced into a bracket. Default = NIL.
 - :two-sided. A two-element list to set the inner and outer margins with
   layout for two-sided printing and binding. E.g. :two-sided '(30 20) means
   the left-hand margin will be 30mm and the right-hand will be 20mm. If
   set, this overrides the :left-margin and :line-width arguments. 
   Default = NIL.
 - :dummy-staves. The player name(s) as a symbol or a list for any parts
   that have been created merely as empty staves to add cross-staff
   notation.
 - :between-system-space. The space in cm between systems (groups of
   staves). Default = NIL (= Lilypond's default distance).
 - :staff-basic-distance. This controls the distance
   between staffs within a system. It's in Lilypond units (relative to
   staff size). Setting to 15 creates a good distance between piano
   staves. Default = NIL (= Lilypond's default distance).
 - :fixed-width. Set to a rhythmic value (e.g. 1/32) in order to create
   fixed width rhythmic spacing. This makes it easier, for some, to read
   complex rhythms as you can see how long rhythms last by the horizontal
   space they occupy. The shorter the value given the more space is
   allocated, so experimentation might be necessary. Default = NIL (usual
   engraver's spacing algorithm used, according to context).
 - :accidental-style. String. See the lilypond documentation for details of
   applicable styles and their results. Default = 'modern.
 - :links. T or NIL to indicate whether the generated PDF should contain
   notes that are clickable links to the lilypond source code or not. Default
   = T. 

RETURN VALUE

 The path of the main score file generated.

EXAMPLE

;;; An example with values for the most frequently used arguments ;
(let ((mini
       (make-slippery-chicken
        '+mini+
        :ensemble '(((fl (flute :midi-channel 1))
                     (cl (b-flat-clarinet :midi-channel 2))
                     (vc (cello :midi-channel 3))))
        :staff-groupings '(2 1)
        :tempo-map '((1 (q 84)) (9 (q 72)))
        :set-palette '((1 ((f3 g3 a3 b3 c4 d4 e4 f4 g4 a4 b4 c5))))
        :set-map '((1 (1 1 1 1 1 1 1 1))
                   (2 (1 1 1 1 1 1 1 1))
                   (3 (1 1 1 1 1 1 1 1)))
        :rthm-seq-palette '((1 ((((4 4) h (q) e (s) s))
                                :pitch-seq-palette ((1 2 3))
                                :marks (bartok 1)))
                            (2 ((((4 4) (q) e (s) s h))
                                :pitch-seq-palette ((1 2 3)))))
        :rthm-seq-map '((1 ((fl (1 2 1 2 1 2 1 2))
                            (cl (1 2 1 2 1 2 1 2))
                            (vc (1 2 1 2 1 2 1 2))))
                        (2 ((fl (1 2 1 2 1 2 1 2))
                            (cl (1 2 1 2 1 2 1 2))
                            (vc (1 2 1 2 1 2 1 2))))
                        (3 ((fl (1 2 1 2 1 2 1 2))
                            (cl (1 2 1 2 1 2 1 2))
                            (vc (1 2 1 2 1 2 1 2)))))
        :rehearsal-letters '(3 11 19))))
  (write-lp-data-for-all mini 
                         :start-bar 7
                         :end-bar 23
                         :paper "letter"
                         :landscape t
                         :respell-notes nil
                         :auto-clefs nil
                         :staff-size 17
                         :in-c nil
                         :barline-thickness 3.7
                         :top-margin 40
                         :bottom-margin 60
                         :left-margin 40
                         :line-width 22
                         :page-nums t
                         :all-bar-nums t
                         :use-custom-markup t
                         :rehearsal-letters-font-size 24
                         :lp-version "2.20.0"
                         :group-barlines nil
                         :page-turns t
                         :players '(fl cl)
                         :tempi-all-players t))

=> T

SYNOPSIS

(defmethod write-lp-data-for-all
    ((sc slippery-chicken) 
     &key
       (base-path (get-sc-config 'default-dir))
       start-bar end-bar (paper "a4") landscape
       ;; MDE Tue May 29 21:34:53 2012 
       start-bar-numbering
       ;; if a list, then these are the enharmonic corrections
       (respell-notes t) 
       ;; automatically add clefs to instruments who read more than one?
       (auto-clefs t)
       (staff-size 14)
       ;; parts will always be transposed but score can be in in C or not
       (in-c nil)
       (barline-thickness 0.5)
       (top-margin 10)                  ; mm
       (bottom-margin 10)               ; mm
       (left-margin 20)                 ; mm
       (line-width 17)                  ; cm
       ;; if not nil, then in cm
       between-system-space
       ;; MDE Tue May  3 12:12:46 2016 -- this one controls the distance
       ;; between staffs within a system. It's in Lilypond units (relative to
       ;; staff size). Setting to 15 creates a good distance between piano
       ;; staves. 
       staff-basic-distance
       (page-nums t)
       ;; print every bar number unless
       ;; multi-bar-rest?
       (all-bar-nums nil)
       ;; this has to be T if we're going to get letters in the parts--but CMN
       ;; printing will have all parts all letters too thereafter
       (rehearsal-letters-all-players t)
       ;; set to t if using bartok pizz and othersigns
       (use-custom-markup t)
       (rehearsal-letters-font-size 18)
       ;; "2.16.2") "2.14.2") ;"2.12.3") "2.17.95")  "2.20.0")
       (lp-version "2.24.1")
       ;; 24.7.11 (Pula) barlines through whole staff group or just a stave
       (group-barlines t)
       ;; 5.11.11 set to t if you want lilypond to optimize page breaks for
       ;; page turns in parts
       (page-turns nil)
       ;; MDE Sat Mar 10 16:52:31 2012 
       (process-event-fun nil)
       ;; MDE Mon Apr 16 16:08:36 2012 -- added so that we can write a subset
       ;; of players into the score (e.g. leave out a computer part). If nil
       ;; all players will be written. NB the order of these will determine
       ;; the order in the score (overriding the ensemble order).
       (players nil)
       (footer nil)
       ;; minimum rest necessary to do a page turn; something like a time
       ;; signature e.g. (2 1) would mean we need a min. of 2 whole rests
       (min-page-turn '(2 1))
       ;; MDE Tue May 29 22:58:25 2012 
       (stemlet-length nil)
       ;; MDE Thu Jan 9 09:20:33 2014 -- if you want hairpin (cresc/dim) to
       ;; extend beyond the note set to T
       (extend-hairpins nil)
       ;; MDE Wed Dec 30 18:29:28 2020, Heidhausen
       (min-hairpin nil)
       ;; MDE Wed Jul  8 10:45:02 2015 -- tuplet numbers on beams don't usually
       ;; include a bracket but we can force this if we like
       (force-bracket nil)
       ;; MDE Thu Mar 26 18:49:46 2015: show the title? could also be a string
       ;; in order to not use the sc title
       (title t)
       ;; MDE Thu Apr 29 17:39:40 2021, Heidhausen -- show the composer? also
       ;; possibly a string
       (composer t)
       two-sided                        ; MDE Wed Oct 21 18:15:08 2015
       ;; MDE Sat Dec 24 14:54:34 2016 -- try also "dodecaphonic" if you want
       ;; accidentals before every pitch 
       (accidental-style "modern")
       ;; MDE Thu Mar 26 19:18:03 2015
       (indent t)
       ;; MDE Thu Apr 28 15:17:36 2016 -- specify the player name(s) as a
       ;; symbol or in a list for any parts that have been created merely as
       ;; empty staves to add cross-staff notation.
       dummy-staves
       ;; MDE Thu Feb  2 14:45:21 2017 -- fixed width rhythmic notation
       fixed-width
       ;; MDE Sat Sep 30 16:55:40 2023, Heidhausen -- the PDF should contain
       ;; links to the source code?
       (links t)
       ;; sim to rehearsal letters
       (tempi-all-players t)
       (ekmelic-style "gost"))

slippery-chicken/write-xml [ Methods ]

[ Top ] [ slippery-chicken ] [ Methods ]

DATE

 March 17th 2017, Edinburgh

DESCRIPTION

 Write a MusicXML file for import into Sibelius, Finale, Dorico, etc. All
 voices for the score and parts are written into one file. As it is assumed
 that editing will take place in the notation software of choice, there are
 only very basic arguments to this method, some of which may even be ignored
 upon import. For example, the :in-c keyword argument of other methods is
 missing here, as switching between sounding and transposing scores is
 assumed to be the job of the notation software used for MusicXML import.

 NB Sibelius 7.5 messes up some transposing instruments, getting octave
 transpositions wrong and adding generally unwanted key signatures.

ARGUMENTS

 - the slippery-chicken object

OPTIONAL ARGUMENTS

 keyword arguments
 - :staff-height.  The suggested height of the staff, in millimetres. Default
   = 7.
 - :page-width. The page width in millimetres. Default = 210 = A4
 - :page-height The page height in millimetres. Default = 297 = A4
 - :tenths. A number representing tenths of interline staff space (positive
   or negative). Both integer and decimal values are allowed, such as 5 for a
   half space and 2.5 for a quarter space. Interline space is measured from
   the middle of a staff line. Distances in a MusicXML file are measured in
   tenths of staff space. Tenths are then scaled to millimeters within the
   scaling element, used in the defaults element at the start of a score. See
   https://usermanuals.musicxml.com/MusicXML/Content/EL-MusicXML-scaling.htm
   for more detail. Default = 40.
 - :left-page-margins. A 4-element list specifying for left pages in the
   score the left, right, top, and bottom margins, all in
   millimetres. Default = '(20 20 20 20) 
 - :right-page-margins. Similar to :left-page-margins but for right pages.
 - :players. Which players to write to the xml file. Default = NIL = process
   all players.
 - :hide-players. Which players to leave out of the score.
 - :start-bar. The bar number to start at. Default = NIL = 1.
 - :end-bar. The bar number to end at. Default = NIL = the last bar in the
   slippery-chicken object. 
 - :respell-notes. NIL, T or a list to indicate whether the method should
   also call the respell-notes method on the given slippery-chicken object
   before generating the output to undertake enharmonic changes. If a list,
   then these are the specific enharmonic corrections to be undertaken. If
   this is T, the method will process all pitches for potential
   respelling. If NIL, no respelling will be undertaken. See the
   documentation for the respell-notes method for more detail. Default = T.
 - :file. The full path of the file to write. Default will be derived from
   the title slot of the slippery-chicken object and will be written into the
   default directory e.g. (set-sc-config 'default-dir "~/Desktop")
 - :suffix. A string to append to the default file name before the .xml
   extension. Default = "".

RETURN VALUE

 The file name written, as a string.

SYNOPSIS

(defmethod write-xml ((sc slippery-chicken)
                      &key
                        (staff-height 7)  ; mm
                        (page-width 210)  ; mm = a4
                        (page-height 297) ; mm = a4
                        (tenths 40)       ; see below
                        ;; left right top bottom, all mm
                        (left-page-margins '(20 20 20 20))
                        (right-page-margins '(20 20 20 20))
                        players hide-players start-bar end-bar
                        (respell-notes t)
                        ;; MDE Tue Nov 30 09:01:48 2021, Heidhausen
                        (suffix "") 
                        file)