./../../src/rthm-seq.lsp

## rthm-seq/add-bar [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Add a rthm-seq-bar object to the end of a given rthm-seq object.

     NB: If the rthm-seq-bar object is added without specifying a
         pitch-seq-palette, the method automatically adds data to the existing
         pitch-seq-palette.

ARGUMENTS

     - A rhtm-seq object.
     - A rthm-seq-bar object.

OPTIONAL ARGUMENTS

     - A pitch-seq-palette.

RETURN VALUE

     Returns the new value of the DURATION slot of the given rthm-seq object.

EXAMPLE

    ;; Returns the new value of the DURATION slot
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (add-bar rs (make-rthm-seq-bar '((5 8) e e+32 s. +q))))

    => 10.5

    ;; Apply the method and print the rhythms objects of the given rthm-seq object
    ;; to see the changes
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (add-bar rs (make-rthm-seq-bar '((5 8) e e+32 s. +q)))
      (print-simple rs))

    =>
    rthm-seq NIL
    (2 4): note Q, note E, note S, note S,
    (2 4): rest E, note Q, rest E,
    (3 8): note S, note S, note E., note S,
    (5 8): note E, note E, note 32, note S., note Q,

    ;; Apply the method and print the DATA slot of the updated PITCH-SEQ-PALETTE
    ;; slot to see the new notes that have been automatically added
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (add-bar rs (make-rthm-seq-bar '((5 8) e e+32 s. +q)))
      (data (first (data (pitch-seq-palette rs)))))

    => (1 2 3 1 1 2 3 4 3 4 3)

SYNOPSIS

    (defmethod add-bar ((rs rthm-seq) (rsb rthm-seq-bar) &optional psp)

## rthm-seq/chop [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Applies the chop method to each rthm-seq-bar object contained in the given
     rthm-seq object (see rthm-seq-bar::chop for details), returning a list of
     rthm-seq objects, each of which contains just one of the rthm-seq-bar
     objects created with chop.

     The chop method is the basis for slippery-chicken's feature of
     intra-phrasal looping.

     NB: Since the chop method functions by comparing each beat of a given
         rthm-seq-bar object to the specified <chop-points> pattern for
         segmenting that beat, all rthm-seq-bar objects in the given rthm-seq
         object must be evenly divisible by the beat for which the pattern is
         defined. For example, if the <chop-points> argument defines a
         quarter-note, all bars in the given rthm-seq object must be evenly
         divisible by a quarter-note, and a rthm-seq object consisting of a 2/4,
         a 3/4 and a 3/8 bar would fail at the 3/8 bar with an error.

     NB: The <unit> argument must be a duplet rhythmic value (i.e. 32, 's, 'e
         etc.) and cannot be a tuplet value (i.e. 'te 'fe etc.).

     NB: In order for the resulting chopped rhythms to be parsable by LilyPond
         and CMN, there can be no tuplets (triplets etc.) among the rhythms to
         be chopped. Such rhythms will result in LilyPond and CMN errors. This
         has only minimal bearing on any MIDI files produced, however, and these
         can potentially be imported into notation software.

ARGUMENTS

     - A rthm-seq object.

OPTIONAL ARGUMENTS

     - <chop-points>. A list of integer pairs, each of which delineates a
       segment of the beat of the given rthm-seq-bar object measured in the
       rhythmic unit specified by the <unit> argument. See the documentation for
       rthm-seq-bar::chop for more details.
     - <unit>. The rhythmic duration that serves as the unit of measurement for
       the chop points. Default = 's.
     - <number-bars-first>. T or NIL. This argument helps in naming (and
       therefore debugging) the newly-created bars.  If T, the bars in the
       original rthm-seq will be renumbered, starting from 1, and this will be
       reflected in the tag of the new bars.  E.g. if T, a new bar's tag may be
       new-bar-from-rs1-b3-time-range-1.750-to-2.000, if NIL this would be
       new-bar-from-rs1-time-range-1.750-to-2.000. Default = T.

RETURN VALUE

     A list of rthm-seq objects.

EXAMPLE

    ;; Create a rthm-seq with three bars, all having a quarter-note beat basis,
    ;; apply chop, and print-simple the resulting list of new rthm-seq-bar
    ;; objects. The rthm-seq numbers printed with this are the IDs of the rthm-seq
    ;; objects, not the bar-nums of the individual rthm-seq-bar objects.
    (let* ((rs (make-rthm-seq '(seq1 ((((2 4) q e s s)
                                       ((e) q (e))
                                       (s s (e) e. s))
                                      :pitch-seq-palette ((1 2 3 4 5 6 7 8 9)
                                                          (9 8 7 6 5 4 3 2 1))))))
           (ch (chop rs
                     '((1 1) (1 2) (1 3) (1 4) (2 2) (2 3) (2 4) (3 3) (3 4) (4 4))
                     's)))
      (loop for rs-obj in ch do (print-simple rs-obj)))

    =>
    rthm-seq 1
    (1 16): NIL S,
    rthm-seq 2
    (1 8): NIL E,
    rthm-seq 3
    (3 16): NIL E.,
    rthm-seq 4
    (1 4): NIL Q,
    rthm-seq 5
    (1 16): rest 16,
    rthm-seq 6
    (1 8): rest 8,
    rthm-seq 7
    (3 16): rest 16/3,
    rthm-seq 8
    (1 16): rest 16,
    rthm-seq 9
    (1 8): rest 8,
    rthm-seq 10
    (1 16): rest 16,
    rthm-seq 11
    (1 16): NIL S,
    rthm-seq 12
    (1 8): NIL E,
    rthm-seq 13
    (3 16): NIL E, NIL S,
    rthm-seq 14
    (1 4): NIL E, NIL S, NIL S,
    rthm-seq 15
    (1 16): rest 16,
    rthm-seq 16
    (1 8): rest S, NIL S,
    rthm-seq 17
    (3 16): rest S, NIL S, NIL S,
    rthm-seq 18
    (1 16): NIL S,
    rthm-seq 19
    (1 8): NIL S, NIL S,
    rthm-seq 20
    (1 16): NIL S,
    rthm-seq 21
    (1 16): rest 16,
    rthm-seq 22
    (1 8): rest 8,
    rthm-seq 23
    (3 16): rest E, NIL S,
    rthm-seq 24
    (1 4): rest E, NIL E,
    rthm-seq 25
    (1 16): rest 16,
    rthm-seq 26
    (1 8): rest S, NIL S,
    rthm-seq 27
    (3 16): rest S, NIL E,
    rthm-seq 28
    (1 16): NIL S,
    rthm-seq 29
    (1 8): NIL E,
    rthm-seq 30
    (1 16): rest 16,
    rthm-seq 31
    (1 16): rest 16,
    rthm-seq 32
    (1 8): rest 8,
    rthm-seq 33
    (3 16): rest 16/3,
    rthm-seq 34
    (1 4): rest 4,
    rthm-seq 35
    (1 16): rest 16,
    rthm-seq 36
    (1 8): rest 8,
    rthm-seq 37
    (3 16): rest 16/3,
    rthm-seq 38
    (1 16): rest 16,
    rthm-seq 39
    (1 8): rest 8,
    rthm-seq 40
    (1 16): rest 16,
    rthm-seq 41
    (1 16): NIL S,
    rthm-seq 42
    (1 8): NIL S, NIL S,
    rthm-seq 43
    (3 16): NIL S, NIL S, rest S,
    rthm-seq 44
    (1 4): NIL S, NIL S, rest E,
    rthm-seq 45
    (1 16): NIL S,
    rthm-seq 46
    (1 8): NIL S, rest S,
    rthm-seq 47
    (3 16): NIL S, rest E,
    rthm-seq 48
    (1 16): rest 16,
    rthm-seq 49
    (1 8): rest 8,
    rthm-seq 50
    (1 16): rest 16,
    rthm-seq 51
    (1 16): NIL S,
    rthm-seq 52
    (1 8): NIL E,
    rthm-seq 53
    (3 16): NIL E.,
    rthm-seq 54
    (1 4): NIL E., NIL S,
    rthm-seq 55
    (1 16): rest 16,
    rthm-seq 56
    (1 8): rest 8,
    rthm-seq 57
    (3 16): rest E, NIL S,
    rthm-seq 58
    (1 16): rest 16,
    rthm-seq 59
    (1 8): rest S, NIL S,
    rthm-seq 60
    (1 16): NIL S,

    ;; Attempting to apply the method to a rthm-seq object in which not all bars
    ;; have time-signatures that are divisible by the beat defined in the
    ;; <chop-points> argument will result in dropping into the debugger with an
    ;; error
    (let* ((rs (make-rthm-seq '(seq1 ((((2 4) q e s s)
                                       ((e) q (e))
                                       ((3 8) (e) e. s))
                                      :pitch-seq-palette ((1 2 3 4 5 6 7)
                                                          (9 8 7 6 5 4 3))))))
           (ch (chop rs
                     '((1 1) (1 2) (1 3) (1 4) (2 2) (2 3) (2 4) (3 3) (3 4) (4 4))
                     's)))
      (loop for rs-obj in ch do (print-simple rs-obj)))

    =>
    rthm-seq-bar::get-beats: Can't find an exact beat of rhythms
       (dur: 0.75 beat-dur: 0.5)!
       [Condition of type SIMPLE-ERROR]

SYNOPSIS

    (defmethod chop ((rs rthm-seq) &optional chop-points (unit 's)
                     (number-bars-first t))

## rthm-seq/combine [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Combine two rthm-seqs into one, updating slots for the new object, which is
     a clone.

     NB: The MARKS slot is ignored for now (it is as of yet

     NB: This method sets the values of the individual slots but leaves the DATA
         slot untouched (for cases in which the user might want to see where the
         new data originated from, or otherwise use the old data somehow, such
         as in a new rthm-seq object).

ARGUMENTS

     - A first rthm-seq object.
     - A second rthm-seq object.

RETURN VALUE

     - A rthm-seq object.

EXAMPLE

    ;; The method returns a rthm-seq object
    (let ((rs1 (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4)))))
          (rs2 (make-rthm-seq '((((4 4) h+e (e) { 3 te te te })
                                ((5 8) e e+32 s. +q)
                                ((3 4) (q) q q))
                               :pitch-seq-palette ((1 2 3 4 1 2 3 1 2))))))
      (combine rs1 rs2))

    =>
    RTHM-SEQ: num-bars: 6
              num-rhythms: 25
              num-notes: 17
              num-score-notes: 21
              num-rests: 4
              duration: 15.0
              psp-inversions: NIL
              marks: NIL
              time-sigs-tag: NIL
              handled-first-note-tie: NIL
             (for brevity's sake, slots pitch-seq-palette and bars are not printed)
    SCLIST: sclist-length: 6, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "NIL-NIL", tag: NIL,
    data: ((((2 4) Q+E S S) ((E) Q (E)) ((3 8) S S E. S)) PITCH-SEQ-PALETTE
           ((1 2 3 1 1 2 3 4))
           (((4 4) H+E (E) { 3 TE TE TE }) ((5 8) E E+32 S. +Q) ((3 4) (Q) Q Q))
           PITCH-SEQ-PALETTE ((1 2 3 4 1 2 3 1 2)))

    ;; With the same combine call, print the collected contents of the BARS slot
    ;; and the PITCH-SEQ-PALETTE slot of the new rthm-seq object
    (let* ((rs1 (make-rthm-seq '((((2 4) q+e s s)
                                  ((e) q (e))
                                  ((3 8) s s e. s))
                                 :pitch-seq-palette ((1 2 3 1 1 2 3 4)))))
           (rs2 (make-rthm-seq '((((4 4) h+e (e) { 3 te te te })
                                  ((5 8) e e+32 s. +q)
                                  ((3 4) (q) q q))
                                 :pitch-seq-palette ((1 2 3 4 1 2 3 1 2)))))
           (crs (combine rs1 rs2)))
      (print-simple crs)
      (print (data (get-first (pitch-seq-palette crs)))))

    =>
    rthm-seq NIL-NIL
    (2 4): note Q, note E, note S, note S,
    (2 4): rest E, note Q, rest E,
    (3 8): note S, note S, note E., note S,
    (4 4): note H, note E, rest E, note TE, note TE, note TE,
    (5 8): note E, note E, note 32, note S., note Q,
    (3 4): rest 4, note Q, note Q,
    (1 2 3 1 1 2 3 4 1 2 3 4 1 2 3 1 2)

SYNOPSIS

    (defmethod combine ((rs1 rthm-seq) (rs2 rthm-seq))

## rthm-seq/delete-marks [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Delete all marks from the MARKS slot of the specified rthm-seq object and
     replace them with NIL.

ARGUMENTS

     - A rthm-seq object

RETURN VALUE

     NIL

EXAMPLE

    (let ((mrs (make-rthm-seq '(seq1 ((((2 4) q e (s) s))
                                      :pitch-seq-palette ((1 2 3))
                                      :marks (ff 1 a 1 pizz 1 ppp 2 s 2))))))
      (print (marks mrs))
      (delete-marks mrs)
      (print (marks mrs)))

    =>
    ((FF 1) (A 1) (PIZZ 1) (PPP 2) (S 2))
    NIL

SYNOPSIS

    (defmethod delete-marks ((rs rthm-seq))

## rthm-seq/get-bar [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Get a specified rthm-seq-bar object from within a rthm-seq object.

ARGUMENTS

     - A rthm-seq object.
     - An integer that is the 1-based number of the desired bar to return from
       within the given rthm-seq object.

RETURN VALUE

     Returns a rthm-seq-bar object.

EXAMPLE

    ;;; Returns a rthm-seq-bar object
    (let ((rs (make-rthm-seq '(seq1 ((((2 4) q e s s)
                                      ((e) q (e))
                                      ((3 8) s s e. s)))))))
      (get-bar rs 2))

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

    (let ((rs (make-rthm-seq '(seq1 ((((2 4) q e s s)
                                      ((e) q (e))
                                      ((3 8) s s e. s)))))))
      (print-simple (get-bar rs 2)))

    => (2 4): rest E, note Q, rest E,

SYNOPSIS

    (defmethod get-bar ((rs rthm-seq) bar-num &optional ignore)

## rthm-seq/get-first [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Return the first rhythm/event object in the specified rthm-seq object.

ARGUMENTS

     - A rthm-seq object.

RETURN VALUE

     A rhythm/event object.

EXAMPLE

    (let ((mrs (make-rthm-seq '(seq1 ((((2 4) q e (s) s))
                                      :pitch-seq-palette ((1 2 3))
                                      :marks (ff 1 a 1 pizz 1 ppp 2 s 2))))))
      (get-first mrs))

    =>
    RHYTHM: value: 4.000, duration: 1.000, rq: 1, is-rest: NIL,
            is-whole-bar-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: (PIZZ A FF), 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

SYNOPSIS

    (defmethod get-first ((rs rthm-seq))

## rthm-seq/get-last [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Return the last rhythm/event object in the specified rthm-seq object.

ARGUMENTS

     - A rthm-seq object.

RETURN VALUE

     A rhythm/event object.

EXAMPLE

    (let ((mrs (make-rthm-seq '(seq1 ((((2 4) q e (s) s))
                                      :pitch-seq-palette ((1 2 3))
                                      :marks (ff 1 a 1 pizz 1 ppp 2 s 2))))))
      (get-last mrs))

    =>
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
            is-whole-bar-rest: NIL,
            score-rthm: 16.0, undotted-value: 16, num-flags: 2, num-dots: 0,
            is-tied-to: NIL, is-tied-from: NIL, compound-duration: 0.250,
            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: 16, tuplet-scaler: 1, grace-note-duration: 0.05
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: S, tag: NIL,
    data: S

SYNOPSIS

    (defmethod get-last ((rs rthm-seq))

## rthm-seq/get-last-attack [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Gets the rhythm object for the last note that needs an attack (i.e. not a
     rest and not a tied note) in a given rthm-seq object.

ARGUMENTS

     - A rthm-seq object.

OPTIONAL ARGUMENTS

     - T or NIL indicating whether to print a warning message if the given index
       (minus 1) is greater than the number of attacks in the rthm-seq object
       (default = T). This is a carry-over argument from the get-nth-attack
       method called within the get-last-attack method and not likely to be
       needed for use with get-last-attack.

RETURN VALUE

     A rhythm object.

EXAMPLE

    ;; Returns a rhythm object
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-last-attack rs))

    =>
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
            score-rthm: 16.0f0, undotted-value: 16, num-flags: 2, num-dots: 0,
            is-tied-to: NIL, is-tied-from: NIL, compound-duration: 0.250,
            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: 16, tuplet-scaler: 1, grace-note-duration: 0.05
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: S, tag: NIL,
    data: S

SYNOPSIS

    (defmethod get-last-attack ((rs rthm-seq) &optional (warn t))

## rthm-seq/get-last-bar [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Get the last rthm-seq-bar object of a given rthm-seq object.

ARGUMENTS

     - A rthm-seq object.

RETURN VALUE

     A rthm-seq-bar object.

EXAMPLE

    ;;; The method returns a rthm-seq-bar object
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-last-bar rs))

    =>
    RTHM-SEQ-BAR: time-sig: 6 (3 8), time-sig-given: T, bar-num: -1,
    [...]
    data: ((3 8) S S E. S)

SYNOPSIS

    (defmethod get-last-bar ((rs rthm-seq))

## rthm-seq/get-last-event [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Get the last event object (or rhythm object) of a given rthm-seq-bar
     object.

ARGUMENTS

     - A rthm-seq object.

RETURN VALUE

     Returns an event (or rhythm) object.

EXAMPLE

    ;; The last event is a rhythm object
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-last-event rs))

    =>
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
            score-rthm: 16.0f0, undotted-value: 16, num-flags: 2, num-dots: 0,
            is-tied-to: NIL, is-tied-from: NIL, compound-duration: 0.250,
            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: 16, tuplet-scaler: 1, grace-note-duration: 0.05
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: S, tag: NIL,
    data: S

    ;; The last event is an event object
    (let ((rs (make-rthm-seq `((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. ,(make-event 'c4 's)))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-last-event rs))

    =>
    EVENT: start-time: NIL, end-time: NIL,
    [...]
    PITCH: frequency: 261.6255569458008, midi-note: 60, midi-channel: NIL
    [...]
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
    [...]
    NAMED-OBJECT: id: S, tag: NIL,
    data: S

SYNOPSIS

    (defmethod get-last-event ((rs rthm-seq))

## rthm-seq/get-multipliers [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Get a list of factors by which a specified rhythmic unit must be multiplied
     in order to create the rhythms of a given rthm-seq object.

     NB: The get-multipliers method determines durations in the source rhythmic
         material based on attacked notes only, so beginning ties will be
         ignored and rests following an attack will count the same as if the
         attacked note were tied to another note with the same duration as the
         rest. For this reason, the results returned by the method when applied
         to a rthm-seq object that contains multiple bars may differ from
         applying the method to multiple rthm-seqs with single bars, albeit with
         the same rhythms when seen as a group (see example below).

ARGUMENTS

     - A rthm-seq object.
     - A rhythm unit, either as a number or a shorthand symbol (i.e. 's)

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether to round the results. T = round.
       Default = NIL. NB: Lisp always rounds to even numbers, meaning x.5 may
       sometimes round up and sometimes round down; thus (round 1.5) => 2, and
       (round 2.5) => 2.

RETURN VALUE

     A list of numbers.

EXAMPLE

    ;;; By default the method returns the list of multipliers un-rounded
    (let ((rs (make-rthm-seq '(seq1 ((((2 4) q e s s))
                                     :pitch-seq-palette ((1 2 3 4)))))))
      (get-multipliers rs 'e))

    => (2.0 1.0 0.5 0.5)

    ;; Setting the optional argument to T rounds the results before returning
    (let ((rs (make-rthm-seq '(seq1 ((((2 4) q e s s))
                                     :pitch-seq-palette ((1 2 3 4)))))))
      (get-multipliers rs 'e t))

    => (2 1 0 0)

    ;;; Applying the method to the a multiple-bar rthm-seq object may return
    ;;; different results than applying the method to each of the bars contained
    ;;; within that rthm-seq object as individual one-bar rthm-seq objects, as the
    ;;; method measures the distances between attacked notes, regardless of ties
    ;;; and rests.
    (let ((rs1 (make-rthm-seq '(seq1 ((((2 4) q +e. s))
                                      :pitch-seq-palette ((1 2))))))
          (rs2 (make-rthm-seq '(seq2 ((((2 4) (s) e (s) q))
                                      :pitch-seq-palette ((1 2))))))
          (rs3 (make-rthm-seq '(seq3 ((((2 4) +e. s { 3 (te) te te } ))
                                      :pitch-seq-palette ((1 2 3))))))
          (rs4 (make-rthm-seq '(seq4 ((((2 4) q +e. s)
                                       ((s) e (s) q)
                                       (+e. s { 3 (te) te te } ))
                                      :pitch-seq-palette ((1 2 3 4 5 6 7)))))))
      (print (get-multipliers rs1 'e))
      (print (get-multipliers rs2 'e))
      (print (get-multipliers rs3 'e))
      (print (get-multipliers rs4 'e)))

    =>
    (3.5 0.5)
    (1.5 2.0)
    (1.1666666666666665 0.6666666666666666 0.6666666666666666)
    (3.5 1.0 1.5 3.5 1.1666666666666665 0.6666666666666666 0.6666666666666666)

SYNOPSIS

    (defmethod get-multipliers ((rs rthm-seq) rthm &optional round ignore)

## rthm-seq/get-nth-attack [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Gets the rhythm object for the nth note in a given rthm-seq object that
     needs an attack, i.e. not a rest and not tied.

ARGUMENTS

     - The zero-based index number indicating which attack is sought.
     - The given rthm-seq object in which to search.

OPTIONAL ARGUMENTS

     - T or NIL indicating whether to print an error message if the given index
       is greater than the number of attacks (minus 1) in the rthm-seq object
       (default = T).

RETURN VALUE

     A rhythm object.

EXAMPLE

    ;; The method returns a rhythm object when successful
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-nth-attack 4 rs))

    =>
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
            score-rthm: 16.0f0, undotted-value: 16, num-flags: 2, num-dots: 0,
            is-tied-to: NIL, is-tied-from: NIL, compound-duration: 0.250,
            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: 16, tuplet-scaler: 1, grace-note-duration: 0.05
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: S, tag: NIL,
    data: S

    ;; By default, the method drops into the debugger with an error when the
    ;; specified index is greater than the number of items in the given rthm-seq
    ;; object.
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-nth-attack 11 rs))

    =>
    rthm-seq::get-nth-attack: Couldn't get attack with index 11
       [Condition of type SIMPLE-ERROR]

    ;; This error can be suppressed, simply returning NIL, by setting the optional
    ;; argument to NIL.
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-nth-attack 11 rs nil))

    => NIL, 0, NIL

SYNOPSIS

    (defmethod get-nth-attack (index (rs rthm-seq)
                               &optional (error t))

## rthm-seq/get-nth-bar [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Get the nth rthm-seq-bar object from a given rthm-seq object.

ARGUMENTS

     - A rthm-seq object.
     - An index number (zero-based).

RETURN VALUE

     Returns a rthm-seq-bar object if successful.

     Returns NIL and prints a warning if the specified index number is greater
     than the number of rthm-seq-bar objects (minus one) in the given rthm-seq
     object.

EXAMPLE

    ;;; The method returns a rhtm-seq-bar object when successful
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-nth-bar 1 rs))

    =>
    RTHM-SEQ-BAR: time-sig: 0 (2 4), time-sig-given: NIL, bar-num: -1,
    [...]
    NAMED-OBJECT: id: "NIL-bar2", tag: NIL,
    data: ((E) Q (E))

    ;; Returns a warning and prints NIL when the specified index number is greater
    ;; than the number of rthm-seq-bar objects in the given rthm-seq object
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-nth-bar 11 rs))

    => NIL
    WARNING: rthm-seq::rthm-seq-check-bounds: Illegal list reference: 11

SYNOPSIS

    (defmethod get-nth-bar (nth (rs rthm-seq))

## rthm-seq/get-nth-non-rest-rhythm [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Get the nth non-rest rhythm object stored in the given rthm-seq object.

ARGUMENTS

     - The zero-based index number indicating which non-rest-rhythm is sought.
     - The given rthm-seq object in which to search.

OPTIONAL ARGUMENTS

     - T or NIL indicating whether to print an error message if the given index
       is greater than the number of non-rest rhythms (minus 1) in given
       rthm-seq object.  (Default = T.)

RETURN VALUE

     A rhythm object.

     Returns NIL if the given index is higher than the highest possible index of
     non-rest rhythms in the given rthm-seq-bar object.

EXAMPLE

    ;; The method returns a rhythm object when successful
    (let ((rs (make-rthm-seq '((((2 4) q e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3 4))))))
      (get-nth-non-rest-rhythm 4 rs))

    =>
    RHYTHM: value: 4.000, duration: 1.000, 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.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

    ;; By default, the method drops into the debugger with an error when the
    ;; specified index is greater than the number of items in the given rthm-seq
    ;; object.
    (let ((rs (make-rthm-seq '((((2 4) q e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3 4))))))
      (get-nth-non-rest-rhythm 11 rs))

    =>
    rthm-seq::get-nth-non-rest-rhythm: Couldn't get non-rest rhythm with index 11
       [Condition of type SIMPLE-ERROR]

    ;; This error can be suppressed, simply returning NIL, by setting the optional
    ;; argument to NIL.
    (let ((rs (make-rthm-seq '((((2 4) q e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3 4))))))
      (get-nth-non-rest-rhythm 11 rs nil))

    => NIL

SYNOPSIS

    (defmethod get-nth-non-rest-rhythm (index (rs rthm-seq)
                                        &optional (error t))

## rthm-seq/get-nth-rhythm [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Gets the rhythm (or event) object for the nth note in a given rthm-seq
     object.

ARGUMENTS

     - The zero-based index number indicating which attack is sought.
     - The given rthm-seq object in which to search.

OPTIONAL ARGUMENTS

     - T or NIL indicating whether to print an error message if the given index
       is greater than the number of attacks (minus 1) in the rthm-seq object
       (default = T).

RETURN VALUE

     A rhythm or event object.

EXAMPLE

    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (get-nth-rhythm 4 rs))

    =>

    RHYTHM: value: 8.000, duration: 0.500, rq: 1/2, is-rest: T,
            score-rthm: 8.0f0, 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-nth-rhythm (index (rs rthm-seq) &optional (error t))

## rthm-seq/get-rhythms [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Get the rhythm objects in a given rthm-seq object, contained in a list.

ARGUMENTS

     - A rthm-seq object.

RETURN VALUE

     A list.

EXAMPLE

    ;; Returns a list of rhythm objects
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (get-rhythms rs))

    =>
    (
    RHYTHM: value: 4.000, duration: 1.000, rq: 1, is-rest: NIL,
    [...]
    RHYTHM: value: 8.000, duration: 0.500, rq: 1/2, is-rest: NIL,
    [...]
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
    [...]
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
    [...]
    RHYTHM: value: 8.000, duration: 0.500, rq: 1/2, is-rest: T,
    [...]
    RHYTHM: value: 4.000, duration: 1.000, rq: 1, is-rest: NIL,
    [...]
    RHYTHM: value: 8.000, duration: 0.500, rq: 1/2, is-rest: T,
    [...]
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
    [...]
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
    [...]
    RHYTHM: value: 5.333, duration: 0.750, rq: 3/4, is-rest: NIL,
    [...]
    RHYTHM: value: 16.000, duration: 0.250, rq: 1/4, is-rest: NIL,
    [...]
    )

    ;; Get just the rhythm labels from the same rthm-seq object
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (loop for r in (get-rhythms rs) collect (data r)))

    => ("Q" "E" S S E Q E S S E. S)

SYNOPSIS

    (defmethod get-rhythms ((rs rthm-seq))

## rthm-seq/get-time-sigs [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Return a list of time-sig objects for each of the rthm-seq-bar objects in a
     given rthm-seq object.

     One time signature is returned for each rthm-seq-bar object, even if two or
     more consecutive objects have the same time signature.

     Optionally, this method can return a list of time signatures in list form
     (e.g. ((2 4) (3 4)) etc.) rather than a list of time-sig objects.

ARGUMENTS

     - A rthm-seq object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether to return the time signatures as time-sig
       objects or a list of two-item lists. T = time-sig objects. Default = T.

RETURN VALUE

     Returns a list of time-sig objects by default. Optionally a list of time
     signatures as two-item lists can be returned instead.

EXAMPLE

    ;; Return a list of time-sig objects, one for each rthm-seq-bar object even if
    ;; consecutive rthm-seq-bar objects have the same time signature
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (get-time-sigs rs))

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

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

    TIME-SIG: num: 3, denom: 8, duration: 1.5, compound: T, midi-clocks: 24, num-beats: 1
    SCLIST: sclist-length: 2, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "0308", tag: NIL,
    data: (3 8)
    **************
    )

    ;; Return the same as a list of two-item lists instead
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (get-time-sigs rs t))

    => ((2 4) (2 4) (3 8))

SYNOPSIS

    (defmethod get-time-sigs ((rs rthm-seq) &optional as-list)

## rthm-seq/insert-bar [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Insert a rthm-seq-bar object into the given rthm-seq object and re-init
     it. If there's a pitch-seq/pitch-seq-palette given (list of numbers, or list
     of lists), splice this in at the appropriate location.

     NB: This method sets the values of the individual slots but leaves the DATA
         slot untouched (for cases in which the user might want to see where the
         new data originated from, or otherwise use the old data somehow, such
         as in a new rthm-seq object).

ARGUMENTS

     - A rthm-seq object.
     - A rthm-seq-bar object.
     - A bar number (integer). This argument is the bar number of the bar to be
       inserted, relative to the rthm-seq and 1-based; e.g., if 3, then it will
       come before the present third bar.

OPTIONAL ARGUMENTS

     - A pitch-seq object.
     - (three ignore arguments for sc-internal use only)

RETURN VALUE

     Returns T if successful.

     Drops into the debugger with an error if the specified bar-number argument
     is greater than the number of rthm-seq-bar objects in the given rthm-seq.

EXAMPLE

    ;; The method returns T when successful
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (insert-bar rs (make-rthm-seq-bar '((3 4) q. e e s s)) 3))

    => T

    ;; Create a rthm-seq object with three rthm-seq-bars and print the contents of
    ;; the NUM-BARS slot to confirm that it contains 3 objects. Insert a bar before
    ;; the third item and print the value of the NUM-BARS slot again to confirm
    ;; that there are now 4 objects. Use print-simple and get-nth-bar to confirm
    ;; that the 3rd object (with a zero-based index of 2) is indeed the one
    ;; inserted.

    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (print (num-bars rs))
      (insert-bar rs (make-rthm-seq-bar '((3 4) q. e e s s)) 3)
      (print (num-bars rs))
      (print-simple (get-nth-bar 2 rs)))

    =>
    3
    4
    (3 4): note Q., note E, note E, note S, note S,

    ;; Attempting to insert a bar with an index number greater than the number of
    ;; objects currently in the rthm-seq object drops into the debugger with an
    ;; error
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (insert-bar rs (make-rthm-seq-bar '((3 4) q. e e s s)) 11))

    =>
    rthm-seq::insert-bar: only 3 bars in rthm-seq!
       [Condition of type SIMPLE-ERROR]

    ;; Inserting a rthm-seq-bar using the optional pitch-seq argument splices the
    ;; specified value of that argument into the existing pitch-seq-palette
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (insert-bar rs (make-rthm-seq-bar '((3 4) q. e e s s)) 3 '((1 2 3 4 5)))
      (data (get-first (pitch-seq-palette rs))))

    => (1 2 3 1 1 2 3 4 5 1 2 3 4)

SYNOPSIS

    (defmethod insert-bar ((rs rthm-seq) (rsb rthm-seq-bar) bar-num
                           &optional pitch-seq ignore1 ignore2 ignore3)

## rthm-seq/make-rhythms [ Functions ]

[ Top ] [ rthm-seq ] [ Functions ]

DATE

     11 Feb 2010

DESCRIPTION

     Initialize a group of rhythms, taking advantage of rthm-seq's ability to
     add tuplet and beaming info.

ARGUMENTS

     - A list of rhythms equalling one full bar
     - The time signature of that bar as a list (e.g (2 4))

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether to divide the resulting list into sublists,
       each of which are the equivalent of one beat long. Default = NIL.

RETURN VALUE

     - A list

EXAMPLE

    ;; Apply the function and test that the result is a list
    (let ((rs (make-rhythms '(q e s s) '(2 4))))
      (listp rs))

    => T

    ;; Apply the function and see that we've created a list with 4 elements
    (let ((rs (make-rhythms '(q e s s) '(2 4))))
      (length rs))

    => 4

    ;; Apply the function with the optional split-into-beats argument set to T and
    ;; see that we now have two lists, each equalling one beat in combined
    ;; length. Print the data of the contents.
    (let ((rs (make-rhythms '(q e s s) '(2 4) t)))
      (print (length rs))
      (print (loop for b in rs collect (length b)))
      (print (loop for b in rs
                collect (loop for r in b
                           collect (data r)))))

    =>
    2
    (1 3)
    ((Q) (E S S))

    ;; Apply the function using beam indications then print the BEAM slots of the
    ;; individual rhythm objects contained in the result
    (let ((rs (make-rhythms '(q - e s s -) '(2 4))))
      (loop for r in rs collect (beam r)))

    => (NIL 1 NIL 0)

    ;; Apply the function using tuplet indications then print the BRACKET slots of
    ;; the individual rhythms objects contained in the result
    (let ((rs (make-rhythms '( { 3 te te te } - e s s -) '(2 4))))
      (loop for r in rs collect (bracket r)))

    => (((1 3)) (-1) (1) NIL NIL NIL)

SYNOPSIS

    (defun make-rhythms (bar time-sig &optional split-into-beats)

## rthm-seq/make-rthm-seq [ Functions ]

[ Top ] [ rthm-seq ] [ Functions ]

DESCRIPTION

     Creates a rthm-seq object from a list of at least bars and generally also a
     list of pitch sequences.

ARGUMENTS

     - A list with the following items:
       - A symbol that will be used as the ID of the seq
       - Another list, containing two items:
         - A list of rthm-seq-bars and
         - A list of pitch-seqs attached to the :pitch-seq-palette accessor

OPTIONAL ARGUMENTS

     keyword argument
     - :psp-inversions. T or NIL to indicate whether to also automatically
       generate and add inverted forms of the specified pitch-seq objects.
       T = generate and add. Default = NIL.

RETURN VALUE

     Returns a rthm-seq object.

EXAMPLE

    ;; Make a rthm-seq object with the ID seq1 that contains one 2/4 bar of
    ;; rhythms and one pitch sequence in the pitch-seq-palette
    (make-rthm-seq '(seq1 ((((2 4) q e s s))
                           :pitch-seq-palette ((1 2 3 4)))))

    =>
    RTHM-SEQ: num-bars: 1
              num-rhythms: 4
              num-notes: 4
              num-score-notes: 4
              num-rests: 0
              duration: 2.0
              psp-inversions: NIL
              marks: NIL
              time-sigs-tag: NIL
              handled-first-note-tie: NIL
             (for brevity's sake, slots pitch-seq-palette and bars are not printed)
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: SEQ1, tag: NIL,
    data: ((((2 4) Q E S S)) PITCH-SEQ-PALETTE (1 2 3 4))

    ;; A rthm-seq object with two bars of rhythms and two pitch-seqs in the
    ;; pitch-seq-palette. There must be as many items in each pitch-seq list as
    ;; there are rhythms in each rthm-seq-bar.
    (make-rthm-seq '(seq1 ((((2 4) q e s s)
                            ((e) q (e)))
                           :pitch-seq-palette ((1 2 3 4 5)
                                               (2 4 6 8 10)))))

    =>
    RTHM-SEQ: num-bars: 2
              num-rhythms: 7
              num-notes: 5
              num-score-notes: 5
              num-rests: 2
              duration: 4.0
              psp-inversions: NIL
              marks: NIL
              time-sigs-tag: NIL
              handled-first-note-tie: NIL
             (for brevity's sake, slots pitch-seq-palette and bars are not printed)
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: SEQ1, tag: NIL,
    data: ((((2 4) Q E S S) ((E) Q (E))) PITCH-SEQ-PALETTE
           ((1 2 3 4 5) (2 4 6 8 10)))

    ;; The pitch-seq-palette may be omitted, and time signatures may be changed
    (make-rthm-seq '(seq1 ((((2 4) q e s s)
                            ((e) q (e))
                            ((3 8) s s e. s)))))

    =>
    RTHM-SEQ: num-bars: 3
              num-rhythms: 11
              num-notes: 9
              num-score-notes: 9
              num-rests: 2
              duration: 5.5
              psp-inversions: NIL
              marks: NIL
              time-sigs-tag: NIL
              handled-first-note-tie: NIL
             (for brevity's sake, slots pitch-seq-palette and bars are not printed)
    SCLIST: sclist-length: 1, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: SEQ1, tag: NIL,
    data: ((((2 4) Q E S S) ((E) Q (E)) ((3 8) S S E. S)))

    ;;; With :psp-inversions set to T, the inverted forms of the specified
    ;;; pitch-seq are automatically generated and added
    (let ((mrs
           (make-rthm-seq '(seq1 ((((2 4) q e s s))
                                  :pitch-seq-palette ((1 2 3 4))))
                          :psp-inversions t)))
      (data (pitch-seq-palette mrs)))

    => (
    PITCH-SEQ: notes: NIL
               highest: 4
               lowest: 1
               original-data: (1 2 3 4)
               user-id: NIL
               instruments: NIL
               relative-notes: (not printed for sake of brevity)
               relative-notes-length: 25
    SCLIST: sclist-length: 4, bounds-alert: T, copy: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "rthm-seq-SEQ1-pitch-seq-palette-ps-1", tag: NIL,
    data: (1 2 3 4)
    **************

    PITCH-SEQ: notes: NIL
               highest: 4
               lowest: 1
               original-data: (4 3 2 1)
               user-id: NIL
               instruments: NIL
               relative-notes: (not printed for sake of brevity)
               relative-notes-length: 25
    SCLIST: sclist-length: 4, bounds-alert: T, copy: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "rthm-seq-SEQ1-pitch-seq-palette-ps-1-inverted", tag: NIL,
    data: (4 3 2 1)
    **************
    )

SYNOPSIS

    (defun make-rthm-seq (rs &key (psp-inversions nil))

## rthm-seq/make-rthm-seq-from-fragments [ Functions ]

[ Top ] [ rthm-seq ] [ Functions ]

DATE

     Jan-2010

DESCRIPTION

     Make a rthm-seq object from a predefined list of rhythm fragments.

     NB: No pitch-seqs can be passed as yet.

ARGUMENTS

     - The ID of the rthm-seq object to be made.
     - A list of rhythm lists (fragments) paired with key IDs. The rhythm lists
       take the form of rthm-seq-bar definitions without the time signatures.
     - A list of lists containing any combination of the key IDs from the list
       of fragments. These will be collated to create the resulting rthm-seq
       object. Each element will make up one whole bar.
     - A list of meters. These can be given either as single numerators, whereby
      the optional <default-beat> argument will then be the denominator) or
      two-item lists consisting of (num denom). There must be one meter for each
      item in the list of references, and the meters must correspond to the
      number of beats in the corresponding item from the list of references.

RETURN VALUE

     A rthm-seq object.

EXAMPLE

    (let ((frags '((1 (- s s - (e)))
                   (2 (s (s) (s) s))
                   (3 ((s) - s e -))
                   (4 (- s s (s) s -))
                   (5 ((e) - s s -))
                   (6 ((q))))))
      (make-rthm-seq-from-fragments
       'test-rs frags
       '((1 2 3) (1 4) (6 1) (5 6))
       '((3 4) (2 4) (2 4) (2 4))))

    =>
    RTHM-SEQ: num-bars: 4
              num-rhythms: 25
              num-notes: 15
              num-score-notes: 15
              num-rests: 10
              duration: 9.0
              psp-inversions: NIL
              marks: NIL
              time-sigs-tag: NIL
              handled-first-note-tie: NIL
             (for brevity's sake, slots pitch-seq-palette and bars are not printed)
    SCLIST: sclist-length: 1, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: TEST-RS, tag: NIL,
    data: ((((3 4) - S S - (E) S (S) (S) S (S) - S E -)
            ((2 4) - S S - (E) - S S (S) S -) ((Q) - S S - (E)) ((E) - S S - (Q))))

SYNOPSIS

    (defun make-rthm-seq-from-fragments (id fragments references meters
                                         &optional (default-beat 4))

## rthm-seq/make-rthm-seq-from-unit-multipliers [ Functions ]

[ Top ] [ rthm-seq ] [ Functions ]

DESCRIPTION

     Given a rhythmic unit, e.g. 32, a list of multipliers (e.g. '(7 9 16)),
     and a time signature (e.g. '(4 4)), return a rthm-seq object made up of
     bars whose rhythms are multiples of the specified unit by the numbers in
     the multipliers list.

     At this point the unit should be a whole number divisor of the beat in the
     time signature, i.e. quintuple eighths won't work in 4/4.

     NB: Setting the auto-beam keyword argument to T can result in errors if
         creating durations longer than 1 beat, as auto-beam will call
         get-beats. :auto-beam is therefore set to NIL by default.

ARGUMENTS

     - A rhythmic duration unit.
     - A list of multipliers.
     - A time signature.

OPTIONAL ARGUMENTS

     keyword arguments:
     - :tag. A symbol that is another name, description etc. for the given
       object. The tag may be used for identification but not for searching
       purposes. Default = NIL.
     - :auto-beam.  T or NIL. When T, the function will attempt to automatically
       set beaming indicators among the resulting rthm-seq-bar objects. This can
       result in errors if the resulting rhythms have a duration of more than 1
       beat. Default = NIL.
     - :id. A symbol that will be the ID of the given object.
       Default = "from-multipliers".
     - :tuplet. An integer or NIL. If an integer, the function will
       automatically place tuplet brackets of that value above beats consisting
       of tuplet rhythms. NB: This function will only place the same value over
       all tuplets.  Default = NIL.

RETURN VALUE

     Returns a rthm-seq object.

EXAMPLE

    ;; Make a rthm-seq object using the rhythmic unit of a 16th-note, rhythms that
    ;; are 4, 2, 2, 4 and 4 16th-notes long, and a time signature of 2/4; then
    ;; print-simple the object returned to see the results.
    (let ((rs (make-rthm-seq-from-unit-multipliers 's '(4 2 2 4 4) '(2 4))))
      (print-simple rs))

    =>
    rthm-seq from-multipliers
    (2 4): note Q, note E, note E,
    (2 4): note Q, note Q,

    ;; Make a rthm-seq object using the rhythmic unit of a 32nd note, combinations
    ;; of irregular duration, and a time signature of 4/4; then print-simple the
    ;; returned object to see the results.
    (let ((rs (make-rthm-seq-from-unit-multipliers 32 '(7 9 16) '(4 4))))
      (print-simple rs))

    =>
    rthm-seq from-multipliers
    (4 4): note E.., note 32, note Q, note H

    ;; The print-simple output of the above example disregards the ties. We can
    ;; check to make sure that there are only three attacked rhythms in the result
    ;; by reading the values of the IS-TIED-FROM and IS-TIED-TO slots, which show
    ;; that the 32 is tied to the Q
    (let ((rs (make-rthm-seq-from-unit-multipliers 32 '(7 9 16) '(4 4))))
      (loop for b in (bars rs)
           collect (loop for r in (rhythms b) collect (is-tied-from r))
           collect (loop for r in (rhythms b) collect (is-tied-to r))))

    => ((NIL T NIL NIL) (NIL NIL T NIL))

    ;;; Using with a tuplet rhythm ('te) and setting the :tuplet option to 3 so
    ;;; that triplet brackets are automatically placed.
    (let ((rs (make-rthm-seq-from-unit-multipliers 'te '(7 9 16) '(4 4)
                                                   :tuplet 3)))
      (loop for b in (bars rs)
         collect (loop for r in (rhythms b) collect (bracket r))))

    => ((NIL NIL ((1 3)) (1) NIL) (NIL ((1 3)) (1) NIL NIL)
        (NIL NIL ((1 3)) (1) NIL))

SYNOPSIS

    (defun make-rthm-seq-from-unit-multipliers (unit multipliers time-sig
                                                &key
                                                ;; a number for brackets over
                                                ;; each beat.
                                                (tuplet nil)
                                                (tag nil)
                                                (auto-beam nil) ; see above
                                                (id "from-multipliers"))

## rthm-seq/scale [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Scale the durations of the rhythm objects in a given rthm-seq object by the
     specified factor.

     NB: As is evident in the examples below, this method does not replace the
         original data in the rthm-seq object's DATA slot.

ARGUMENTS

     - A rthm-seq object.
     - A real number that is the scaling factor.

RETURN VALUE

     Returns a rthm-seq object.

EXAMPLE

    ;; The method returns a rthm-seq object.
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (scale rs 3))

    =>
    RTHM-SEQ: num-bars: 3
              num-rhythms: 11
              num-notes: 8
              num-score-notes: 9
              num-rests: 2
              duration: 16.5
              psp-inversions: NIL
              marks: NIL
              time-sigs-tag: NIL
              handled-first-note-tie: NIL
             (for brevity's sake, slots pitch-seq-palette and bars are not printed)
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: NIL, tag: NIL,
    data: ((((2 4) Q+E S S) ((E) Q (E)) ((3 8) S S E. S)) PITCH-SEQ-PALETTE
           ((1 2 3 1 1 2 3 4)))

    ;; Create a rthm-seq object, scale the durations by 3 times using the scale
    ;; method, and print-simple the corresponding slots to see the results
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 1 1 2 3 4))))))
      (print-simple (scale rs 3)))

    =>
    rthm-seq NIL
    (6 4): note H., note Q., note E., note E.,
    (6 4): rest Q., note H., rest Q.,
    (9 8): note E., note E., note E., note E.,

SYNOPSIS

    (defmethod scale ((rs rthm-seq) scaler
                      &optional ignore1 ignore2 ignore3)

## rthm-seq/set-nth-attack [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Sets the value of the nth rhythm object of a given rthm-seq object that
     needs an attack; i.e., not a rest and not a tied note.

     NB: This method does not check to ensure that the resulting rthm-seq bars
         contain the right number of beats.

ARGUMENTS

     - A zero-based index number for the attacked note to change.
     - An event.
     - A rthm-seq object.

OPTIONAL ARGUMENTS

     - T or NIL indicating whether to print an error message if the given index
       is greater than the number of attacks (minus 1) in the rthm-seq object
       (default = T).

RETURN VALUE

     - An event object.

EXAMPLE

    ;; The method returns an event object
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (set-nth-attack 2 (make-event 'c4 'q) rs))

    =>
    EVENT: start-time: NIL, end-time: NIL,
    [...]
           pitch-or-chord:
    PITCH: frequency: 261.6255569458008, midi-note: 60, midi-channel: 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.000, duration: 1.000, rq: 1, is-rest: NIL,
    [...]
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: Q, tag: NIL,
    data: Q

    ;; Create a rthm-seq object, apply set-nth-attack, print the corresponding
    ;; slots to see the change
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (set-nth-attack 2 (make-event 'c4 'q) rs)
      (print-simple rs))

    =>
    rthm-seq NIL
    (2 4): note Q, note E, note S, C4 Q,
    (2 4): rest E, note Q, rest E,
    (3 8): note S, note S, note E., note S,

    ;; By default, the method drops into the debugger with an error when the
    ;; specified index is greater than the number of items in the given rthm-seq
    ;; object.
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (set-nth-attack 11 (make-event 'c4 'q) rs))

    =>
    rthm-seq::set-nth-attack: Can't set attack 11 as only 8 notes in the rthm-seq
       [Condition of type SIMPLE-ERROR]

    ;; This error can be suppressed, simply returning NIL, by setting the optional
    ;; argument to NIL.
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (set-nth-attack 11 (make-event 'c4 'q) rs nil))

    => NIL

SYNOPSIS

    (defmethod set-nth-attack (index (e event) (rs rthm-seq)
                               &optional (error t))

## rthm-seq/set-nth-bar [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DESCRIPTION

     Change the contents of the nth rthm-seq-bar object in the given rthm-seq.

ARGUMENTS

     - A zero-based index number for the bar to change.
     - A rthm-seq-bar object containing the new bar.
     - A rthm-seq object.

RETURN VALUE

     A rthm-seq-bar object.

EXAMPLE

    ;; The method returns what is passed to it as the new-bar argument (generally a
    ;; rthm-seq-bar object.
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (set-nth-bar 1 (make-rthm-seq-bar '((2 4) (s) e (s) q)) rs))

    =>
    RTHM-SEQ-BAR: time-sig: 0 (2 4), time-sig-given: T, bar-num: -1,
    [...]
    data: ((2 4) (S) E (S) Q)

    ;; Create a rthm-seq object, change the second bar (index 1) using the
    ;; set-nth-bar method, and print the contents of the rhythms data to see the
    ;; changes.
    (let ((rs (make-rthm-seq '((((2 4) q+e s s)
                                ((e) q (e))
                                ((3 8) s s e. s))
                               :pitch-seq-palette ((1 2 3 4 1 1 2 3))))))
      (set-nth-bar 1 (make-rthm-seq-bar '((2 4) (s) e (s) q)) rs)
      (print-simple rs))

    =>
    rthm-seq NIL
    (2 4): note Q, note E, note S, note S,
    (2 4): rest S, note E, rest S, note Q,
    (3 8): note S, note S, note E., note S,

SYNOPSIS

    (defmethod set-nth-bar (index new-bar (rs rthm-seq))

## rthm-seq/split [ Methods ]

[ Top ] [ rthm-seq ] [ Methods ]

DATE

     27 Jan 2011

DESCRIPTION

     Splits the rthm-seq-bar objects of a given rthm-seq object into multiple
     smaller rthm-seq-bar objects, creating a new rthm-seq object with a greater
     number of bars than the original. This will only work if the given
     rthm-seq-bar objects can be split into whole beats; e.g., a 4/4 bar will
     not be split into 5/8 + 3/8.

     The keyword arguments :min-beats and :max-beats serve as guidelines rather
     than strict cut-offs. In some cases, the method may only be able to
     effectively split the given rthm-seq-bar by dividing it into segments that
     slightly exceed the length stipulated by these arguments (see example
     below).

     Depending on the min-beats/max-beats arguments stipulated by the user or
     the rhythmic structure of the given rthm-seq-bar objects, the given
     rthm-seq-bar or rthm-seq objects may not be splittable, in which case NIL
     is returned. If the keyword argument :warn is set to T, a warning will be
     also printed in such cases.

     NB: This method sets the values of the individual slots but leaves the DATA
     slot untouched (for cases in which the user might want to see where the new
     data originated from, or otherwise use the old data somehow, such as in a
     new rthm-seq object).

ARGUMENTS

     - A rthm-seq object.

OPTIONAL ARGUMENTS

     keyword arguments
     - :min-beats. This argument takes an integer value to indicate the minimum
       number of beats in any of the new rthm-seq-bar objects created. This
       serves as a guideline only and may occasionally be exceeded in value by
       the method. Default value = 2.
     - :max-beats. This argument takes an integer value to indicate the maximum
       number of beats in any of the new rthm-seq-bar objects created. This
       serves as a guideline only and may occasionally be exceeded in value by
       the method. Default value = 5.
     - :warn. Indicates whether to print a warning if the rthm-seq-bar object is
       unsplittable. Value T = print a warning. Defaults to NIL.

RETURN VALUE

     A rthm-seq object.

EXAMPLE

    ;; The method returns a new rthm-seq object
    (let ((rs (make-rthm-seq '((((4 4) q e s s (e) e e (e))
                                ((3 4) s s e s e s e. s)
                                ((5 4) h q. e e s s))
                               :pitch-seq-palette ((1 2 3 4 5 6 1 2 3 4 5 6 7 8 1 2
                                                    3 4 5 6))))))
      (split rs))

    =>

    RTHM-SEQ: num-bars: 5
              num-rhythms: 22
              num-notes: 20
              num-score-notes: 20
              num-rests: 2
              duration: 12.0
              psp-inversions: NIL
              marks: NIL
              time-sigs-tag: NIL
              handled-first-note-tie: NIL
             (for brevity's sake, slots pitch-seq-palette and bars are not printed)
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: NIL, tag: NIL,
    data: ((((4 4) Q E S S (E) E E (E)) ((3 4) S S E S E S E. S)
            ((5 4) H Q. E E S S))
           PITCH-SEQ-PALETTE ((1 2 3 4 5 6 1 2 3 4 5 6 7 8 1 2 3 4 5 6)))

    ;; Without setting the :min-beats and :max-beats arguments, the following
    ;; rthm-seq object is broken down from 3 to 5 rthm-seq-bar objects
    (let* ((rs (make-rthm-seq '((((4 4) q e s s (e) e e (e))
                                 ((3 4) s s e s e s e. s)
                                 ((5 4) h q. e e s s))
                                :pitch-seq-palette ((1 2 3 4 5 6 1 2 3 4 5 6 7 8 1 2
                                                     3 4 5 6)))))
           (rssplt (split rs)))
      (print-simple rssplt))

    =>
    rthm-seq NIL
    (2 4): note Q, note E, note S, note S,
    (2 4): rest E, note E, note E, rest E,
    (3 4): note S, note S, note E, note S, note E, note S, note E., note S,
    (2 4): note H,
    (3 4): note Q., note E, note E, note S, note S,

    ;; Setting :min-beats to 4 affects the resulting subdivisions to larger bars
    (let* ((rs (make-rthm-seq '((((4 4) q e s s (e) e e (e))
                                 ((3 4) s s e s e s e. s)
                                 ((5 4) h q. e e s s))
                                :pitch-seq-palette ((1 2 3 4 5 6 1 2 3 4 5 6 7 8 1 2
                                                     3 4 5 6)))))
           (rssplt (split rs :min-beats 4)))
      (print-simple rssplt))

    =>
    rthm-seq NIL
    (4 4): note Q, note E, note S, note S, rest E, note E, note E, rest E,
    (3 4): note S, note S, note E, note S, note E, note S, note E., note S,
    (5 4): note H, note Q., note E, note E, note S, note S,

    ;; Even though :max-beats is set to 2, an occasional 3/4 bar is constructed
    (let* ((rs (make-rthm-seq '((((4 4) q e s s (e) e e (e))
                                 ((3 4) s s e s e s e. s)
                                 ((5 4) h q. e e s s))
                                :pitch-seq-palette ((1 2 3 4 5 6 1 2 3 4 5 6 7 8 1 2
                                                     3 4 5 6)))))
           (rssplt (split rs :max-beats 2)))
      (print-simple rssplt))

    =>
    rthm-seq NIL
    (2 4): note Q, note E, note S, note S,
    (2 4): rest E, note E, note E, rest E,
    (3 4): note S, note S, note E, note S, note E, note S, note E., note S,
    (2 4): note H,
    (3 4): note Q., note E, note E, note S, note S,

SYNOPSIS

    (defmethod split ((rs rthm-seq)
                      &key (min-beats 2) (max-beats 5) warn (clone t))

## sclist/rthm-seq [ Classes ]

[ Top ] [ sclist ] [ Classes ]

NAME

     rthm-seq

     File:             rthm-seq.lsp

     Class Hierarchy:  named-object -> linked-named-object -> sclist -> rthm-seq

     Version:          1.0.2

     Project:          slippery chicken (algorithmic composition)

     Purpose:          Implementation of the rthm-seq class which holds the bars
                       and rhythms of a sequence (multiple bars).  This will
                       generally be stored in a rthm-seq-palette and referenced
                       later in the rthm-seq-map.

                       The data used to create such an object will look
                       something like:

                       (rthm1 ((((2 4) q (q))
                                 (s x 4 (e) e)
                                 ((3 8) (e) e (e)))
                               :pitch-seq-palette '((psp1 (1 2 1 2 3 2 1))
                                                    (psp2 (3 2 4 6 1 5 7))
                                                    (psp3 (2 3 4 1 3 4 5)))))

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

     Creation date:    14th February 2001

     $$ Last modified: 11:19:37 Sat Apr 20 2013 BST

     SVN ID: $Id: rthm-seq.lsp 3674 2013-06-10 11:07:52Z medward2 $