./../../src/event.lsp

## event/add-arrow [ Methods ]

[ Top ] [ event ] [ Methods ]

DATE

     25 Jun 2011

DESCRIPTION

     Adds a start-arrow mark to the given event object and stores text that is
     to be attached to the start and end of the given arrow for LilyPond
     output. This is a little more complex than the usual mark adding process,
     hence this separate method and it not being possible to add arrows to
     rthm-seq objects.  Not available for CMN.

     NB: A separate end-arrow mark should be attached to the note where the end
         text is to appear.  Use end-arrow for this or (add-mark e 'end-arrow).

ARGUMENTS

     - An event object.
     - A start-text string.
     - An end-text string.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether or not to print a warning when trying to
       attach an arrow and accompanying marks to a rest. Default = NIL.

RETURN VALUE

     Returns T.

EXAMPLE

    ;; Create an event object and see that the MARKS-BEFORE and MARKS slots are set
    ;;; to NIL by default
    (let ((e (make-event 'c4 'q)))
      (print (marks-before e))
      (print (marks e)))

    =>
    NIL
    NIL

    ;; Create an event object, apply the add-arrow method, and print the
    ;; corresponding slots to see the changes.
    (let ((e (make-event 'c4 'q)))
      (add-arrow e "start here" "end here")
      (print (marks-before e))
      (print (marks e)))

    =>
    ((ARROW "start here" "end here"))
    (START-ARROW)

    ;; Create an event object that is a rest and apply the add-arrow method with
    ;; the optional argument set to T to see the warning printed.
    (let ((e (make-event nil 'q)))
      (add-arrow e "start here" "end here" t))

    => T
    event::add-arrow: add arrow to rest?

SYNOPSIS

    (defmethod add-arrow ((e event) start-text end-text &optional warn-rest)

## event/add-clef [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Add a clef indication to the MARKS-BEFORE slot of the given event object.

     NB: This method does not check that the clef-name added is indeed a clef,
     nor does it check to see if other clefs have already been attached to the
     same event object.

ARGUMENTS

     - An event object.
     - A clef name (symbol).

OPTIONAL ARGUMENTS

     - (Internal "ignore" arguments only; not needed by the user).

RETURN VALUE

     Returns the contents (list) of the MARKS-BEFORE slot if successful.

     Returns NIL if the clef name is already present in the MARKS-BEFORE slot
     and is therefore not added.

EXAMPLE

    ;; Successfully adding a clef returns the contents of the MARKS-BEFORE slot
    (let ((e (make-event 'c4 'q)))
      (add-clef e 'treble))

    => ((CLEF TREBLE))

    ;; Returns NIL if the clef name is already present
    (let ((e (make-event 'c4 'q)))
      (add-clef e 'treble)
      (add-clef e 'treble))

    => NIL

    ;; Add a clef name to the marks-before slot and check that it's there
    (let ((e (make-event 'c4 'q)))
      (add-clef e 'bass)
      (marks-before e))

    => ((CLEF BASS))

SYNOPSIS

    (defmethod add-clef ((e event) clef &optional (delete-others t) ignore1 ignore2)

## event/add-pitches [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Add pitches to a non-rest event.  This works whether the event is a single
     pitch or a chord.  NB This adds to the sounding pitches, not written
     pitches of transposing instruments.  The midi-channel of the pitch is
     presumed to be correct before this method is called.

ARGUMENTS

     - The event object
     - &rest: an arbitrary number of pitches: either pitch objects or symbols.

RETURN VALUE

     The same event but with the new pitches added.

EXAMPLE

    (let ((e1 (make-event 'c4 'q))
          (e2 (make-event '(c4 e4 g4) 'e)))
      (add-pitches e1 'cs3 'd5)
      (add-pitches e2 'cs2)))

SYNOPSIS

    (defmethod add-pitches ((e event) &rest pitches)

## event/add-trill [ Methods ]

[ Top ] [ event ] [ Methods ]

DATE

     24 Sep 2011

DESCRIPTION

     Used for adding pitched trills to printed score output. Adds the necessary
     values to the MARKS and MARKS-BEFORE slots of a given event object.

     NB: The main interface for adding trills by hand is
         slippery-chicken::trill, which is the class-method combination that
         should be accessed for this purpose.

     NB: This method will check to see if the specified trill marks are already
         present in the MARKS and MARKS-BEFORE slots. If they are, the method
         will print a warning but will add the specified trill marks anyway.

ARGUMENTS

     - An event object.
     - A pitch-symbol for the trill note.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether or not to print a warning when attaching
       trill information to a rest. Default = NIL.

RETURN VALUE

     Always returns T.

     NB: At the moment the method will also print the reminder warning that this
     is a LilyPond-only mark.

EXAMPLE

    ;; Create an event object and print the contents of the MARKS-BEFORE and MARKS
    ;; slots to see that they're empty by default.
    (let ((e (make-event 'c4 'q)))
      (print (marks-before e))
      (print (marks e)))

    =>
    NIL
    NIL

    ;; Create an event object, add a trill to the note 'D4, and print the
    ;; corresponding slots to see the changes
    (let ((e (make-event 'c4 'q)))
      (add-trill e 'd4)
      (print (marks-before e))
      (print (marks e)))

    =>
    WARNING:
    rhythm::validate-mark: no CMN mark for BEG-TRILL-A (but adding anyway).

    (BEG-TRILL-A)
    ((TRILL-NOTE D4))

    ;; By default the method adds prints no warning when adding a mark to a rest
    ;; (though it still prints the warning that there is no CMN mark)
    (let ((e (make-event nil 'q)))
      (add-trill e 'd4)
      (print (marks-before e))
      (print (marks e)))

    =>
    WARNING:
    rhythm::validate-mark: no CMN mark for BEG-TRILL-A (but adding anyway).

    (BEG-TRILL-A)
    ((TRILL-NOTE D4))

    ;; Set the optional argument to T to have the method print a warning when
    ;; attaching a mark to a rest
    (let ((e (make-event nil 'q)))
      (add-trill e 'd4 t)
      (print (marks-before e))
      (print (marks e)))

    =>
    event::add-trill: add trill to rest?
    WARNING:
    rhythm::validate-mark: no CMN mark for BEG-TRILL-A (but adding anyway).

    (BEG-TRILL-A)
    ((TRILL-NOTE D4))

    ;; Adding a trill that is already there will result in a warning being printed
    ;; but will add the mark anyway
    (let ((e (make-event 'c4 'q)))
      (loop repeat 4 do (add-trill e 'd4))
      (print (marks-before e))
      (print (marks e)))

    =>
    WARNING:
       rhythm::add-mark: (TRILL-NOTE D4) already present but adding again!:
    [...]
    (BEG-TRILL-A BEG-TRILL-A BEG-TRILL-A BEG-TRILL-A)
    ((TRILL-NOTE D4) (TRILL-NOTE D4) (TRILL-NOTE D4) (TRILL-NOTE D4))

SYNOPSIS

    (defmethod add-trill ((e event) trill-note &optional warn-rest)

## event/delete-clefs [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Delete any clef names found in the MARKS-BEFORE slot of a given event
     object.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether or not to print a warning when there are no
       clef marks to delete.
     - (Other internal "ignore" arguments only; not needed by the user).

RETURN VALUE

     Always NIL.

EXAMPLE

    ;; Returns NIL when no clef marks are found to delete, and prints a warning by
    ;; default.
    (let ((e (make-event 'c4 'q)))
      (delete-clefs e))

    => NIL
    WARNING: event::delete-clefs: no clef to delete:
    [...]

    ;; Setting the optional WARN argument to T suppresses the warning when no clefs
    ;; are found.
    (let ((e (make-event 'c4 'q)))
      (delete-clefs e nil))

    => NIL

    ;; Also returns NIL when successful
    (let ((e (make-event 'c4 'q)))
      (add-clef e 'treble)
      (delete-clefs e))

    => NIL

    ;; Create an event, add a clef, print the MARKS-BEFORE slot, delete the event,
    ;; print MARKS-BEFORE again to make sure it's gone
    (let ((e (make-event 'c4 'q)))
      (add-clef e 'treble)
      (print (marks-before e))
      (delete-clefs e)
      (print (marks-before e)))

    =>
    ((CLEF TREBLE))
    NIL

SYNOPSIS

    (defmethod delete-clefs ((e event) &optional (warn t) ignore1 ignore2)

## event/delete-written [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Delete the contents of the WRITTEN-PITCH-OR-CHORD slot of a given event
     object and reset to NIL.

ARGUMENTS

     - An event object.

RETURN VALUE

     Always returns NIL.

EXAMPLE

    ;; Create an event object, print the contents of the written-pitch-or-chord ;
    ;; slot to see it's set to NIL, set-written to -2, print the contents of the ;
    ;; corresponding slot to see the data of the newly created pitch object, ;
    ;; delete-written, print the contents of the written-pitch-or-chord slot to see ;
    ;; it's empty.                          ;
    (let ((e (make-event 'c4 'q)))
      (print (written-pitch-or-chord e))
      (set-written e -2)
      (print (data (written-pitch-or-chord e)))
      (delete-written e)
      (print (written-pitch-or-chord e)))

    =>
    NIL
    BF3
    NIL

SYNOPSIS

    (defmethod delete-written ((e event))

## event/end-arrow [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Adds an end-arrow mark to the given event object.

     NB: This method works for LilyPond only. When used with CMN, output will
         still be generated, but no mark will be added. The method prints a
         corresponding warning when applied.

ARGUMENTS

     - An event object.

RETURN VALUE

     Returns T.

EXAMPLE

    ;; Returns T
    (let ((e (make-event 'c4 'q)))
      (end-arrow e))

    => T
    WARNING:
    rhythm::validate-mark: no CMN mark for END-ARROW (but adding anyway).

    ;; Create an event object, add end-arrow, and print the MARKS and MARKS-SLOTS
    ;; to see the result
    (let ((e (make-event 'c4 'q)))
      (end-arrow e)
      (print (marks-before e))
      (print (marks e)))

    =>
    NIL
    (END-ARROW)

SYNOPSIS

    (defmethod end-arrow ((e event))

## event/end-trill [ Methods ]

[ Top ] [ event ] [ Methods ]

DATE

     24 Sep 2011

DESCRIPTION

     Adds an 'end-trill-a mark to the MARKS slot of the given event object.

ARGUMENTS

     - An event object.

RETURN VALUE

     T

EXAMPLE

    ;; The end-trill method returns T
    (let ((e (make-event 'c4 'q)))
      (end-trill e))

    => T

    ;; Add an 'end-trill-a and check the MARKS slot to see that it's there
    (let ((e (make-event 'c4 'q)))
      (end-trill e)
      (marks e))

    => (END-TRILL-A)

SYNOPSIS

    (defmethod end-trill ((e event))

## event/enharmonic [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Change the pitch of the pitch object within the given event object to its
     enharmonic equivalent.

     In its default form, this method only applies to note names that already
     contain an indication for an accidental (such as DF4 or BS3), while
     "white-key" note names (such as B3 or C4) will not produce an enharmonic
     equivalent. In order to change white-key pitches to their enharmonic
     equivalents, set the :force-naturals argument to T.

     NB: Doesn't work on chords.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     keyword arguments:
     - :written. T or NIL to indicate whether the test is to handle the written
       or sounding pitch in the event. T = written. Default = NIL.
     - :force-naturals. T or NIL to indicate whether to force "natural" note
       names that contain no F or S in their name to convert to their enharmonic
       equivalent (ie, B3 = CF4). NB double-flats/sharps are not implemented so
       this will only work on F/E  B/C.

RETURN VALUE

     An event object.

EXAMPLE

    ;; The method alone returns an event object
    (let ((e (make-event 'cs4 'q)))
      (enharmonic e))

    =>
    EVENT: start-time: NIL, end-time: NIL,
    [...]

    ;; Create an event, change it's note to the enharmonic equivalent, and print
    ;; it.
    (let ((e (make-event 'cs4 'q)))
      (enharmonic e)
      (data (pitch-or-chord e)))

    => DF4

    ;; Without the :force-naturals keyword, no "white-key" note names convert to
    ;; enharmonic equivalents
    (let ((e (make-event 'b3 'q)))
      (enharmonic e)
      (data (pitch-or-chord e)))

    => B3

    ;; Set the :force-naturals keyword argument to T to enable switching white-key
    ;; note-names to enharmonic equivalents
    (let ((e (make-event 'b3 'q)))
      (enharmonic e :force-naturals t)
      (data (pitch-or-chord e)))

    => CF4

SYNOPSIS

    (defmethod enharmonic ((e event) &key written force-naturals
                           ;; 1-based
                           chord-note-ref)

## event/event-distance [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Get the distance (interval) in semitones between the pitch level of one
     event object and a second. Negative numbers indicate direction interval
     directionality. An optional argument allows distances to be always printed
     as absolute values (positive).

     Event-distance can also be determined between chords, in which case the
     distance is measured between the highest pitch of one event object and the
     lowest of the other.

ARGUMENTS

     - A first event object.
     - A second event object.

OPTIONAL ARGUMENTS

     - T or NIL for whether the value should be returned as an absolute
       value (i.e., always positive). Default = NIL.

RETURN VALUE

     A number.

EXAMPLE

    ;; The semitone distance between two single pitches in ascending direction ;
                         (let ((e1 (make-event 'c4 'q))
    (e2 (make-event 'e4 'q)))
    (event-distance e1 e2))

                         => 4.0

    ;; The semitone distance between two single pitches in descending direction ;
                         (let ((e1 (make-event 'c4 'q))
    (e2 (make-event 'e4 'q)))
    (event-distance e2 e1))

                         => -4.0

    ;; Set the optional argument to T to get the absolute distance (positive ;
    ;; number)                              ;
                         (let ((e1 (make-event 'c4 'q))
    (e2 (make-event 'e4 'q)))
    (event-distance e2 e1 t))

                         => 4.0

    ;; The semitone distance between two chords in ascending direction ;
                         (let ((e1 (make-event '(c4 e4 g4) 'q))
    (e2 (make-event '(d4 f4 a4) 'q)))
    (event-distance e1 e2))

                         => 9.0

SYNOPSIS

    (defmethod event-distance ((e1 event) (e2 event) &optional absolute)

## event/event-p [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Test to confirm that a given object is an event object.

ARGUMENTS

     - An object.

RETURN VALUE

     T if the tested object is indeed an event object, otherwise NIL.

EXAMPLE

    ;; Create an event and then test whether it is an event object
    (let ((e (make-event 'c4 'q)))
      (event-p e))
    => T

    ;; Create a non-event object and test whether it is an event object
    (let ((e (make-rhythm 4)))
      (event-p e))
    => NIL

    ;; The make-rest function also creates an event
    (let ((e (make-rest 4)))
      (event-p e))
    => T

    ;; The make-punctuation-events, make-events and make-events2 functions create
    ;; lists of events, not events themselves.
    (let ((e (make-events '((g4 q) e s))))
      (event-p e))
    => NIL

SYNOPSIS

    (defun event-p (thing)

## event/flat-p [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Determine whether the pitch of a given event object has a flat.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether the test is to handle the written or
       sounding pitch in the event. T = written. Default = NIL.

RETURN VALUE

     Returns T if the note tested has a flat, otherwise NIL (ie, is natural or
     has a sharp).

EXAMPLE

    ;; Returns T when the note is flat
    (let ((e (make-event 'df4 'q)))
      (flat-p e))

    => T

    ;; Returns NIL when the note is not flat (ie, is sharp or natural)
    (let ((e (make-event 'c4 'q)))
      (flat-p e))

    => NIL

    (let ((e (make-event 'cs4 'q)))
      (flat-p e))

    => NIL

SYNOPSIS

    (defmethod flat-p ((e event) &optional written)

## event/force-artificial-harmonic [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Change the pitch-or-chord content of a given event object such that the
     existing pitch will be notated as an artificial harmonic.

     The method creates pitch data for an artificial harmonic that will result
     in the specified pitch, rather than adding an artificial harmonic to the
     specified pitch. Thus, the method changes the existing pitch content by
     transposing the specified pitch down two octaves and adding a new pitch one
     perfect fourth above it (changing the given pitch object to a chord
     object). It then also adds the mark 'flag-head to the MARKS slot of the
     upper pitch for printing layout so that the upper pitch is printed as a
     diamond.

ARGUMENTS

     - An event object.

RETURN VALUE

     The chord object which creates the harmonic.

EXAMPLE

    ;; The method returns NIL.              ;
                         (let ((e (make-event 'c7 'q)))
    (force-artificial-harmonic e))

                         => NIL

    ;; Create an event object, apply force-artificial-harmonic, then get the new ;
    ;; pitch material                       ;
                         (let ((e (make-event 'c7 'q)))
    (force-artificial-harmonic e)
    (loop for p in (data (pitch-or-chord e)) collect (data p)))

                         => (C5 F5)

    ;; Create an event object, apply force-artificial-harmonic, then get the marks ;
    ;; attached to each note in the object to see the 'flag-head ;
                         (let ((e (make-event 'c7 'q)))
    (force-artificial-harmonic e)
    (loop for p in (data (pitch-or-chord e)) collect (marks p)))

                         => (NIL (FLAG-HEAD))

SYNOPSIS

    (defmethod force-artificial-harmonic ((e event) &optional instrument)

## event/force-rest [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Changes a given event object to a rest by setting both the PITCH-OR-CHORD
     and WRITTEN-PITCH-OR-CHORD slots to NIL and the IS-REST slot to T.

ARGUMENTS

     - An event object.

RETURN VALUE

     - An event object

EXAMPLE

    ;; The method returns an event object.  ;
                         (let ((e (make-event 'c4 'q)))
    (force-rest e))

                         =>
                         EVENT: start-time: NIL, end-time: NIL,
                         [...]

    ;; Create an event object, apply force-rest, then print the corresponding slots ;
    ;; to see the effectiveness of the method ;
                         (let ((e (make-event 'c4 'q)))
    (force-rest e)
    (print (pitch-or-chord e))
    (print (written-pitch-or-chord e))
    (print (is-rest e)))

                         =>
                         NIL
                         NIL
                         T

SYNOPSIS

    (defmethod force-rest :after ((e event))

## event/get-amplitude [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Return the amplitude attached to a given event object.

     An optional argument allows the amplitude to be converted to and returned
     as a MIDI value.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether the amplitude value is to be returned as a
       standard digital amplitude (a number between 0.0 and 1.0) or as a
       standard MIDI velocity value (a whole number between 0 and 127). T = MIDI
       value. Default = NIL.

RETURN VALUE

     If the optional argument is set to NIL, returns a real number.

     If the optional argument is set to T, returns a whole number (and a
     remainder).

EXAMPLE

    ;; Get the amplitude as a decimal value. (Each new event object has a default
    ;; amplitude of 0.7).
    (let ((e (make-event 'c4 'q)))
      (get-amplitude e))

    => 0.7

    ;; Get the amplitude as a rounded MIDI value.
    (let ((e (make-event 'c4 'q)))
      (get-amplitude e t))

    => 89, -0.10000000000000853

SYNOPSIS

    (defmethod get-amplitude ((e event) &optional (midi nil))

## event/get-clef [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Return the symbol associated with the key CLEF in the MARKS-BEFORE slot of
     the given event object.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - (Internal "ignore" arguments only; not needed by the user).

RETURN VALUE

     Returns the given clef name as a symbol if successful.

     Returns NIL if there is no clef name found in the MARKS-BEFORE slot of the
     given event object.

EXAMPLE

    ;; Returns NIL when no clef is found
    (let ((e (make-event 'c4 'q)))
      (get-clef e))

    => NIL

    ;; Returns the clef name as symbol when successful.
    (let ((e (make-event 'c4 'q)))
      (add-clef e 'treble)
      (get-clef e))

    => TREBLE

SYNOPSIS

    (defmethod get-clef ((e event) &optional ignore1 ignore2 ignore3)

## event/get-degree [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Get the degree of the event, summing or averaging for chords.

ARGUMENTS

     - an event object

OPTIONAL ARGUMENTS

     keyword arguments:
     - :written. T or NIL to indicate whether to use the written (in the case of
       transposing instruments) or sounding pitches. T = written. Default = NIL.
     - :sum. T or NIL to indicate whether to return the sum of the degrees
       instead of a list (see below). T = degrees. Default = NIL.
     - :average: sim. to sum but T or NIL to indicate whether to return the
        average instead of sum.

RETURN VALUE

     By default this returns a list (even if it's a single pitch), unless :sum T
     whereupon it will return a single value: the sum of the degrees if a chord,
     otherwise just the degree. :average T will return the average of the sum.
     A rest would return '(0) or 0.

EXAMPLE

    ;;; NB This uses the quarter-tone scale so degrees are double what they would ;
    ;;;    be in the chromatic-scale.       ;
                         (let ((event (make-event '(cs4 d4) 'e))
    (rest (make-rest 'e)))
    (print (get-degree event))
    (print (get-degree rest))
    (print (get-degree event :average t))
    (get-degree event :sum t))
                         (122 124)
                         (0)
                         123.0
                         246

SYNOPSIS

    (defmethod get-degree ((e event) &key written sum average)

## event/get-dynamic [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Gets the dynamic marking attached to a given event object.

     NB: This method is similar to the event::get-dynamics method, but assumes
     that there is only one dynamic and returns that dynamic as a single symbol
     rather than a list. If the user suspects that multiple dynamics may have
     somehow have been added to the MARKS slot of the event class, use
     get-dynamics to obtain a list of all dynamics in that slot; otherwise, this
     is the method that should be generally used.

ARGUMENTS

     - An event object.

RETURN VALUE

     The symbol representing the dynamic if there is one attached to that event,
     otherwise NIL.

EXAMPLE

    ;; The method returns just the dynamic marking from the MARKS list, as a symbol
    (let ((e (make-event 'c4 'q)))
      (add-mark-once e 'ppp)
      (add-mark-once e 'pizz)
      (get-dynamic e))

    => PPP

    ;; The method returns NIL if there is no dynamic in the MARKS list
    (let ((e (make-event 'c4 'q)))
      (add-mark-once e 'pizz)
      (get-dynamic e))

    => NIL

SYNOPSIS

    (defmethod get-dynamic ((e event))

## event/get-dynamics [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Get the list of dynamic marks from a given event object, assuming there are
     multiple dynamics present. If other non-dynamic events are also contained
     in the MARKS slot of the rhythm object within the given event object, these
     are disregarded and only the dynamic marks are returned.

     NB: This method is similar to the event::get-dynamic, but is intended for
         use should multiple dynamics have somehow become attached to the same
         event. The method event::get-dynamic is the method that should
         generally be used.

ARGUMENTS

     - An event object.

RETURN VALUE

     A list containing the dynamics stored in the MARKS slot of the rhythm
     object within the given event object. NIL is returned if no dynamic marks
     are attached to the given event object.

EXAMPLE

    ;; Create an event object and get the dynamics attached to that object. These
    ;; are NIL by default (unless otherwise specified).
    (let ((e (make-event 'c4 'q)))
      (get-dynamics e))

    => NIL

    ;; Create an event object, add one dynamic and one non-dynamic mark, print all
    ;; marks, then retrieve only the dynamics.
    (let ((e (make-event 'c4 'q)))
      (add-mark-once e 'ppp)
      (add-mark-once e 'pizz)
      (print (marks e))
      (get-dynamics e))

    =>
    (PIZZ PPP)
    (PPP)

    ;; Should multiple dynamics have become attached to the same event object,
    ;; get-dynamics will return all dynamics present in the MARKS slot
    (let ((e (make-event 'c4 'q)))
      (add-mark-once e 'pizz)
      (add-mark-once e 'ppp)
      (push 'fff (marks e))
      (print (marks e))
      (get-dynamics e))

    => (FFF PPP)

SYNOPSIS

    (defmethod get-dynamics ((e event))

## event/get-midi-channel [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Retrieve the value set for the midi-channel slot of the pitch object within
     a given event object.

ARGUMENTS

     - An event object.

RETURN VALUE

     An integer representing the given midi-channel value.

EXAMPLE

    ;; The default midi-channel value for a newly created event-object is NIL
    ;;; unless otherwise specified.
    (let ((e (make-event 'c4 'q)))
      (get-midi-channel e))

    => NIL

    ;; Create an event object, set its MIDI-channel and retrieve it
    (let ((e (make-event 'c4 'q)))
      (set-midi-channel e 11 12)
      (get-midi-channel e))

    => 11

SYNOPSIS

    (defmethod get-midi-channel ((e event))

## event/get-pitch-symbol [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Retrieve the pitch symbol (CM/CMN note-name notation) of a given event
     object. Returns a single symbol if the given event object consists of a
     single pitch; otherwise, returns a list of pitch symbols if the given event
     object consists of a chord.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether the test is to handle the event's
       written or sounding pitch. T = written. Default = T.

RETURN VALUE

     A symbol, if the event object consists of only a single pitch, otherwise a
     list of pitch symbols if the event object consists of a chord.

EXAMPLE

    ;; Get the pitch symbol of an event object with a single pitch
    (let ((e (make-event 'c4 'q)))
      (get-pitch-symbol e))

    => C4

    ;; Getting the pitch symbol of an event object that consists of a chord returns
    ;; a list of pitch symbols
    (let ((e (make-event '(c4 e4 g4) 'q)))
      (get-pitch-symbol e))

    => (C4 E4 G4)

SYNOPSIS

    (defmethod get-pitch-symbol ((e event) &optional (written t))

## event/has-hairpin [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Return T or NIL depending on whether the event has a beginning or ending
     hairpin (cresc. or dim. line).

ARGUMENTS

     - an event object

RETURN VALUE

     The hairpin mark the event has, as a list, or NIL if it has none.

SYNOPSIS

    (defmethod has-hairpin ((e event))

## event/has-mark-before [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Determine whether a specifed event object has a specified mark in its
     MARKS-BEFORE slot.

ARGUMENTS

     - An event object.
     - A mark.

RETURN VALUE

     Returns the specified mark if the mark exists in the MARKS-BEFORE slot,
     otherwise returns NIL

EXAMPLE

    ;;; Returns the specified mark if that mark is present
    (let ((e (make-event 'c4 4)))
      (add-mark-before e 'ppp)
      (has-mark-before e 'ppp))

    => (PPP)

    ;;; Returns NIL if the specified mark is not present
    (let ((e (make-event 'c4 4)))
      (add-mark-before e 'ppp)
      (has-mark-before e 'fff))

    => NIL

SYNOPSIS

    (defmethod has-mark-before ((e event) mark &optional (test #'equal))

## event/highest [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Get the highest pitch (of a chord) in a given event object. If the given
     event object contains a single pitch only, that pitch is returned.

ARGUMENTS

     - An event object.

RETURN VALUE

     A pitch object.

EXAMPLE

    ;; Returns a pitch object
    (let ((e (make-event 'c4 'q)))
      (highest e))

    =>
    PITCH: frequency: 261.6255569458008, midi-note: 60, midi-channel: NIL
    pitch-bend: 0.0
    degree: 120, data-consistent: T, white-note: C4
    nearest-chromatic: C4
    src: 1.0, src-ref-pitch: C4, score-note: C4
    qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,
    micro-tone: NIL,
    sharp: NIL, flat: NIL, natural: T,
    octave: 4, c5ths: 0, no-8ve: C, no-8ve-no-acc: C
    show-accidental: T, white-degree: 28,
    accidental: N,
    accidental-in-parentheses: NIL, marks: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: C4, tag: NIL,
    data: C4

    ;; Returns the highest note of a chord object within an event object ;
                         (let ((e (make-event '(d4 fs4 a4) 'q)))
    (data (highest e)))

    => A4

SYNOPSIS

    (defmethod highest ((e event))

## event/inc-duration [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Increase the duration of a given event object by a specified time in
     seconds. This will result in new values for the end-time,
     duration-in-tempo, and compound-duration-in-tempo slots.

     NB: Changing this value directly could result in incorrect timing info in a
         bar.

ARGUMENTS

     - An event object.
     - A value that is the increment in seconds by which the duration is to be
       extended.

RETURN VALUE

     The new duration in seconds.

EXAMPLE

    ;;; Create a slippery-chicken object, assign a variable to one of the event
    ;;; objects it contains, print the corresponding duration slots; apply
    ;;; inc-duration and print the corresponding duration slots again to see the
    ;;; change.
    (let* ((mini
           (make-slippery-chicken
            '+mini+
            :ensemble '(((vc (cello :midi-channel 1))))
            :set-palette '((1 ((gs3 as3 b3))))
            :set-map '((1 (1)))
            :rthm-seq-palette '((1 ((((2 4) q (e) s (32) 32))
                                    :pitch-seq-palette ((1 2 3)))))
            :rthm-seq-map '((1 ((vc (1)))))))
          (e (get-event mini 1 3 'vc)))
      (print (end-time e))
      (print (duration-in-tempo e))
      (print (compound-duration-in-tempo e))
      (inc-duration e 7.0)
      (print (end-time e))
      (print (duration-in-tempo e))
      (print (compound-duration-in-tempo e)))

    =>
    1.75
    0.25
    0.25
    8.75
    7.25
    7.25

SYNOPSIS

    (defmethod inc-duration ((e event) inc)

## event/is-chord [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Test to determine whether a given event object consists of a chord (as
     opposed to a single pitch or a rest).

ARGUMENTS

     - An event object.

RETURN VALUE

     - If the given event object is a chord, the method returns a number that is
       the number of notes in the chord.
     - Returns NIL if the given event object is not a chord.

EXAMPLE

    ;; Returns NIL if not a chord           ;
    (let ((e (make-event 'c4 'q)))
      (is-chord e))

    => NIL

    ;; If a chord, returns the number of notes in the chord ;
    (let ((e (make-event '(c4 e4 g4) 'q)))
      (is-chord e))

    => 3

    ;; A rest is not a chord                ;
    (let ((e (make-rest 'q)))
      (is-chord e))

    => NIL

SYNOPSIS

    (defmethod is-chord ((e event))

## event/is-dynamic [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Determine whether a specified symbol belongs to the list of predefined
     dynamic marks.

ARGUMENTS

     - A symbol.

RETURN VALUE

     NIL if the specified mark is not found on the predefined list of possible
     dynamic marks, otherwise the tail of the list of possible dynamics starting
     with the given dynamic.

EXAMPLE

    (is-dynamic 'pizz)
    => NIL

    (is-dynamic 'f)
    => (F FF FFF FFFF)

SYNOPSIS

    (defun is-dynamic (mark)

## event/is-single-pitch [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Test to see if an event object consists of a single pitch (as opposed to a
     chord or a rest).

ARGUMENTS

     - An event object.

RETURN VALUE

     Returns T if the given event object consists of a single pitch, otherwise
     returns NIL.

EXAMPLE

    ;; Returns T if the event object consists of a single pitch ;
    (let ((e (make-event 'c4 'q)))
      (is-single-pitch e))

    => T

    ;; Returns NIL if the event object is a chord ;
    (let ((e (make-event '(c4 e4 g4) 'q)))
      (is-single-pitch e))

    => NIL

    ;; Also returns NIL if the event object is a rest ;
    (let ((e (make-rest 'q)))
      (is-single-pitch e))

    => NIL

SYNOPSIS

    (defmethod is-single-pitch ((e event))

## event/lowest [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Get the lowest pitch (of a chord) in a given event object. If the given
     event object contains a single pitch only, that pitch is returned.

ARGUMENTS

     - An event object.

RETURN VALUE

     A pitch object.

EXAMPLE

    ;; Returns a pitch object               ;
    (let ((e (make-event 'c4 'q)))
      (lowest e))

    =>
    PITCH: frequency: 261.6255569458008, midi-note: 60, midi-channel: NIL
    pitch-bend: 0.0
    degree: 120, data-consistent: T, white-note: C4
    nearest-chromatic: C4
    src: 1.0, src-ref-pitch: C4, score-note: C4
    qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,
    micro-tone: NIL,
    sharp: NIL, flat: NIL, natural: T,
    octave: 4, c5ths: 0, no-8ve: C, no-8ve-no-acc: C
    show-accidental: T, white-degree: 28,
    accidental: N,
    accidental-in-parentheses: NIL, marks: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: C4, tag: NIL,
    data: C4

    ;; Returns the lowest note of a chord object within an event object ;
    (let ((e (make-event '(d4 fs4 a4) 'q)))
      (data (lowest e)))

    => D4

SYNOPSIS

    (defmethod lowest ((e event))

## event/make-event [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Create an event object for holding rhythm, pitch, and timing data.

ARGUMENTS

     - A pitch or chord. This can be one of those objects (will be added to the
       pitch-or-chord slot without cloning), or a pitch symbol or list of pitch
       symbols (for a chord).
     - The event's rhythm (e.g. 'e). If this is a number, its interpretation is
       dependent on the value of duration (see below). NB if this is a rhythm
       object, it will be cloned.

OPTIONAL ARGUMENTS

     keyword arguments:
     - :start-time. The start time of the event in seconds. Default = NIL.
     - :is-rest. Set to T or NIL to indicate whether or not the given event is a
       rest. Default = NIL. NB: The make-rest method is better suited to making
       rests; however, if using make-event to do so, the pitch-or-chord slot
       must be set to NIL.
     - :is-tied-to. This argument is for score output and playing purposes. Set
       to T or NIL to indicate whether this event is tied to the previous event
       (i.e. it won't sound independently). Default = NIL.
     - :duration. T or NIL to indicate whether the specified duration of the
       event has been stated in absolute seconds, not a known rhythm like
       'e. Thus (make-event 'c4 4 :duration nil) indicates a quarter note with
       duration 1, but (make-event '(c4 d4) 4 :duration t) indicates a whole
       note with an absolute duration of 4 seconds (both assuming a tempo of
       60). Default = NIL.
     - :amplitude sets the amplitude of the event. Possible values span from 0.0
       (silent) to maximum of 1.0. Default = (get-sc-config 'default-amplitude).
     - :tempo. A number to indicate the tempo of the event as a normal bpm
       value. Default = 60. This argument is only used when creating the rhythm
       slots (e.g. duration) not for setting duration-in-tempo.
     - :midi-channel. A number from 0 to 127 indicating the MIDI channel on
       which the event should be played back. Default = NIL.
     - :microtones-midi-channel. If the event is microtonal, this argument
       indicates the MIDI-channel to be used for the playback of the microtonal
       notes. Default = NIL. NB: See player.lsp/make-player for details on
       microtones in MIDI output.
     - :transposition. A number in semitones that indicates the transposition of
       the instrument that this event is being created for.  E.g. -2 would be
       for a B-flat clarinet.
     - :written.  The given pitch or chord is the written value.  In this case
       the sounding value will be set according to the (required) transposition
       argument.  Default = NIL.

RETURN VALUE

     - An event object.

EXAMPLE

    ;; A quarter-note (crotchet) C
                         (make-event 'c4 4)

                         =>
    EVENT: start-time: NIL, end-time: NIL,
    duration-in-tempo: 0.0,
    compound-duration-in-tempo: 0.0,
    amplitude: 0.7,
    bar-num: -1, marks-before: NIL,
    tempo-change: NIL
    instrument-change: NIL
    display-tempo: NIL, start-time-qtrs: -1,
    midi-time-sig: NIL, midi-program-changes: NIL,
    8va: 0
    pitch-or-chord:
    PITCH: frequency: 261.6255569458008, midi-note: 60, midi-channel: NIL
    pitch-bend: 0.0
    degree: 120, data-consistent: T, white-note: C4
    nearest-chromatic: C4
    src: 1.0, src-ref-pitch: C4, score-note: C4
    qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,
    micro-tone: NIL,
    sharp: NIL, flat: NIL, natural: T,
    octave: 4, c5ths: 0, no-8ve: C, no-8ve-no-acc: C
    show-accidental: T, white-degree: 28,
    accidental: N,
    accidental-in-parentheses: NIL, marks: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: C4, tag: NIL,
    data: C4
    written-pitch-or-chord: NIL
    RHYTHM: value: 4.0, duration: 1.0, rq: 1, is-rest: NIL, score-rthm: 4.0f0,
    undotted-value: 4, num-flags: 0, num-dots: 0, is-tied-to: NIL,
    is-tied-from: NIL, compound-duration: 1.0, 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: 4, tag: NIL,
    data: 4

    ;; Create a whole-note (semi-breve) chord, then print its data, value, duration
    ;; and pitch content
    (let ((e (make-event '(c4 e4 g4) 4 :duration t)))
      (print (data e))
      (print (value e))
      (print (duration e))
      (print (loop for p in (data (pitch-or-chord e)) collect (data p))))

    =>
    W
    1.0f0
    4.0
    (C4 E4 G4)

    ;; Create a single-pitch quarter-note event which is tied to, plays back on
    ;; MIDI channel 1 and has an amplitude of 0.5, then print these values by
    ;; accessing the corresponding slots.
    (let ((e (make-event 'c4 4
                         :is-tied-to t
                         :midi-channel 1
                         :amplitude 0.5)))
      (print (is-tied-to e))
      (print (midi-channel (pitch-or-chord e)))
      (print (amplitude e)))

    =>
    T
    1
    0.5

    ;; Create an event object that consists of a quarter-note rest and print the
    ;; contents of the corresponding slots
    (let ((e (make-event nil 'q :is-rest t)))
      (print (pitch-or-chord e))
      (print (data e))
      (print (is-rest e)))

    =>
    NIL
    Q
    T

SYNOPSIS

    (defun make-event (pitch-or-chord rthm &key
                       start-time
                       is-rest
                       is-tied-to
                       duration
                       midi-channel
                       microtones-midi-channel
                       ;; MDE Thu May 31 19:03:59 2012 -- allow us to auto-set the
                       ;; written-pitch-or-chord slot
                       transposition
                       ;; MDE Sat Apr 20 15:13:41 2013 -- allow us to create
                       ;; written pitch events and auto-set sounding
                       written
                       (amplitude (get-sc-config 'default-amplitude))
                       (tempo 60))

## event/make-events [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Make a list of events using the specified data, whereby a list indicates a
     note (or chord) and its rhythm and a single datum is the rhythm of a rest.

ARGUMENTS

     - A list.

OPTIONAL ARGUMENTS

     - A whole number indicating the MIDI channel on which the event is to be
       played.
     - A whole number indicating the MIDI channel on which microtonal pitches of
       the event are to be played. NB: See player.lsp/make-player for details on
       microtones in MIDI output.

RETURN VALUE

     A list.

EXAMPLE

    ;; Create a list of events including a quarter note, two rests, and a chord,
    ;; then print-simple its contents
    (let ((e (make-events '((g4 q) e s ((d4 fs4 a4) s)))))
      (loop for i in e do (print-simple i)))
    =>
    G4 Q, rest E, rest S, (D4 FS4 A4) S,

    ;; Create a list of events to be played on MIDI-channel 3, then check the MIDI
    ;; channels of each sounding note
    (let ((e (make-events '((g4 q) e s (a4 s) q e (b4 s)) 3)))
      (loop for i in e
         when (not (is-rest i))
         collect (midi-channel (pitch-or-chord i))))
    => (3 3 3)

SYNOPSIS

    (defun make-events (data-list &optional midi-channel microtones-midi-channel)

## event/make-events2 [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Like make-events, but rhythms and pitches are given in separate lists to
     allow for rhythms with ties using "+" etc. "Nil" or "r" given in the pitch
     list indicates a rest; otherwise, a single note name will set a single
     pitch while a list of note names will set a chord. Pitches for tied notes
     only have to be given once.

ARGUMENTS

     - A list of rhythms.
     - A list of note names (including NIL or R for rests).

OPTIONAL ARGUMENTS

     - A whole number value to indicate the MIDI channel on which to play back
       the event.
     - A whole number value to indicate the MIDI channel on which to play back
       microtonal pitch material for the event. NB: See player.lsp/make-player
       for details on microtones in MIDI output.

RETURN VALUE

     A list.

EXAMPLE

    ;; Create a make-events2 list and use the print-simple function to retrieve its
    ;; contents.
    (let ((e (make-events2 '(q e e. h+s 32 q+te) '(cs4 d4 (e4 g4 b5) nil a3 r))))
      (loop for i in e do (print-simple i)))
    =>
    CS4 Q, D4 E, (E4 G4 B5) E., rest H, rest S, A3 32, rest Q, rest TE,

    ;; Create a list of events using make-events2, indicating they be played back
    ;; on MIDI-channel 3, then print the corresponding slots to check it
    (let ((e (make-events2 '(q e. h+s 32 q+te) '(cs4 b5 nil a3 r) 3)))
      (loop for i in e
         when (not (is-rest i))
         collect (midi-channel (pitch-or-chord i))))
    =>
    (3 3 3)

SYNOPSIS

    (defun make-events2 (rhythms pitches
                         &optional midi-channel microtones-midi-channel)

## event/make-punctuation-events [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Given a list of numbers, a rhythm, and a note name or list of note names,
     create a new list of single events separated by rests.

     The rhythm specified serves as the basis for the new list. The numbers
     specified represent groupings in the new list that are each made up of one
     rhythm followed by rests. Each consecutive grouping in the new list has the
     length of each consecutive number in the numbers list multiplied by the
     rhythm specified.

     Notes can be a single note or a list of notes. If the latter, they'll be
     used one after the other, repeating the final note once reached.

ARGUMENTS

     - A list of grouping lengths.
     - A rhythm.
     - A note name or list of note names.

RETURN VALUE

     A list.

EXAMPLE

    ;; Create a list of three groups that are 2, 3, and 5 16th-notes long, with the
    ;; first note of each grouping being a C4, then print-simple it's contents.
    (let ((pe (make-punctuation-events '(2 3 5) 's 'c4)))
      (loop for e in pe do (print-simple e)))
    =>
    C4 S, rest S, C4 S, rest S, rest S, C4 S, rest S, rest S, rest S, rest S,

    ;; Create a list of "punctuated" events using a list of note names. Once the
    ;; final note name is reached, it is repeated for all remaining non-rest
    ;; rhythms.
    (let ((pe (make-punctuation-events '(2 3 5 8) 'q '(c4 e4))))
      (loop for e in pe do (print-simple e)))
    =>
    C4 Q, rest Q, E4 Q, rest Q, rest Q, E4 Q, rest Q, rest Q, rest Q, rest Q, E4 Q,
    rest Q, rest Q, rest Q, rest Q, rest Q, rest Q, rest Q,

SYNOPSIS

    (defun make-punctuation-events (distances rhythm notes)

## event/make-rest [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Create an event object that consists of a rest.

ARGUMENTS

     - A rhythm (duration).

OPTIONAL ARGUMENTS

     keyword arguments:
     - :start-time. A number that is the start-time of the event in seconds.
     - :duration. T or NIL. T indicates that the duration given is a value of
       absolute seconds rather than a known rhythm (e.g. 'e). Default = NIL.
     - :tempo. Beats per minute. Default = 60.

RETURN VALUE

     - An event object.

EXAMPLE

    ;; Make an event object consisting of a quarter rest
    (make-rest 4)
    =>
    EVENT: start-time: NIL, end-time: NIL,
    duration-in-tempo: 0.0,
    compound-duration-in-tempo: 0.0,
    amplitude: 0.7,
    bar-num: -1, marks-before: NIL,
    tempo-change: NIL
    instrument-change: NIL
    display-tempo: NIL, start-time-qtrs: -1,
    midi-time-sig: NIL, midi-program-changes: NIL,
    8va: 0
    pitch-or-chord: NIL
    written-pitch-or-chord: NIL
    RHYTHM: value: 4.0, duration: 1.0, rq: 1, is-rest: T, score-rthm: 4.0f0,
    undotted-value: 4, num-flags: 0, num-dots: 0, is-tied-to: NIL,
    is-tied-from: NIL, compound-duration: 1.0, 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: 4,
    tuplet-scaler: 1, grace-note-duration: 0.05
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: 4, tag: NIL,
    data: 4

    ;; Make an event object consisting of 4 seconds of rest (rather than a quarter
    ;; indicated by the :duration t) starting at time-point 13.7 seconds, then
    ;; print the corresponding slot values.
    (let ((e (make-rest 4 :start-time 13.7 :duration t)))
      (print (is-rest e))
      (print (data e))
      (print (duration e))
      (print (value e))
      (print (start-time e)))
    =>
    T
    W
    4.0
    1.0f0
    13.7

SYNOPSIS

    (defun make-rest (rthm &key start-time duration (tempo 60))

## event/natural-p [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Determine whether the pitch of a given event object is a natural note (no
     sharps or flats).

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether the test is to handle the written or
       sounding pitch in the event. T = written. Default = NIL.

RETURN VALUE

     Returns T if the note tested is natural, otherwise NIL (ie, has a flat or
     has a sharp).

EXAMPLE

    ;; Returns T when the note is natural
    (let ((e (make-event 'c4 'q)))
      (natural-p e))

    => T

    ;; Returns NIL when the note is not natural (ie, is sharp or flat)
    (let ((e (make-event 'cs4 'q)))
      (natural-p e))

    => NIL

    (let ((e (make-event 'df4 'q)))
      (natural-p e))

    => NIL

SYNOPSIS

    (defmethod natural-p ((e event) &optional written)

## event/no-accidental [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Sets the SHOW-ACCIDENTAL and ACCIDENTAL-IN-PARENTHESES slots of the given
     event object to NIL.

ARGUMENTS

     - An event object.

RETURN VALUE

     Always returns NIL.

EXAMPLE

    ;; The SHOW-ACCIDENTAL slot is automatically set to T on new event objects
    ;; that consist of a sharp or flat note.
    (let ((e (make-event 'cs4 'q)))
      (show-accidental (pitch-or-chord e)))

    => T

    ;; The method no-accidental sets the SHOW-ACCIDENTAL slot to NIL (and the
    ;; ACCIDENTAL-IN-PARENTHESES if not already).
    (let ((e (make-event 'cs4 'q)))
      (no-accidental e)
      (show-accidental (pitch-or-chord e)))

    => NIL

SYNOPSIS

    (defmethod no-accidental ((e event))

## event/output-midi [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Generate the data necessary for MIDI output for a given event object.

     NB: The given event object must contain data for start-time and
         midi-channel.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - A decimal number that is the number of seconds to offset the timing of
       the MIDI output.
     - A decimal number that is to override any other existing event object data
       for amplitude.

RETURN VALUE

     Returns the data required for MIDI output.

EXAMPLE

    ;; Simple use
    (let ((e (make-event 'c4 'q
                         :start-time 0.0
                         :midi-channel 1)))
      (output-midi e))

    => (#i(midi time 0.0 keynum 60 duration 1.0 amplitude 0.7 channel 0))

    ;; Specifying time offset and forced amplitude value
    (let ((e (make-event 'c4 'q
                         :start-time 0.0
                         :midi-channel 1)))
      (output-midi e 0.736 0.3))

    => (#i(midi time 0.736 keynum 60 duration 1.0 amplitude 0.3 channel 0))

SYNOPSIS

    (defmethod output-midi ((e event) &optional (time-offset 0.0) force-velocity)

## event/pitch- [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Determine the interval in half-steps between two pitches.

     NB: This is determined by subtracting the MIDI note value of one event from
     the other. Negative numbers may result if the greater MIDI note value is
     subtracted from the lesser.

ARGUMENTS

     - A first event object.
     - A second event object.

RETURN VALUE

     A number.

EXAMPLE

    (let ((e1 (make-event 'c4 'q))
          (e2 (make-event 'a3 'q)))
      (pitch- e1 e2))

    => 3.0

    ;; Subtracting the upper from the lower note returns a negative number
    (let ((e1 (make-event 'a3 'q))
          (e2 (make-event 'c4 'q)))
      (pitch- e1 e2))

    => -3.0

SYNOPSIS

    (defmethod pitch- ((e1 event) (e2 event))

## event/remove-dynamics [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Remove all dynamic symbols from the list of marks attached to a given event
     object.

     NB: This doesn't change the amplitude.

ARGUMENTS

     - An event object.

RETURN VALUE

     Returns the modified list of marks attached to the given event object if
     the specified dynamic was initially present in that list and successfully
     removed, otherwise returns NIL.

EXAMPLE

    ;; Create an event object, add one dynamic mark and one non-dynamic mark, print
    ;; all marks attached to the object, and remove just the dynamics from that
    ;; list of all marks.
    (let ((e (make-event 'c4 'q)))
      (add-mark-once e 'ppp)
      (add-mark-once e 'pizz)
      (print (marks e))
      (remove-dynamics e))

    =>
    (PIZZ PPP)
    (PIZZ)

    ;; Attempting to remove dynamics when none are present returns NIL.
    (let ((e (make-event 'c4 'q)))
      (remove-dynamics e))

    => NIL

SYNOPSIS

    (defmethod remove-dynamics ((e event))

## event/replace-mark [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Replace a specified mark of a given event object with a second specified
     mark. If an event object contains more than one mark, individual marks can
     be changed without modifying the remaining marks.

ARGUMENTS

     - An event object.
     - The mark to be replaced.
     - The new mark.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether the mark to be replaced is in the
       MARKS-BEFORE slot. T = it is in the MARKS-BEFORE slot. Default = NIL.

RETURN VALUE

     Returns the new value of the MARKS/MARKS-BEFORE slot of the given object.

EXAMPLE

    ;; Add marks to the MARKS slot and replace 'a with 'batt ;
                         (let ((e (make-event 'c4 'q)))
    (loop for m in '(a s pizz)
    do (add-mark e m))
    (replace-mark e 'a 'batt))

                         => (PIZZ S BATT)

    ;; Add marks to the MARKS-BEFORE slot and replace 'arco with 'at ;
                         (let ((e (make-event 'c4 'q)))
    (loop for m in '(arco col-legno)
    do (add-mark-before e m))
    (replace-mark e 'arco 'at t))

                         => (COL-LEGNO AT)

                         |#
    (defmethod replace-mark ((e event) what with &optional before)

## event/set-midi-channel [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Set the MIDI-channel and microtonal MIDI-channel for the pitch object
     within a given event object.

ARGUMENTS

     - An event object.
     - A whole number indicating the MIDI-channel to be used for playback of
       this event object.
     - A whole number indicating the MIDI-channel to be used for playback of the
       microtonal pitch material of this event.

RETURN VALUE

     Returns the value of the MIDI-channel setting (a whole number) if the
     MIDI-channel slot has been set, otherwise NIL.

EXAMPLE

    ;; Unless specified the MIDI channel of a newly created event object defaults
    ;;; to NIL.
    (let ((e (make-event 'c4 'q)))
      (midi-channel (pitch-or-chord e)))

    => NIL

    (let ((e (make-event 'c4 'q)))
      (set-midi-channel e 7 8)
      (midi-channel (pitch-or-chord e)))

    => 7

SYNOPSIS

    (defmethod set-midi-channel ((e event) midi-channel microtonal-midi-channel)

## event/set-midi-time-sig [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Sets a MIDI time signature for the given event object. This must be a
     time-sig object, not just a time signature list.

ARGUMENTS

     - An event object.
     - A time-sig object.

RETURN VALUE

     Returns a time-sig object.

EXAMPLE

    ;; Creating a new event object sets the midi-time-sig slot to NIL by default
    (let ((e (make-event 'c4 'q)))
      (midi-time-sig e))

    => NIL

    ;; The set-midi-time-sig method returns a time-sig object
    (let ((e (make-event 'c4 'q)))
      (set-midi-time-sig e (make-time-sig '(3 4))))

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

    ;; Set the midi-time-sig slot and read the data of the given time-sig object
    (let ((e (make-event 'c4 'q)))
      (set-midi-time-sig e (make-time-sig '(3 4)))
      (data (midi-time-sig e)))

    => (3 4)

SYNOPSIS

    (defmethod set-midi-time-sig ((e event) time-sig)

## event/set-written [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Set the written pitch (as opposed to sounding; i.e., for transposing
     instruments) of a given event object. The sounding pitch remains unchanged
     as a pitch object in the PITCH-OR-CHORD slot, while the written pitch is
     added as a pitch object to the WRITTEN-PITCH-OR-CHORD slot.

ARGUMENTS

     - An event object.
     - A number indicating the difference in semitones (positive or
       negative) between the written and sounding pitches.  E.g. to set the
       written-note for a B-flat Clarinet, this would be 2, for an E-flat
       Clarinet, it would be -3.

RETURN VALUE

     The 'written' pitch object.

EXAMPLE

    ;; Returns a pitch object (here for example for a D Trumpet or Clarinet) ;
    (let ((e (make-event 'c4 'q)))
      (set-written e -2))

    =>
    PITCH: frequency: 233.08186975464196, midi-note: 58, midi-channel: NIL
    pitch-bend: 0.0
    degree: 116, data-consistent: T, white-note: B3
    nearest-chromatic: BF3
    src: 0.8908987045288086, src-ref-pitch: C4, score-note: BF3
    qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,
    micro-tone: NIL,
    sharp: NIL, flat: T, natural: NIL,
    octave: 3, c5ths: 1, no-8ve: BF, no-8ve-no-acc: B
    show-accidental: T, white-degree: 27,
    accidental: F,
    accidental-in-parentheses: NIL, marks: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: BF3, tag: NIL,
    data: BF3

    ;; Create a single-pitch event object, set it's written pitch to two half-steps ;
    ;; lower, and print the corresponding data slots ;
    (let ((e (make-event 'c4 'q)))
      (set-written e -2)
      (print (data (pitch-or-chord e)))
      (print (data (written-pitch-or-chord e))))

    =>
    C4
    BF3

SYNOPSIS

    (defmethod set-written ((e event) transposition)

## event/setf amplitude [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Change the amplitude slot of a given event object and automatically add a
     mark to set a corresponding dynamic.

     Numbers greater than 1.0 and less than 0.0 will also be stored in the
     amplitude slot of the given event object without printing a warning, though
     corresponding dynamic marks are only available for values between 0.0 and
     1.0. Any value above 1.0 or below 0.0 will result in a dynamic marking of
     FFFF and NIENTE respectively.

ARGUMENTS

     - An amplitude value (real number).
     - An event object.

RETURN VALUE

     Returns the specified amplitude value.

EXAMPLE

    ;; When no amplitude is specified, new event objects are created with a default
    ;; amplitude of 0.7.
    (let ((e (make-event 'c4 'q)))
      (amplitude e))

    => 0.7

    ;; Setting an amplitude returns the amplitude set
    (let ((e (make-event 'c4 'q)))
      (setf (amplitude e) .3))

    => 0.3

    ;; Create an event object, set its amplitude, then print the contents of the
    ;; amplitude and marks slots to see the dynamic setting.
    (let ((e (make-event 'c4 'q)))
      (setf (amplitude e) .3)
      (print (amplitude e))
      (print (marks e)))

    =>
    0.3
    (PP)

    ;; Setting an amplitude greater than 1.0 or less than 0.0 sets the amplitude
    ;; correspondingly and sets the dynamic mark to FFFF or NIENTE respectively.
    (let ((e1 (make-event 'c4 'q))
          (e2 (make-event 'c4 'q)))
      (setf (amplitude e1) 1.3)
      (setf (amplitude e2) -1.3)
      (print (marks e1))
      (print (marks e2)))

    =>
    (FFFF)
    (NIENTE)

SYNOPSIS

    (defmethod (setf amplitude) :after (value (e event))

## event/setf tempo-change [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Store the tempo when a change is made.

     NB: This creates a full tempo object, not just a number representing bpm.

ARGUMENTS

     - An event object.
     - A number indicating the new tempo bpm.

RETURN VALUE

     Returns a tempo object.

EXAMPLE

    ;; Creation of a new event object sets the tempo-change slot to NIL by default,
    ;; unless otherwise specified.
    (let ((e (make-event 'c4 'q)))
      (tempo-change e))

    => NIL

    ;; The tempo-change method returns a tempo object
    (let ((e (make-event 'c4 'q)))
      (setf (tempo-change e) 132))

    =>
    TEMPO: bpm: 132, beat: 4, beat-value: 4.0, qtr-dur: 0.45454545454545453
           qtr-bpm: 132.0, usecs: 454545, description: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: NIL, tag: NIL,
    data: 132

    ;; The new tempo object is stored in the event object's tempo-change slot.
    (let ((e (make-event 'c4 'q)))
      (setf (tempo-change e) 132)
      e)

    =>
    EVENT: start-time: NIL, end-time: NIL,
           duration-in-tempo: 0.0,
           compound-duration-in-tempo: 0.0,
           amplitude: 0.7, score-marks: NIL,
           bar-num: -1, cmn-objects-before: NIL,
           tempo-change:
    TEMPO: bpm: 132, beat: 4, beat-value: 4.0, qtr-dur: 0.45454545454545453
           qtr-bpm: 132.0, usecs: 454545, description: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: NIL, tag: NIL,
    data: 132
    [...]

SYNOPSIS

    (defmethod (setf tempo-change) (value (e event))

## event/sharp-p [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Determine whether the pitch of a given event object has a sharp.

ARGUMENTS

     - An event object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether the test is to handle the written or
       sounding pitch in the event. T = written. Default = NIL.

RETURN VALUE

     Returns T if the note tested has a sharp, otherwise NIL (ie, is natural or
     has a flat).

EXAMPLE

    ;; Returns T when the note is sharp
    (let ((e (make-event 'cs4 'q)))
      (sharp-p e))

    => T

    ;; Returns NIL when the note is not sharp (ie, is flat or natural)
    (let ((e (make-event 'c4 'q)))
      (sharp-p e))

    => NIL

    (let ((e (make-event 'df4 'q)))
      (sharp-p e))

    => NIL

SYNOPSIS

    (defmethod sharp-p ((e event) &optional written)

## event/sort-event-list [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Sort a list of event objects by start time from lowest to highest.

ARGUMENTS

     - A list of event objects.

RETURN VALUE

     A list of event objects.

EXAMPLE

    ;; Create a list of event object with non-sequential start-times, sort them,
    ;; and return the pitches and start times of the newly ordered list.
    (let ((e-list (loop repeat 8
                     for nn in '(c4 d4 e4 f4 g4 a4 b4 c5)
                     for st in '(1.0 3.0 2.0 5.0 8.0 4.0 7.0 6.0)
                     collect (make-event nn 'e :start-time st))))
      (sort-event-list e-list)
      (loop for e in e-list
         collect (get-pitch-symbol e)
         collect (start-time e)))
    =>
    (C4 1.0 E4 2.0 D4 3.0 A4 4.0 F4 5.0 C5 6.0 B4 7.0 G4 8.0)

SYNOPSIS

    (defun sort-event-list (event-list)

## event/transpose [ Methods ]

[ Top ] [ event ] [ Methods ]

DESCRIPTION

     Transpose the pitch content of a given event object by a specified number
     of semitones. This method can be applied to chords or single-pitches.

     If functions are given, these will be used for the note or chord in the
     event, whereby semitones may or may not be NIL in that case (transposition
     could be dependent on the note or chord rather than being a fixed shift).

     NB: By default this method returns a modified clone of the original rather
         than changing the values of the original itself. The user can choose to
         replace the values of the original by setting the keyword argument
         :destructively to T.

ARGUMENTS

     - An event object.
     - A number (can be positive or negative).

OPTIONAL ARGUMENTS

     keyword arguments:
     - :destructively. T or NIL to indicate whether the method is to replace the
       pitch values of the original event object (T) or return a new event
       object with the new pitches (NIL). Default = NIL.
     - :chord-function. A function to be used for the transposition of
       chords. Default = #'transpose.
     - :pitch-function. A function to be used for the transposition of
       pitches. Default = #'transpose.

RETURN VALUE

     An event object.

EXAMPLE

    ;; Transpose returns an event object    ;
    (let ((e (make-event 'c4 'q)))
      (transpose e 1))

    =>
    EVENT: start-time: NIL, end-time: NIL,
    duration-in-tempo: 0.0,
    [...]

    ;; By default transpose returns a modified clone, leaving the original event ;
    ;; object untouched.                    ;
    (let ((e (make-event 'c4 'q)))
      (print (data (pitch-or-chord (transpose e 1))))
      (print (data (pitch-or-chord e))))

    =>
    CS4
    C4

    ;; When the keyword argument :destructively is set to T, the data of the ;
    ;; original event object is replaced    ;
    (let ((e (make-event 'c4 'q)))
      (transpose e 1 :destructively t)
      (data (pitch-or-chord e)))

    => CS4

    ;; Can transpose by 0 as well (effectively no transposition) ;
    (let ((e (make-event 'c4 'q)))
      (transpose e 0 :destructively t)
      (data (pitch-or-chord e)))

    => C4

    ;; ...or by negative intervals          ;
    (let ((e (make-event 'c4 'q)))
      (transpose e -3 :destructively t)
      (data (pitch-or-chord e)))

    => A3

    ;; Can transpose chords too             ;
    (let ((e (make-event '(c4 e4 g4) 'q)))
      (transpose e -3 :destructively t)
      (loop for p in (data (pitch-or-chord e)) collect (data p)))

    => (A3 CS4 E4)

SYNOPSIS

    (defmethod transpose ((e event) semitones
                          &key
                          destructively
                          ;; the default functions are the class methods for pitch
                          ;; or chord.
                          (chord-function #'transpose)
                          (pitch-function #'transpose))

## event/wrap-events-list [ Functions ]

[ Top ] [ event ] [ Functions ]

DESCRIPTION

     Given a list of time-ascending event objects, rotate their start-times by
     moving the lowest start time to a specified point in the list (determined
     either by time or by nth position), assigning the subsequent start times
     sequentially through the remainder of events in the list, and wrapping
     around to the head of the list again to assign the final remaining start
     times. If the first event doesn't start at 0, its start time will be
     conserved.

ARGUMENTS

     - A flat list of event objects.
     - An integer that is the number of the event object with which to start
       (nth position), or a decimal time in seconds.

OPTIONAL ARGUMENTS

     keyword argument:
     - :time. T or NIL to indicate whether the second argument is a time in
       seconds or an nth index. If a time in seconds, the method skips to the
       closest event object in the list. T = time in seconds. Default = NIL.

RETURN VALUE

     Returns a flat list of event objects with adjust start-times.

EXAMPLE

    ;;; Create a list of events of eighth-note durations, specifying start-times at ;
    ;;; 0.5-second intervals and print the pitches and start-times. Then apply the ;
    ;;; function and print the pitches and start-times again to see the change. ;
    (let ((e-list (loop for st from 1.0 by 0.5
                     for nn in '(c4 d4 e4 f4 g4 a4 b4 c5)
                     collect (make-event nn 'e :start-time st))))
      (print
       (loop for e in e-list
          collect (get-pitch-symbol e)
          collect (start-time e)))
      (wrap-events-list e-list 3)
      (print
       (loop for e in e-list
          collect (get-pitch-symbol e)
          collect (start-time e))))
    =>
    (C4 1.0 D4 1.5 E4 2.0 F4 2.5 G4 3.0 A4 3.5 B4 4.0 C5 4.5)
    (C4 3.5 D4 4.0 E4 4.5 F4 1.0 G4 1.5 A4 2.0 B4 2.5 C5 3.0)

SYNOPSIS

    (defun wrap-events-list (events start-at &key (time nil))

## rhythm/event [ Classes ]

[ Top ] [ rhythm ] [ Classes ]

NAME

     event

     File:             event.lsp

     Class Hierarchy:  named-object -> linked-named-object -> rhythm -> event

     Version:          1.0.6

     Project:          slippery chicken (algorithmic composition)

     Purpose:          Implementation of the event class which holds data for
                       the construction of an audible event, be it a midi note,
                       a sample (with corresponding sampling-rate conversion
                       factor) or chord of these types.

                       It is generally assumed that event instances will be
                       created from (copies of) rhythm instances by promotion
                       through the sc-change-class function, hence this class is
                       derived from rhythm.

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

     Creation date:    March 19th 2001

     $$ Last modified: 11:53:10 Mon Jan 18 2016 GMT

     SVN ID: $Id: event.lsp 5468 2016-01-18 17:29:54Z medward2 $