./../../src/pitch-seq.lsp

## pitch-seq/get-notes [ Methods ]

[ Top ] [ pitch-seq ] [ Methods ]

DESCRIPTION

     This gets notes from the sets, limiting the notes used to the range of the
     instrument and any other ranges defined in the slippery-chicken class. If
     either the instrument or set are missing it just gets the relative pitches
     we use to display a pitch sequence.

     limit-high and limit-low are pitch objects. They are extra range definers
     that are given to the slippery-chicken object to control the pitch curve of
     an instrument over the duration of the whole piece. They always refer to
     sounding pitches.

     The order of operations for selecting pitches are as follows:

     1) Limit the set object to the instrument's range.

     2) Remove the notes that have already been selected for other instruments.
        This is where the slippery-chicken slot :instrument-hierarchy plays an
        important role.  This can be skipped if the <avoid-used-notes> argument
        is nil.

     3) If there is a subset with the same ID as the ID slot for the
        player, use only those pitches common to that subset and those in
        step 2. If not, try again using the subset-id of the instrument.

     4) If the ratio between the number of pitches now available and the number
        of different numbers in the pitch-seq is less than the slippery-chicken
        slot pitch-seq-index-scaler-min*, add notes from those used by other
        instruments until there are enough; the lowest number in the pitch-seq
        will now select the lowest pitch in the set that is in the instrument's
        range.

        If however there are enough pitches without adding pitches already used
        by other instruments, then where in the available pitches the lowest
        number of the pitch-seq will be placed depends on whether the
        prefers-notes slot of the instrument has been set to be high or low. If
        high, then the highest number in the pitch-seq will result in the
        highest pitch in the available pitches that is in the instrument's
        range. If low, then the lowest number in the pitch-seq will result in
        the lowest pitch in the available pitches that is in the instrument's
        range. If the user hasn't set this slot, then the range of the pitch-seq
        will correspond to the middle of the available pitches.

        There are two caveats here if the instrument's prefers-notes slot is
        NIL: 1) If the lowest number in the pitch-seq is 5 or higher, this will
        have the same effect as the prefers-notes slot being high. Similarly, if
        the lowest number is 1, it will have the same effect as the
        prefers-notes slot being low. These two numbers (5 and 1) are actually
        global slippery chicken configuration data: (get-sc-config
        pitch-seq-lowest-equals-prefers-high) and (get-sc-config
        pitch-seq-lowest-equals-prefers-low) so can be set using the
        set-sc-config function.

        * The question as to how many pitches are enough pitches before adding
        used notes is determined by the pitch-seq-index-scaler-min argument,
        which is by default 0.5 (in the slippery-chicken slot that's usually
        used and passed to this method). As the pitch-seq notes must be offset
        and scaled before they can be used as indices, there's a minimum scaler
        that's considered acceptable; anything below this would result in more
        notes being added.

     5) If at this point there are no available pitches, the function will by
        default trigger an error and exit (see however pitch-seq-no-pitches-error
        in globals.lsp). This could happen if the value of set-limits, both high
        and low, took the available pitches outside of the instrument's range,
        for instance.

     6) The pitch-seq numbers are now offset and scaled, then rounded in order
        to use them as indices into the pitch list. If a number is in
        parentheses then this is where the instrument's chord function would be
        called. As notes are selected, the set marks them as used for the next
        time around. Also, there's an attempt to avoid melodic octaves on
        adjacent notes; however, if the set is full of octaves this won't be
        possible; in that case a warning will be issued and the octave will be
        used.

ARGUMENTS

     - A pitch-seq object.
     - An instrument object.
     - A player object.
     - An sc-set object.
     - A hint pitch (ignored for now).
     - A pitch-object defining the highest possible note.
     - A pitch-object defining the lowest possible note.
     - The sequence number (for diagnostics).
     - The last note of the previous sequence, as a pitch object.
     - The lowest scaler that will be accepted before adding notes from those
       used; i.e., if the pitch-seq needs 6 notes and only 3 are available,
       there would be note repetition, but as this would create a scaler of 0.5,
       that would be acceptable
     - Whether to avoid lines jumping an octave in either direction (passed by
       the slippery chicken slot).
     - Whether to remove notes already chosen for other instruments before
       selecting notes for this one.

RETURN VALUE

     Returns the list of pitch objects that forms the notes slot of the given
     pitch-seq

SYNOPSIS

    (defmethod get-notes ((ps pitch-seq) instrument player set hint-pitch limit-high
                          limit-low seq-num last-note-previous-seq
                          pitch-seq-index-scaler-min avoid-melodic-octaves
                          avoid-used-notes)

## pitch-seq/invert [ Methods ]

[ Top ] [ pitch-seq ] [ Methods ]

DESCRIPTION

     Invert the pitch sequence contour attached to a given pitch-seq object. The
     inversion uses only the same numbers from the original pitch contour list.

ARGUMENTS

     - A pitch-seq object.

RETURN VALUE

     A pitch-seq object.

EXAMPLE

    (let ((ps (make-pitch-seq '(pseq1 (1 2 1 3 4 7)))))
      (data (invert ps)))

    => (7 4 7 3 2 1)

SYNOPSIS

    (defmethod invert ((ps pitch-seq))

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

[ Top ] [ pitch-seq ] [ Functions ]

DESCRIPTION

     Create a pitch-seq object.

     This function can be either called with one argument, consisting of a
     two-item list, in which the first item is the pitch-seq ID and the second
     is a list of numbers representing the pitch curve of the intended pitch
     sequence; or it can be created with two arguments, the first of which being
     the list of numbers representing the pitch curve and the second being the
     pitch-seq's ID.

     NB We can assign a pitch-seq exclusively to particular instruments in the
     ensemble simply by passing their names as symbols along with the curve
     data.  See below for an example.

ARGUMENTS

     - A two-item list, of which the first item is a symbol to be used as the
       object's ID, and the second is a list of integers representing the general
       contour of the pitch sequence.

OPTIONAL ARGUMENTS

     - If the optional argument format is used, the first argument is to be
       a list of numbers representing the general contour of the pitch sequence,
       and the second is to be a symbol for the pitch-seq object's ID.

RETURN VALUE

     - A pitch-seq object.

EXAMPLE

    ;; The first creation option is using one argument that is a two-item list,
    ;; whereby the first item is a symbol to be used as the pitch-seq object's ID
    ;; and the second is a list of numbers representing the general contour of the
    ;; pitch sequence.
    (make-pitch-seq '(pseq1 (1 2 1 1 3)))

    =>
    PITCH-SEQ: notes: NIL
    highest: 3
    lowest: 1
    original-data: (1 2 1 1 3)
    user-id: T
    instruments: NIL
    relative-notes: (not printed for sake of brevity)
    relative-notes-length: 25
    SCLIST: sclist-length: 5, bounds-alert: T, copy: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: PSEQ1, tag: NIL,
    data: (1 2 1 1 3)

    ;; The second creation option uses two arguments, the first of which is a list
    ;; of numbers representing the general contour of the pitch sequence, the
    ;; second of which is a symbol which will be used as the pith-seq object's ID.
    (make-pitch-seq '(2 1 1 3 1) 'pseq2)

    =>
    PITCH-SEQ: notes: NIL
    highest: 3
    lowest: 1
    original-data: (2 1 1 3 1)
    user-id: NIL
    instruments: NIL
    relative-notes: (not printed for sake of brevity)
    relative-notes-length: 25
    SCLIST: sclist-length: 5, bounds-alert: T, copy: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: PSEQ2, tag: NIL,
    data: (2 1 1 3 1)

    ;; An example assigning a pitch-seq only to specific instruments: ; ;
    (make-pitch-seq '((1 2 1 1 3) violin flute) 'ps1))

SYNOPSIS

    (defun make-pitch-seq (id-data &optional (id nil))

## sclist/pitch-seq [ Classes ]

[ Top ] [ sclist ] [ Classes ]

NAME

     pitch-seq

     File:             pitch-seq.lsp

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

     Version:          1.0.10

     Project:          slippery chicken (algorithmic composition)

     Purpose:          Implementation of the pitch-seq class.  This describes
                       the pitch curves for a given rhythmic sequence.  These
                       are normally simple lists of notes indicating pitch
                       height (and later mapped onto sets); chords are indicated
                       by placing a number in parentheses.

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

     Creation date:    19th February 2001

     $$ Last modified:  11:31:57 Tue Jul 16 2019 CEST

     SVN ID: $Id$