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

## rthm-seq-map/add-repeats [ Methods ]

[ Top ] [ rthm-seq-map ] [ Methods ]

DATE

     30-Dec-2010

DESCRIPTION

     Generate repeating sequences at given cycle points using recurring-event
     data. This process modifies the number of beats.

ARGUMENTS

     - A rthm-seq-map object.
     - A list of two-item lists of integers that determine the cycle
       pattern. This list will have the format of the recurring-event class's
       DATA slot (see recurring-event.lsp).
     - A list of two-item lists of integers that determine the number of repeats
       made (or references into the :repeats list). This list is also processed
       cyclically (i.e. the recurring-event class's RETURN-DATA-CYCLE slot).

OPTIONAL ARGUMENTS

     keyword arguments:
     - :section. The section map reference. Default = 1.
     - :repeats-indices. A list of the number of repeat bars returned by the
        cycle data (i.e. recurring-event class's RETURN-DATA slot). Generally
        this will remain NIL and the number of repeats will be expressed
        directly in the third argument, but it could be useful to use references
        into this list there instead, since the recurring-event class already
        makes this possible. Default = NIL.
     - :start. An integer that is the number of the bar/rthm-seq where the
       process is to begin. Default = 1.
     - :end. An integer that is the number of the bar/rthm-seq where the process
       is to end. NIL = process all bars/rthm-seqs. Default = NIL.
     - :print. T or NIL to indicate whether to print the rthm-seq ID and the
       number repetitions to the listener. T = print. Default = NIL.

RETURN VALUE

     An integer that is the number of bars added.

EXAMPLE

    ;;; Straightforward usage, additionally printing the DATA slot before and after
    ;;; applying the method
    (let ((mrsm
           (make-rthm-seq-map
            'rsm-test
            '((1 ((vn (1 2 3 2 1 3 1 3 2 3 1 2 1 3 1 3 2 1)))))
            :palette (make-rsp
                      'rs-pal
                      '((1 ((((2 4) q e s s))))
                        (2 ((((2 4) e s s q))))
                        (3 ((((2 4) s s q e)))))))))
      (print (get-data-data '(1 vn) mrsm))
      (add-repeats mrsm '((1 6) (2 6)) '((11 6) (23 3)))
      (print (get-data-data '(1 vn) mrsm)))

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

    ;;; Using the :start, :end, and :print arguments
    (let ((mrsm
           (make-rthm-seq-map
            'rsm-test
            '((1 ((vn (1 2 3 2 1 3 1 3 2 3 1 2 1 3 1 3 2 1)))))
            :palette (make-rsp
                      'rs-pal
                      '((1 ((((2 4) q e s s))))
                        (2 ((((2 4) e s s q))))
                        (3 ((((2 4) s s q e)))))))))
      (print (get-data-data '(1 vn) mrsm))
      (add-repeats mrsm '((1 6) (2 6)) '((11 6) (23 3))
                   :start 3
                   :end 11
                   :print t)
      (print (get-data-data '(1 vn) mrsm)))

    =>
    (1 2 3 2 1 3 1 3 2 3 1 2 1 3 1 3 2 1)
    2 x 11
    1 x 11
    3 x 11
    1 x 11
    3 x 11
    2 x 11
    1 x 23
    (1 2 3 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 1
     1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 3 1 1 1 1
     1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 3 1 3 2 1)

SYNOPSIS

    (defmethod add-repeats ((rsm rthm-seq-map) repeat-every repeats &key
                            (section 1) repeats-indices (start 1) end print)

## rthm-seq-map/add-repeats-simple [ Methods ]

[ Top ] [ rthm-seq-map ] [ Methods ]

DESCRIPTION

     Add repeats of a specified rthm-seq within the given rthm-seq-map object a
     specified number of times.

ARGUMENTS

     - A rthm-seq-map object.
     - An integer that is the number of the rthm-seq (position within the
       rthm-seq-map) to be repeated.
     - An integer that is the number of times that rthm-seq is to be repeated.

OPTIONAL ARGUMENTS

     keyword arguments:
     - :section. An integer that is the ID of the section in which the repeat
       operation is to be performed.
     - :print. T or NIL to indicate whether to print the rthm-seq ID and the
       number repetitions to the listener. T = print. Default = NIL.

RETURN VALUE

     Always returns T.

EXAMPLE

    ;;; Print the DATA of the given rthm-seq-map, apply the method, and print again
    ;;; to see the difference.
    (let ((mrsm
           (make-rthm-seq-map
            'rsm-test
            '((1 ((vn (1 2 3 2 1 3 1 3 2 3 1 2 1 3 1 3 2 1)))))
            :palette (make-rsp
                      'rs-pal
                      '((1 ((((2 4) q e s s))))
                        (2 ((((2 4) e s s q))))
                        (3 ((((2 4) s s q e)))))))))
      (print (get-data-data '(1 vn) mrsm))
      (add-repeats-simple mrsm 3 13)
      (print (get-data-data '(1 vn) mrsm)))

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

SYNOPSIS

    (defmethod add-repeats-simple ((rsm rthm-seq-map) start-seq repeats &key
                                   (section 1) print)

## rthm-seq-map/check-num-sequences [ Functions ]

[ Top ] [ rthm-seq-map ] [ Functions ]

DESCRIPTION

     Check to ensure that each player in each section of the given rthm-seq-map
     object has the same number of references as every other instrument. If not,
     drop into the debugger with an error.

     NB: This function is called automatically every time make-rthm-seq-map is
         called so it shouldn't generally be necessary for the user to call this
         method.  However, if the rthm-seq-map is changed somehow, it might be a
         good idea to recheck.

ARGUMENTS

     - A rthm-seq-map object.

RETURN VALUE

     Returns T if all players have the same number of references in each
     section, otherwise drops into the debugger with an error.

EXAMPLE

    ;;; Passes the test:
    (let ((rsmt (make-rthm-seq-map
                 'rsm-test
                 '((sec1 ((vn (rs1a rs3a rs2a))
                          (va (rs1b rs3b rs2b))
                          (vc (rs1a rs3b rs2a))))
                   (sec2 ((vn (rs1a rs2a rs1a))
                          (va (rs1a rs2a rs1b))
                          (vc (rs1a rs2b rs1a))))
                   (sec3 ((vn (rs1a rs1a rs3a))
                          (va (rs1a rs1a rs3b))
                          (vc (rs1a rs1b rs3a))))
                   (sec4 ((vn (rs1a rs1a rs1a))
                          (va (rs1a rs1a rs1b))
                          (vc (rs1a rs1b rs1a))))))))
      (check-num-sequences rsmt))

    => T

    ;;; Doesn't pass the test; drops into debugger with an error.
    (let ((rsmt (make-rthm-seq-map
                 'rsm-test
                 '((sec1 ((vn (rs1a rs3a rs2a))
                          (va (rs1b rs3b))
                          (vc (rs1a rs3b rs2a))))
                   (sec2 ((vn (rs1a))
                          (va (rs1a rs2a rs1b))
                          (vc (rs1a rs2b rs1a))))
                   (sec3 ((vn (rs1a rs3a))
                          (va (rs1a))
                          (vc (rs1a rs1b rs3a))))
                   (sec4 ((vn (rs1a))
                          (va (rs1a rs1a rs1b))
                          (vc (rs1a rs1a))))))))
      (check-num-sequences rsmt))

    =>
    rthm-seq-map::check-num-sequences: In rthm-seq-map RSM-TEST-5, instrument VA:
    Each instrument must have the same number of sequences for any given section:
    (RS1B RS3B)
       [Condition of type SIMPLE-ERROR]

SYNOPSIS

    (defun check-num-sequences (rsm)

## rthm-seq-map/get-map-refs [ Methods ]

[ Top ] [ rthm-seq-map ] [ Methods ]

DATE

     29-Dec-2010

DESCRIPTION

     Return the list of rthm-seq-palette references for the given player and
     section.

ARGUMENTS

     - A rthm-seq-map object.
     - The ID of the section in which the references are sought.
     - The ID of the player for whom the references are sought.

RETURN VALUE

     A list of references (each of which might also  be a list).

EXAMPLE

    (let ((rsmt (make-rthm-seq-map
                 'rsm-test-5
                 '((sec1 ((vn (rs1 rs3 rs2))
                          (va (rs2 rs3 rs1))
                          (vc (rs3 rs1 rs2))))
                   (sec2 ((vn (rs1 rs2 rs1))
                          (va (rs2 rs1 rs3))
                          (vc (rs1 rs3 rs3))))
                   (sec3 ((vn (rs1 rs1 rs3))
                          (va (rs1 rs3 rs2))
                          (vc (rs3 rs2 rs3)))))
                 :palette (make-rsp
                           'rs-pal
                           '((rs1 ((((2 4) q e s s))))
                             (rs2 ((((2 4) e s s q))))
                             (rs3 ((((2 4) s s q e)))))))))
      (get-map-refs rsmt 'sec3 'vc))

    => (RS3 RS2 RS3)

SYNOPSIS

    (defmethod get-map-refs ((rsm rthm-seq-map) section player)

## rthm-seq-map/get-time-sig-ral [ Methods ]

[ Top ] [ rthm-seq-map ] [ Methods ]

DESCRIPTION

     Collate the IDs of all rthm-seq objects in a given rthm-seq-map into groups
     based on identical time signatures and return this as a
     recursive-assoc-list object that has the same structure of the map.

     Instead of having the list of rthm-seq references for each
     section/instrument, the method returns an assoc-list whose keys are the
     time-sig tags, with the corresponding data being circular-sclists of
     rthm-seq IDs.

     The result is a recursive-assoc-list for each instrument/section that can
     be queried to find the rthm-seq refs of all rthm-seqs that share the same
     bar/time-sig structure; e.g., all those that have a 2/4 bar followed by a
     3/4 bar etc.

ARGUMENTS

     - A rthm-seq-map object.
     - A rthm-seq-palette object.

RETURN VALUE

     A recursive-assoc-list object.

EXAMPLE

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

    =>
    RECURSIVE-ASSOC-LIST: recurse-simple-data: T
                          num-data: 1
                          linked: T
                          full-ref: (1)
    ASSOC-LIST: warn-not-found T
    CIRCULAR-SCLIST: current 0
    SCLIST: sclist-length: 1, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "sub-ral-of-+MINI+-RTHM-SEQ-MAP", tag: NIL,
    data: (
    ASSOC-LIST: warn-not-found T
    CIRCULAR-SCLIST: current 0
    SCLIST: sclist-length: 2, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: (1 SAX), next: NIL
    NAMED-OBJECT: id: SAX, tag: NIL,
    data: (
    CIRCULAR-SCLIST: current 0
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "0404-0204", tag: NIL,
    data: (4 6 1)
    **************

    CIRCULAR-SCLIST: current 0
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: "0404", tag: NIL,
    data: (5 3 2)
    **************
    )
    **************
    )
    **************

SYNOPSIS

    (defmethod get-time-sig-ral ((rsm rthm-seq-map) (rsp rthm-seq-palette))

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

[ Top ] [ rthm-seq-map ] [ Functions ]

DESCRIPTION

     Make a rthm-seq-map object.

ARGUMENTS

     - The ID of the rthm-seq-map object to be made.
     - A list of nested lists, generally taking the form
       '((section1 ((player1 (rthm-seq ids))
                    (player2 (rthm-seq ids))
                    (etc... (etc...))))
         (section2 ((player1 (rthm-seq ids))
                    (player2 (rthm-seq ids))
                    (etc...)))
         (etc...))

OPTIONAL ARGUMENTS

     keyword arguments:
     - :palette. A palette object or NIL. If a palette object is specified or
       defined here, it will be automatically bound to the given rthm-seq-map
       object. Default = NIL.
     - :warn-not-found. T or NIL to indicate whether a warning is printed when
       an index which doesn't exist is used for look-up.
       T = warn. Default = NIL.
     - :replacements. A list of lists in the format
       '(((1 2 vla) 3 20b) ((2 3 vln) 4 16a)) that indicate changes to
       individual elements of lists within the given rthm-seq-map object. (Often
       rthm-seq-map data is generated algorithmically but individual elements of
       the lists need to be changed.)  Each such list indicates a change, the
       first element of the list being the reference into the rthm-seq-map (the
       vla player of section 1, subsection 2 in the first example here), the
       second element is the nth of the data list for this key to change, and
       the third is the new data. Default = NIL.
     - :recurse-simple-data. T or NIL to indicate whether to recursively
       instantiate a recursive-assoc-list in place of data that appears to be a
       simple assoc-list (i.e. a 2-element list). If NIL, the data of 2-element
       lists whose second element is a number or a symbol will be ignored,
       therefore remaining as a list. For example, this data would normally
       result in a recursive call: (y ((2 23) (7 28) (18 2))).
       T = recurse. Default = T.

RETURN VALUE

     A rthm-seq-map object.

EXAMPLE

    ;;; Straightforward usage
    (make-rthm-seq-map 'rsm-test
                        '((1 ((vn (1 2 3 4))
                              (va (2 3 4 1))
                              (vc (3 4 1 2))))
                          (2 ((vn (4 5 6))
                              (va (5 6 4))
                              (vc (6 4 5))))
                          (3 ((vn (7 8 9 1 2))
                              (va (8 9 1 2 7))
                              (vc (9 1 2 7 8))))))

    =>

    RTHM-SEQ-MAP: num-players: 3
                  players: (VA VC VN)
    SC-MAP: palette id: NIL
    RECURSIVE-ASSOC-LIST: recurse-simple-data: T
                          num-data: 9
                          linked: NIL
                          full-ref: NIL
    ASSOC-LIST: warn-not-found NIL
    CIRCULAR-SCLIST: current 0
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: RSM-TEST, tag: NIL,
    data: (
    [...]

    ;;; An example using the :replacements argument and binding directly to a
    ;;; specified rthm-seq-palette object.
    (make-rthm-seq-map 'rsm-test
                       '((1 ((vn (1 2 3 4))
                             (va (2 3 4 1))
                             (vc (3 4 1 2))))
                         (2 ((vn (4 5 6))
                             (va (5 6 4))
                             (vc (6 4 5))))
                         (3 ((vn (7 8 9 1 2))
                             (va (8 9 1 2 7))
                             (vc (9 1 2 7 8)))))
                       :palette (make-rsp
                                 'rs-pal
                                 '((rs1 ((((2 4) q e s s))))
                                   (rs2 ((((2 4) e s s q))))
                                   (rs3 ((((2 4) s s q e))))))
                       :replacements '(((1 vn) 2 7)
                                       ((2 va) 1 1)
                                       ((3 vc) 1 0)))

    =>
    RTHM-SEQ-MAP: num-players: 3
                  players: (VA VC VN)
    SC-MAP: palette id: RS-PAL
    RECURSIVE-ASSOC-LIST: recurse-simple-data: T
                          num-data: 9
                          linked: NIL
                          full-ref: NIL
    ASSOC-LIST: warn-not-found NIL
    CIRCULAR-SCLIST: current 0
    SCLIST: sclist-length: 3, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: RSM-TEST, tag: NIL,
    data: (
    [...]

SYNOPSIS

    (defun make-rthm-seq-map (id rsm &key (palette nil) (warn-not-found nil)
                                          (replacements nil)
                                          (recurse-simple-data t))

## rthm-seq-map/rsm-count-notes [ Functions ]

[ Top ] [ rthm-seq-map ] [ Functions ]

DESCRIPTION

     Returns the number of notes in the given rthm-seq-map object for the
     specified player and rthm-seq-palette.

ARGUMENTS

     - A rthm-seq-map object.
     - The ID of the player whose notes are to be counted.
     - The rthm-seq-palette object whose rthm-seq object IDs are referred to by
       the given rthm-seq-map object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether to count just the number of notes that need
       new events (i.e., not counting tied notes; also not counting chords,
       since chords need only one event) or the total number of notes in that
       player's part in the score. T = count just attacked notes. Default = T.

RETURN VALUE

     Returns an integer that is the number of notes counted.

EXAMPLE

    (let ((rsmt (make-rthm-seq-map
                 'rsm-test
                 '((sec1 ((vn (rs1 rs3 rs2))
                          (va (rs2 rs3 rs1))
                          (vc (rs3 rs1 rs2))))
                   (sec2 ((vn (rs1 rs2 rs1))
                          (va (rs2 rs1 rs3))
                          (vc (rs1 rs3 rs3))))
                   (sec3 ((vn (rs1 rs1 rs3))
                          (va (rs1 rs3 rs2))
                          (vc (rs3 rs2 rs3)))))))
          (rspt (make-rsp
                 'rs-pal
                 '((rs1 ((((2 4) q (e) s s))))
                   (rs2 ((((2 4) e +s (s) q))))
                   (rs3 ((((2 4) (s) s +q e))))))))
      (print (rsm-count-notes rsmt 'vn rspt))
      (print (rsm-count-notes rsmt 'va rspt nil)))

    =>
    23
    27

SYNOPSIS

    (defun rsm-count-notes (rthm-seq-map player palette &optional (just-attacks t))

## rthm-seq-map/set-map-refs [ Methods ]

[ Top ] [ rthm-seq-map ] [ Methods ]

DATE

     30-Dec-2010

DESCRIPTION

     Change the reference IDs of the specified rthm-seq objects in the given
     rthm-seq-map object.

ARGUMENTS

     - A rthm-seq-map object.
     - The ID of the section in which references are to be set.
     - The ID of the player for whom the references are to be set.
     - A list of the new rthm-seq IDs (references)

RETURN VALUE

     Returns the modified named object whose ID is the specified player.

EXAMPLE

    (let ((rsmt (make-rthm-seq-map
                 'rsm-test-5
                 '((sec1 ((vn (rs1 rs3 rs2))
                          (va (rs2 rs3 rs1))
                          (vc (rs3 rs1 rs2))))
                   (sec2 ((vn (rs1 rs2 rs1))
                          (va (rs2 rs1 rs3))
                          (vc (rs1 rs3 rs3))))
                   (sec3 ((vn (rs1 rs1 rs3))
                          (va (rs1 rs3 rs2))
                          (vc (rs3 rs2 rs3)))))
                 :palette (make-rsp
                           'rs-pal
                           '((rs1 ((((2 4) q e s s))))
                             (rs2 ((((2 4) e s s q))))
                             (rs3 ((((2 4) s s q e)))))))))
      (set-map-refs rsmt 'sec2 'vc '(rs2 rs3 rs2)))

    =>
    NAMED-OBJECT: id: VC, tag: NIL,
    data: (RS2 RS3 RS2)

SYNOPSIS

    (defmethod set-map-refs ((rsm rthm-seq-map) section player new-refs)

## sc-map/rthm-seq-map [ Classes ]

[ Top ] [ sc-map ] [ Classes ]

NAME

     rthm-seq-map

     File:             rthm-seq-map.lsp

     Class Hierarchy:  named-object -> linked-named-object -> sclist ->
                       circular-sclist -> assoc-list -> recursive-assoc-list ->
                       sc-map -> rthm-seq-map

     Version:          1.0.1

     Project:          slippery chicken (algorithmic composition)

     Purpose:          Implementation of the rthm-seq-map class which maps
                       references to rthm-seq objects for the players in the
                       piece.  Extensions to the sc-map superclass are the
                       collection of all the players in the piece and a
                       check to make sure that each list each instrument has the
                       same number of rthm-seq references for each section.

                       Instances of this class must declare sections and
                       players so if the piece is in one section, give it
                       the label 1 or whatever, e.g.

                       '((1
                          ((vln (2 20 1 9 10 22 16 25 6 14 21 17 4 9 13 2))
                           (vla (2 23 3 7 13 22 19 3 8 12 23 14 2 10 15 4))
                           (vc (2 21 3 12 11 22 16 1 8 17 23 20 24 9 12 2)))))

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

     Creation date:    July 28th 2001

     $$ Last modified: 15:51:50 Fri Apr 19 2013 BST

     SVN ID: $Id: rthm-seq-map.lsp 3465 2013-04-19 14:55:13Z medward2 $