./../../src/chord.lsp

## chord/add-harmonics [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Adds pitches to the set which are harmonically related to the existing
     pitches. The keywords are the same as for the get-harmonics function.  See
     also sc-set method of the same name and get-pitch-list-harmonics. NB This
     will automatically sort all pitches from high to low.

ARGUMENTS

     - a chord object

OPTIONAL ARGUMENTS

     keyword arguments:
      see get-harmonics function

RETURN VALUE

     the same set object as the first argument but with new pitches added.

SYNOPSIS

    (defmethod add-harmonics ((c chord) &rest keywords)

## chord/add-mark [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Add the specified mark to the MARKS slot of the given chord object.

ARGUMENTS

     - A chord object.
     - A mark.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether to print a warning when attempting to add a
       mark to a rest.

RETURN VALUE

     Returns the full contents of the MARKS slot of the given chord object

EXAMPLE

    ;;; Returns the complete contents of the MARKS slot
    (let ((chrd (make-chord '(cs4 e4 fs4 af4 bf4))))
      (add-mark chrd 'fff)
      (add-mark chrd 'pizz))

    => (PIZZ FFF)

SYNOPSIS

    (defmethod add-mark ((c chord) mark &optional warn-rest)

## chord/add-pitches [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Add the specified pitches to the given chord object.

ARGUMENTS

     - A chord object.
     - The pitches to add to that object. These can be pitch objects or any data
       that can be passed to make-pitch, or indeed lists of these, as they will
       be flattened.

RETURN VALUE

     - A chord object.

EXAMPLE

    (let ((ch (make-chord '(c4 e4 g4))))
      (print (get-pitch-symbols ch))
      (add-pitches ch 'bf3)
      (print (get-pitch-symbols ch))
      (add-pitches ch 'af3 'a4 'b4)
      (print (get-pitch-symbols ch))
      (add-pitches ch '(cs5 ds5 fs5))
      (print (get-pitch-symbols ch)))

    =>
    (C4 E4 G4)
    (BF3 C4 E4 G4)
    (AF3 BF3 C4 E4 G4 A4 B4)
    (AF3 BF3 C4 E4 G4 A4 B4 CS5 DS5 FS5)

SYNOPSIS

    (defmethod add-pitches ((c chord) &rest pitches)

## chord/artificial-harmonic? [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     October 4th 2014

DESCRIPTION

     Determine whether a chord represents an artificial harmonic of the type
     that strings play. An artificial harmonic here is defined as a three note
     chord where the second note has a 'flag-head mark (i.e diamond shape) and
     the 1st and 3rd are related in frequency by an integer ratio.

     NB What we don't do (yet) is test whether the 2nd note is the correct nodal
     point to produce the given pitch.

ARGUMENTS

     - a chord object

OPTIONAL ARGUMENTS

     - cents-tolerance: how many cents the top note can deviate from a pure
       partial frequency. E.g. the 7th harmonic is about 31 cents from the
       nearest tempered note.

RETURN VALUE

     If the chord is an artificial harmonic then the sounding (3rd) note is
     returned, otherwise NIL.

SYNOPSIS

    (defmethod artificial-harmonic? ((c chord) &optional (cents-tolerance 31))

## chord/calculate-dissonance [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     27th July 2015, Edinburgh

DESCRIPTION

     Calculates the dissonance of a chord as it would appear when played on the
     piano (by default; other instruments' spectral data can also be used: see
     below). This uses a roughness calculation model by Pantelis N. Vassilakis
     as outlined at http://www.acousticslab.org/learnmoresra/moremodel.html. The
     model has been perceptually verified. We use spectral data handled by
     spectra.lsp to sum the roughness of sine pairs up to the first 12 partials
     of each tone, i.e. every partial of every tone is calculated in relation to
     all other tones' partials, taking their amplitudes into account.

     NB If notes are above/below the piano range for which we have data then we
     use the highest/lowest spectral data available.

     NB This method will be called automatically the first time you access a
     chord object's dissonance slot. In that case the default keyword arguments
     will be used. If you want to use different arguments or recalculate
     dissonance after the chord has been altered, this method can be used at any
     time but bear in mind that it does not automatically change the dissonance
     slot so use setf for that if necessary. If you merely want to change the
     default spectra which are used, then you can do that at startup via
     (set-sc-config 'default-spectra ...)

ARGUMENTS

     - the chord object

OPTIONAL ARGUMENTS

     keyword arguments:
     - :num-partials. The number of partials we want to use in our
       calculation. Default = 12.
     - :average. T or NIL to indicate whether we want to use the average
       spectrum for an octave with the current note of a chord in the middle.
       Default = T.
     - :spectrum. Pass a two-element list of partial frequency scalers (list)
       and amplitudes (list) to use instead of the piano data. The amplitudes
       should be normalised from 0.0 to 1.0 and there should be as many of these
       as frequency scalers and :num-partials. Bear in mind that even using the
       same data for several calls, this will still give different results for
       the same chord type starting on different notes, as the perceptual
       dissonance is based on pitch height as well as interval structure.
       Default = (get-sc-config 'default-spectra) (see globals.lsp)

RETURN VALUE

     A floating point number representing the dissonance value. Higher values
     are more dissonant.

SYNOPSIS

    (defmethod calculate-dissonance ((c chord)
                                     &key (num-partials 12) (average t)
                                       (spectrum (get-sc-config 'default-spectra)))

## chord/calculate-spectral-centroid [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     July 28th 2015

DESCRIPTION

     Calculate the spectral centroid of a chord. This technique is of course
     usually applied in digital signal processing to an audio signal via a
     Fast Fourier Transform (FFT). It's perhaps a little strange to use this on
     pitch data, not least of which because we will not be taking into
     account any phase information or interference of possible harmonic partial
     interactions, but nevertheless we get a good indication of the "pitch
     height" of a chord via this method.

     NB This will be called automatically the first time you access a chord
     object's centroid slot. In that case the default keyword arguments will be
     used. If you want to use different arguments or recalculate the centroid
     after the chord has been altered, this method can be used at any time but
     bear in mind that it does not automatically change the centroid slot so use
     setf for that if necessary.

ARGUMENTS

     - the chord object

OPTIONAL ARGUMENTS

     keyword arguments:
     - :num-partials. The number of partials we want to use in our
       calculation. Default = 12.
     - :average. T or NIL to indicate whether we want to use the average
       spectrum for an octave with the current note of a chord in the middle.
       Default = T.
     - :spectrum. Pass a two-element list of partial frequency scalers (list)
       and amplitudes (list) to use instead of the piano data. The amplitudes
       should be normalised from 0.0 to 1.0 and there should be as many of these
       as frequency scalers and :num-partials. Bear in mind that even using the
       same data for several calls, this will still give different results for
       the same chord type starting on different notes, as the perceptual
       dissonance is based on pitch height as well as interval structure.
       Default = (get-sc-config 'default-spectra) (see globals.lsp)

RETURN VALUE

     A floating point value representing the frequency in Hertz of the spectral
     centroid.

EXAMPLE

    (calculate-spectral-centroid (make-chord '(fs3 c4 cs4 d4 ds4 e4)))
     --> 692.3215865354373d0
    (calculate-spectral-centroid (make-chord '(fs3 c4 cs4 d4 ds4 e4 g6)))
     --> 772.4924013974714d0

SYNOPSIS

    (defmethod calculate-spectral-centroid ((c chord)
                                            &key (num-partials 12)
                                              (average t)
                                              (spectrum
                                               (get-sc-config 'default-spectra)))

## chord/chord-equal [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Test to see if two chords are equal.

     NB: Two unsorted chord objects that contain the exact same pitch objects in
         a different order will not be considered equal and will return NIL.

     NB: Equality is tested on pitch content only, not on, for example, the
         values of the MIDI slots of those pitch objects etc.

ARGUMENTS

     - A first chord object.
     - A second chord object.

RETURN VALUE

     T or NIL. T if the pitch content of the chords is equal, otherwise NIL.

EXAMPLE

    ;; Two chords are equal
    (let ((chrd1 (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12))
          (chrd2 (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (chord-equal chrd1 chrd2))

    => T

    ;; Chord objects with the same pitch objects in a different order are unequal
    (let ((chrd1 (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12))
          (chrd2 (make-chord '(e4 c4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12
                            :auto-sort nil)))
      (chord-equal chrd1 chrd2))

    => NIL

    ;; Only the pitch content is compared. Content of other slots is irrelevant.
    (let ((chrd1 (make-chord '(e4 c4 gqs4 bqf4 d5 f5)
                             :midi-channel 11
                             :microtones-midi-channel 12))
          (chrd2 (make-chord '(e4 c4 gqs4 bqf4 d5 f5)
                             :midi-channel 7
                             :microtones-midi-channel 8)))
      (chord-equal chrd1 chrd2))

    => T

SYNOPSIS

    (defmethod chord-equal ((c1 chord) (c2 chord))

## chord/chord-member [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Test whether a specified pitch object is a member of a given chord object.

ARGUMENTS

     - A chord object.
     - A pitch object. This must be a pitch object, not just a note-name symbol,
       but the pitch object can be made with either a note-name symbol or a
       numerical hertz frequency value.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether or not the method should consider
       enharmonically equivalent pitches to be equal. T = enharmonics are
       equal. Default = T.

RETURN VALUE

     Similar to Lisp's "member" function, this method returns the tail of the
     data (list of pitch objects) of the tested chord object starting with the
     specified pitch object if that pitch is indeed a member of that list,
     otherwise returns NIL.

     NB: Since the method returns the tail of the given chord (the "rest" of the
         pitches after the given pitch), the result may be different depending
         on whether that chord has been auto-sorted or not.

EXAMPLE

    ;; Returns the tail of pitch objects contained starting with the tested pitch
    (let ((chrd (make-chord '(c4 e4 gqs4 a4 d5 f5 bqf5)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (pitch-list-to-symbols (chord-member chrd (make-pitch 'a4))))

    => (A4 D5 F5 BQF5)

    ;; The chord object's default auto-sort feature might appear to affect outcome
    (let ((chrd (make-chord '(d5 c4 gqs4 a4 bqf5 f5 e4)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (pitch-list-to-symbols (chord-member chrd (make-pitch 'a4))))

    => (A4 D5 F5 BQF5)

    ;; Returns NIL if the pitch is not present in the tested chord object. This
    ;; example uses the "pitch-list-to-symbols" function to simplify the
    ;; pitch-object output.
    (let ((chrd (make-chord '(d5 c4 gqs4 a4 bqf5 f5 e4)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (pitch-list-to-symbols (chord-member chrd (make-pitch 'b4))))

    => NIL

    ;; The optional <enharmonics-are-equal> argument is set to NIL by default
    (let ((chrd (make-chord '(c4 e4 a4 d5 f5))))
      (pitch-list-to-symbols (chord-member chrd (make-pitch 'ds4))))

    => NIL

    ;; Setting the optional <enharmonics-are-equal> argument to T
    (let ((chrd (make-chord '(c4 ef4 a4 d5 f5))))
      (pitch-list-to-symbols (chord-member chrd (make-pitch 'ds4) t)))

    => (EF4 A4 D5 F5)

    ;; The optional <octaves-are-true> argument is NIL by default

    (let ((chrd (make-chord '(c4 ef4 a4 d5 ef5 f5))))
      (pitch-list-to-symbols (chord-member chrd (make-pitch 'c5))))

    => NIL

    ;; If optional <octaves-are-true> argument is set to T, any occurrence of the
    ;; same pitch class in a different octave will be considered part of the chord
    ;; and return a positive result.
    (let ((chrd (make-chord '(c4 ef4 a4 d5 ef5 f5))))
      (pitch-list-to-symbols (chord-member chrd (make-pitch 'c5) nil t)))

    => (C4 EF4 A4 D5 EF5 F5)

SYNOPSIS

    (defmethod chord-member ((c chord) (p pitch)
                             &optional (enharmonics-are-equal t)
                                       (octaves-are-true nil))

## chord/chord= [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     November 11th 2013

DESCRIPTION

     Test whether the pitch objects of the two chords are pitch=.  Assumes both
     chords are sorted by pitch height.  See pitch= in the pitch class for
     details of comparing pitches.

RETURN VALUE

     T or NIL

SYNOPSIS

    (defmethod chord= ((c1 chord) (c2 chord) &optional enharmonics-are-equal
                       (frequency-tolerance 0.01)) ; (src-tolerance 0.0001))

## chord/common-notes [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Return the integer number of pitches common to two chord objects.

ARGUMENTS

     - A first chord object.
     - A second chord object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether enharmonically equivalent pitches are to be
       considered the same pitch. T = enharmonically equivalent pitches are
       considered the same pitch. Default = T.
     - T or NIL to indicate whether the same pitch class in different octaves is
       to be considered the same pitch. T = consider the same pitch class from
       octaves to be the same pitch. Default = NIL.

RETURN VALUE

     Returns an integer that is the number of pitches common to the two chords
     objects.

EXAMPLE

    ;; The following two chord objects have 3 pitches in common
    (let ((chrd-1 (make-chord '(c4 e4 g4 b4 d5 f5)))
          (chrd-2 (make-chord '(d3 f3 a3 c4 e4 g4))))
      (common-notes chrd-1 chrd-2))

    => 3

    ;; By default, enharmonically equivalent pitches are considered to be the same
    ;; pitch
    (let ((chrd-1 (make-chord '(c4 e4 g4 b4 d5 f5)))
          (chrd-2 (make-chord '(d3 f3 a3 c4 ff4 g4))))
      (common-notes chrd-1 chrd-2))

    => 3

    ;; Setting the first optional argument to NIL causes enharmonically equivalent
    ;; pitches to be considered separate pitches
    (let ((chrd-1 (make-chord '(c4 e4 g4 b4 d5 f5)))
          (chrd-2 (make-chord '(d3 f3 a3 c4 ff4 g4))))
      (common-notes chrd-1 chrd-2 nil))

    => 2

    ;; By default, the same pitch class in different octaves is considered to be a
    ;; separate pitch
    (let ((chrd-1 (make-chord '(c4 e4 g4 b4 d5 f5)))
          (chrd-2 (make-chord '(d3 f3 a3 ff4 g4 c5))))
      (common-notes chrd-1 chrd-2 t))

    => 2

    ;; Setting the second optional argument to T causes all pitches of the same
    ;; pitch class to be considered equal regardless of their octave
    (let ((chrd-1 (make-chord '(c4 e4 g4 b4 d5 f5)))
          (chrd-2 (make-chord '(d3 f3 a3 ff4 g4 c5))))
      (common-notes chrd-1 chrd-2 t t))

    => 5

SYNOPSIS

    (defmethod common-notes ((c1 chord) (c2 chord)
                             &optional (enharmonics-are-equal t)
                             (octaves-are-true nil))

## chord/delete-marks [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Delete all marks from the MARKS slot of the given chord object.

ARGUMENTS

     - A chord object.

RETURN VALUE

     Returns NIL.

EXAMPLE

    ;;; Make a chord object, add two marks, and print the MARKS slot to see them;
    ;;; apply delete-marks and print the MARKS slot again to see the change
    (let ((chrd (make-chord '(cs4 e4 fs4 af4 bf4))))
      (add-mark chrd 'fff)
      (add-mark chrd 'pizz)
      (print (marks chrd))
      (delete-marks chrd)
      (print (marks chrd)))

    =>
    (PIZZ FFF)
    NIL

SYNOPSIS

    (defmethod delete-marks ((c chord))

## chord/get-highest [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     28/10/14

DESCRIPTION

     Assuming the auto-sort slot is T (which it is by default), return the last
     (= highest) pitch in the chord.

ARGUMENTS

     - a chord object

RETURN VALUE

     The highest pitch (object) in the chord.

SYNOPSIS

    (defmethod get-highest ((c chord))

## chord/get-interval-structure [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Get the distances between each pitch in a given sc-set object and the
     lowest (or neighbouring) pitch in that object in DEGREES (which default to
     quarter-tones in slippery chicken). This method assumes that the given
     sc-set object is sorted from low to high, which is the default action for
     sc-set objects.

ARGUMENTS

     - An sc-set object.

     OPTIONAL
     - T or NIL indicating whether to return values in semitones or default of
       degrees. Special case: if this argument is 'frequencies, then the
       interval structure will be returned as frequency differences. T =
       semitones. Default = NIL.
     - T or NIL to indicated whether we should return intervals from pitch to
       pitch (T) or from the lowest to each pitch (NIL). Default = NIL.

RETURN VALUE

     A list of integers.

EXAMPLE

    ;;; Returns the distances in degrees (which are quarter-tones by default
    ;;; in slippery chicken--use (in-scale :chromatic) at the top of your code to
    ;;; set to the chromatic scale):

    (get-interval-structure (make-chord '(c4 e4 g4)))

    => (8.0 14.0)

    ;;; Return semitones
    (get-interval-structure (make-chord '(c4 e4 g4)) t))

    ;;; Interval structure not from lowest but from pitch to pitch (ascending)
    (get-interval-structure (make-chord '(c4 e4 g4 b4)) t t)
    (4.0 3.0 4.0)

    => (4.0 7.0)

SYNOPSIS

    (defmethod get-interval-structure ((c chord) &optional in-semitones neighbour)

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

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Get the MIDI channel of the first pitch object contained in a given chord
     object.

     NB: This method returns only the midi-channel of the first pitch object in
         the chord object's data list.

ARGUMENTS

     - A chord object.

RETURN VALUE

     An integer.

EXAMPLE

    (let ((chrd (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (get-midi-channel chrd))

    => 11

SYNOPSIS

    (defmethod get-midi-channel ((c chord))

## chord/get-partials-amps [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     July 28th 2015, Edinburgh

DESCRIPTION

     Return a list containing for every pitch in the chord a list of two lists:
     first the partial frequency scalars (which will be integers or very close
     to integers) then the normalised partial amplitudes.

     Note that if spectrum are given then average is ignored. If spectrum is an
     assoc-list then we get the data from it otherwise if it's just a list of
     freq-scalers then amps, it's fixed and we use that repeatedly.

ARGUMENTS

     - the chord object

OPTIONAL ARGUMENTS

     keyword arguments:
     - :average. Whether to average spectral data over one octave centring around
     each of the pictures in the chord. Default = T.
     - :spectrum. The spectrum data. Default = (get-sc-config 'default-spectra)
       (see globals.lsp)

RETURN VALUE

     A list of two element sublist. of numbers.

EXAMPLE

    (get-partials-amps (make-chord '(c4 e4 g4)))
    -->
    (((0.99666667 1.9958333 2.9941666 3.9958336 5.002501 6.015 7.0333333 8.049168
       9.086666 10.125 11.174167 12.234166)
      (0.9447856 1.0000001 0.22975834 0.13516104 0.1625952 0.05319352 0.12118169
       2.1978654e-4 0.049031425 0.010756988 0.011732774 0.0))
     ((0.9966666 1.9958333 2.9966667 4.0025005 5.0133333 6.028333 7.0575004
       8.085834 9.136668 10.193334 11.264999 12.346667)
      (0.99999994 0.73724264 0.20146085 0.10752921 0.122650035 0.03613218
       0.06638182 0.0 0.022111647 0.004390597 0.011441806 5.167861e-4))
     ((0.9966666 1.995 3.0 4.005834 5.0208335 6.042501 7.08 8.1225 9.185 10.261666
       11.45 11.405833)
      (1.0 0.48279247 0.1664997 0.066108614 0.07859015 0.027295936 0.035848983 0.0
       0.010107763 0.0027390774 0.0040924386 0.0010194636)))

SYNOPSIS

    (defmethod get-partials-amps ((c chord)
                                  &key (average t)
                                    (spectrum (get-sc-config 'default-spectra)))

## chord/get-pitch [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Get the pitch object located at the specified index within the given chord
     object. The <ref> argument is 1-based.

ARGUMENTS

     - A chord object.
     - An integer that is the index of the pitch object sought within the data
       list of the given chord object.

RETURN VALUE

     A pitch object.

EXAMPLE

    (let ((chrd (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (get-pitch chrd 3))

    =>
    PITCH: frequency: 403.482, midi-note: 67, midi-channel: 12
           pitch-bend: 0.5
           degree: 135, data-consistent: T, white-note: G4
           nearest-chromatic: G4
           src: 1.5422108173370361, src-ref-pitch: C4, score-note: GS4
           qtr-sharp: 1, qtr-flat: NIL, qtr-tone: 1,
           micro-tone: T,
           sharp: NIL, flat: NIL, natural: NIL,
           octave: 4, c5ths: 0, no-8ve: GQS, no-8ve-no-acc: G
           show-accidental: T, white-degree: 32,
           accidental: QS,
           accidental-in-parentheses: NIL, marks: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: GQS4, tag: NIL,
    data: GQS4

SYNOPSIS

    (defmethod get-pitch ((c chord) ref)

## chord/get-pitch-symbols [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Return the data of the pitch objects from a given chord object as a list of
     note-name symbols.

ARGUMENTS

     - A chord object.

RETURN VALUE

     A list of note-name symbols.

EXAMPLE

    (let ((chrd (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (get-pitch-symbols chrd))

    => (C4 E4 GQS4 BQF4 D5 F5)

SYNOPSIS

    (defmethod get-pitch-symbols ((c chord) &optional ignore)

## chord/has-notes [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     16-Aug-2010

DESCRIPTION

     Tests whether a given chord object contains at least one pitch
     object.

     (make-chord nil) is a valid function call and creates a chord object with
     no notes.

ARGUMENTS

     - A chord object.

RETURN VALUE

     Returns T if the given chord object contains at least one pitch object,
     otherwise returns NIL.

EXAMPLE

    ;; Returns T if the given chord object contains at least one pitch object
    (let ((chrd (make-chord '(c4))))
      (has-notes chrd))

    => T

    (let ((chrd (make-chord '(c4 e4 g4))))
      (has-notes chrd))

    => T

    ;; Otherwise returns NIL
    (let ((chrd (make-chord nil)))
      (has-notes chrd))

    => NIL

SYNOPSIS

    (defmethod has-notes ((c chord))

## chord/highest [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Return the pitch object from the given chord object that has the highest
     pitch data.

     NB: As opposed to the "lowest" method, this method cannot handle chord
         objects whose pitches have not been auto-sorted from low to high.

ARGUMENTS

     - A chord object.

RETURN VALUE

     A pitch object

EXAMPLE

    ;; Returns the last pitch object of a chord object
    (let ((chrd (make-chord '(e4 c4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (highest chrd))

    =>
    PITCH: frequency: 698.456, midi-note: 77, midi-channel: 11
           pitch-bend: 0.0
           degree: 154, data-consistent: T, white-note: F5
           nearest-chromatic: F5
           src: 2.669679641723633, src-ref-pitch: C4, score-note: F5
           qtr-sharp: NIL, qtr-flat: NIL, qtr-tone: NIL,
           micro-tone: NIL,
           sharp: NIL, flat: NIL, natural: T,
           octave: 5, c5ths: 0, no-8ve: F, no-8ve-no-acc: F
           show-accidental: T, white-degree: 38,
           accidental: N,
           accidental-in-parentheses: NIL, marks: NIL
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: F5, tag: NIL,
    data: F5

    ;; Is not capable of returning the highest pitch object from chord objects that
    ;; have not been auto-sorted
    (let ((chrd (make-chord '(e4 c4 gqs4 bqf4 f5 d5)
                            :midi-channel 11
                            :microtones-midi-channel 12
                            :auto-sort nil)))
      (data (highest chrd)))

    => D5

SYNOPSIS

    (defmethod highest ((c chord))

## chord/lowest [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Return the pitch object from the given chord object that has the lowest
     pitch data. The method can handle chord objects whose pitches have not been
     auto-sorted from low to high.

ARGUMENTS

     - A chord object.

RETURN VALUE

     A pitch object.

EXAMPLE

    ;; Returns the pitch object of the lowest pitch despite not being sorted
    (let ((chrd (make-chord '(e4 c4 gqs4 bqf4 d5 f5)
                            :midi-channel 11
                            :microtones-midi-channel 12
                            :auto-sort nil)))
      (lowest chrd))

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

SYNOPSIS

    (defmethod lowest ((c chord))

## chord/make-chord [ Functions ]

[ Top ] [ chord ] [ Functions ]

DESCRIPTION

     Create a chord object from a list of note-name symbols.

ARGUMENTS

     - A list of note-name symbols.

OPTIONAL ARGUMENTS

     keyword arguments:
     - :id. An element of any type that is to be the ID of the chord object
       created.
     - :auto-sort. T or NIL to indicate whether the method should first sort the
       individual pitch objects created from low to high before returning the
       new chord object. T = sort. Default = T.
     - :midi-channel. An integer that is to be the MIDI channel value to which
       all of the chromatic pitch objects in the given chord object are to be
       set for playback. Default = 1.
     - :microtones-midi-channel. An integer that is to be the MIDI channel value
       to which all of the microtonal pitch objects in the given chord object
       are to be set for playback. Default = 1. NB: See
       player.lsp/make-player for details on microtones in MIDI output.
     - :force-midi-channel. T or NIL to indicate whether to force a given value
       to the MIDI-CHANNEL slot, even if the notes passed to the method are
       already pitch objects with non-zero MIDI-CHANNEL values.

RETURN VALUE

     A chord object.

EXAMPLE

    ;; Simple usage with default values for keyword arguments
    (make-chord '(c4 e4 g4 b4 d5 f5))

    =>
    CHORD: auto-sort: T, marks: NIL, micro-tone: NIL
    SCLIST: sclist-length: 6, bounds-alert: T, copy: T
    LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
    NAMED-OBJECT: id: NIL, tag: NIL,
    data: (
    PITCH: frequency: 261.626, midi-note: 60, midi-channel: 0
    [...]
    data: C4
    PITCH: frequency: 329.628, midi-note: 64, midi-channel: 0
    [...]
    data: E4
    [...]
    PITCH: frequency: 391.995, midi-note: 67, midi-channel: 0
    [...]
    data: G4
    [...]
    PITCH: frequency: 493.883, midi-note: 71, midi-channel: 0
    [...]
    data: B4
    [...]
    PITCH: frequency: 587.330, midi-note: 74, midi-channel: 0
    [...]
    data: D5
    [...]
    PITCH: frequency: 698.456, midi-note: 77, midi-channel: 0
    [...]
    data: F5
    )

    ;; By default the pitches are first sorted low to high
    (let ((mc (make-chord '(e4 c4 g4 b4 f5 d5))))
      (loop for p in (data mc) collect (data p)))

    => (C4 E4 G4 B4 D5 F5)

    ;; Setting the :midi-channel and :microtones-midi-channel arguments results in
    ;; the MIDI-CHANNEL slot of each of the contained pitch objects being set
    ;; accordingly, depending on whether it is a chromatic or microtonal pitch
    (let ((mc (make-chord '(cqs4 e4 gqf4 b4 dqf5 f5)
                          :midi-channel 11
                          :microtones-midi-channel 12)))
      (loop for p in (data mc) collect (midi-channel p)))

    => (12 11 12 11 12 11)

SYNOPSIS

    (defun make-chord (note-list &key (id nil) (auto-sort t) (midi-channel 1)
                       (microtones-midi-channel 1) (force-midi-channel t))

## chord/no-accidental [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Set the SHOW-ACCIDENTAL slot of all pitch objects within a given chord
     object to NIL. This results in no accidentals for the given chord being printed
     when written to a score, and also excludes the writing of any accidentals
     for that chord in parentheses.

ARGUMENTS

     - A chord object.

RETURN VALUE

     Always returns NIL.

EXAMPLE

    ;;; Make a chord, print the SHOW-ACCIDENTAL slots of the pitch objects it
    ;;; contains; then call the method and print the same slots again to see the
    ;;; change.

    (let ((chrd (make-chord '(cs4 e4 fs4 af4 bf4))))
      (print (loop for p in (data chrd) collect (show-accidental p)))
      (no-accidental chrd)
      (print (loop for p in (data chrd) collect (show-accidental p))))

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

SYNOPSIS

    (defmethod no-accidental ((c chord))

## chord/output-midi-note [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Generate the MIDI-related data for each pitch in a given chord object.

ARGUMENTS

     - A chord object.
     - A number that is the start time in seconds of the given chord within the
       output MIDI file.
     - A decimal number between 0.0 and 1.0 that is the amplitude of the given
       chord in the output MIDI file.
     - A number that is the duration in seconds of the given chord in the output
       MIDI file.

RETURN VALUE

     The corresponding data in list form.

EXAMPLE

    ;; Generate the MIDI-related data required for a 5-note chord that starts 100
    ;; seconds into the output MIDI file, with an amplitude of 0.5 and a duration
    ;; of 13.0 seconds.
    (let ((chrd (make-chord '(cs4 e4 fs4 af4 bf4))))
      (output-midi-note chrd 100.0 0.5 13.0))

    => (#i(midi time 100.0 keynum 61 duration 13.0 amplitude 0.5 channel -1)
        #i(midi time 100.0 keynum 64 duration 13.0 amplitude 0.5 channel -1)
        #i(midi time 100.0 keynum 66 duration 13.0 amplitude 0.5 channel -1)
        #i(midi time 100.0 keynum 68 duration 13.0 amplitude 0.5 channel -1)
        #i(midi time 100.0 keynum 70 duration 13.0 amplitude 0.5 channel -1))

SYNOPSIS

    (defmethod output-midi-note ((c chord) time amplitude duration)

## chord/pitch- [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Determine the difference between the lowest pitch of two chords. This
     method can be used, for example, to compare the written and sounding
     versions of a chord to determine transposition.

     If the lower chord is passed as the first argument, the method will return
     a negative number.

     NB: This method takes pitch bend into consideration when calculating.

ARGUMENTS

     - A first chord object.
     - A second chord object.

RETURN VALUE

     A positive or negative decimal number.

EXAMPLE

    ;; The method measures the distance between the first (lowest) pitches of the
    ;;; chord only.
    (let ((chrd-1 (make-chord '(c4 e4 g4)))
          (chrd-2 (make-chord '(d4 e4 fs4 a4))))
      (pitch- chrd-2 chrd-1))

    => 2.0

    ;;; Passing the lower chord as the first argument produces a negative result
    (let ((chrd-1 (make-chord '(c4 e4 g4)))
          (chrd-2 (make-chord '(d4 e4 fs4 a4))))
      (pitch- chrd-1 chrd-2))

    => -2.0

SYNOPSIS

    (defmethod pitch- ((c1 chord) (c2 chord))

## chord/respell-chord [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Respell the pitches of a given chord object to improve interval structure;
     i.e., removing augmented intervals etc.

     This method respells pitches from the bottom of the chord upwards. It does
     not process the pitches downwards again once pitches has been
     changed. Instead, it reattempts the whole respelling with the enharmonic of
     the lowest pitch to determine which spelling produces the fewest
     accidentals.

     NB: Respelling pitches in a chord is a rather complex process and is by no
         means fool-proof. The process employed here is based on avoiding double
         accidentals; thus, since both FS4 and BS4 have single sharps, the BS4
         won't be changed to C5.

ARGUMENTS

     - A chord object.

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether to print feedback from the process to the
       listener. T = print. Default = NIL.

RETURN VALUE

     A chord object.

EXAMPLE

    (let ((chrd (make-chord '(a3 ds4 f4 fs5 c6))))
      (pitch-list-to-symbols (data (respell-chord chrd t))))

    => (A3 EF4 F4 GF5 C6)

SYNOPSIS

    (defmethod respell-chord ((c chord) &optional verbose)

## chord/rm-pitches [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Remove the specified pitches from an existing chord object.

ARGUMENTS

     - A chord object.
     - The pitches to remove from that object. These can be pitch objects or any
       data that can be passed to make-pitch, or indeed lists of these, as they
       will be flattened. NB: No warning/error will be signalled if the pitches
       to be removed are not actually in the chord.

RETURN VALUE

     - A chord object.

EXAMPLE

    (let ((ch (make-chord '(af3 bf3 c4 e4 g4 a4 b4 cs5 ds5 fs5))))
      (print (get-pitch-symbols ch))
      (rm-pitches ch 'bf3)
      (print (get-pitch-symbols ch))
      (rm-pitches ch 'af3 'a4 'b4)
      (print (get-pitch-symbols ch))
      (rm-pitches ch '(cs5 ds5 fs5))
      (print (get-pitch-symbols ch)))

    =>
    (AF3 BF3 C4 E4 G4 A4 B4 CS5 DS5 FS5)
    (AF3 C4 E4 G4 A4 B4 CS5 DS5 FS5)
    (C4 E4 G4 CS5 DS5 FS5)
    (C4 E4 G4)

SYNOPSIS

    (defmethod rm-pitches ((c chord) &rest pitches)

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

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Set the MIDI channel of the pitch objects in a given chord object to the
     specified values.

ARGUMENTS

     - A chord object.
     - An integer that is to be the MIDI channel for chromatic pitches in the
       given chord object.
     - An integer that is to be the MIDI channel for microtonal pitches in the
       given chord object. NB: See player.lsp/make-player for details on
       microtones in MIDI output.

RETURN VALUE

     Always returns NIL.

EXAMPLE

    ;; Returns NIL
    (let ((chrd (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                              :midi-channel 11
                              :microtones-midi-channel 12)))
      (set-midi-channel chrd 3 4))

    => NIL

    ;; Print the value of the MIDI slot for each of the pitch objects contained in
    ;; the chord object before and after setting
    (let ((chrd (make-chord '(c4 e4 gqs4 bqf4 d5 f5)
                              :midi-channel 11
                              :microtones-midi-channel 12)))
      (print (loop for p in (data chrd) collect (midi-channel p)))
      (set-midi-channel chrd 3 4)
      (print (loop for p in (data chrd) collect (midi-channel p))))

    =>
    (11 11 12 12 11 11)
    (3 3 4 4 3 3)

SYNOPSIS

    (defmethod set-midi-channel ((c chord) midi-channel microtones-midi-channel)

## chord/similarity [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

     12th August 2015, Wals, Austria

DESCRIPTION

     Calculates the similarity of two chord objects on a scale of 0.0-1.0. This
     weights equally the number of common notes and the interval structure
     between adjacent notes.

ARGUMENTS

     - the first chord object
     - the second chord object

OPTIONAL ARGUMENTS

     - T or NIL to indicate whether enharmonic notes should be treated as
       equal. Even when NIL, enharmonic equivalents will still score high
       overall, just not perfect.
     - T or NIL to indicate whether octave equivalents such as f#1 and f#2
       should result in higher scores.

RETURN VALUE

     a number between 0.0 and 1.0, with 1.0 being the same exact chord and 0.0
     being two chords with no notes and no adjacent intervals in common.

EXAMPLE

    (similarity (make-chord '(c4 e4 g4)) (make-chord '(c4 e4 g4)))
    => 1.0
    (similarity (make-chord '(c4 e4 g4)) (make-chord '(df4 f4 af4)))
    => 0.5
    (similarity (make-chord '(c1 cs1 f1 b1)) (make-chord '(d1 e1 fs1 gs1 as1)))
    => 0.0
    (similarity (make-chord '(cs4 es4 gs4)) (make-chord '(df4 f4 af4)))
    => 1.0
    (similarity (make-chord '(cs4 es4 gs4)) (make-chord '(df4 f4 af4)) nil)
    => 0.75

SYNOPSIS

    (defmethod similarity ((c1 chord) (c2 chord)
                           &optional (enharmonics-are-equal t)
                             (octaves-are-true nil))

## chord/sort-pitches [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Sort the pitch objects contained within a given chord object and return
     them as a list of pitch objects.

     As an optional argument, 'ascending or 'descending can be given to indicate
     whether to sort from low to high or high to low.

ARGUMENTS

     - A chord object.

OPTIONAL ARGUMENTS

     - The symbol 'ASCENDING or 'DESCENDING to indicate whether to sort the
       given pitch objects from low to high or high to low.
       Default = 'ASCENDING.

RETURN VALUE

     Returns a list of pitch objects.

EXAMPLE

    ;; Apply the method with no optional argument (defaults to 'ASCENDING) and
    ;; collect and print the data of the pitch objects in the resulting list
    (let ((chrd (make-chord '(d5 c4 gqs4 bqf5 f5 e4)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (print (loop for p in (sort-pitches chrd) collect (data p))))

    => (C4 E4 GQS4 D5 F5 BQF5)

    ;; Sort from high to low
    (let ((chrd (make-chord '(d5 c4 gqs4 bqf5 f5 e4)
                            :midi-channel 11
                            :microtones-midi-channel 12)))
      (print (loop for p in (sort-pitches chrd 'descending) collect (data p))))

    => (BQF5 F5 D5 GQS4 E4 C4)

SYNOPSIS

    (defmethod sort-pitches ((c chord) &optional (order 'ascending))

## chord/transpose [ Methods ]

[ Top ] [ chord ] [ Methods ]

DESCRIPTION

     Transpose the pitches of a given chord object by a specified number of
     semitones. The specified number can be positive or negative, and may
     contain a decimal segment for microtonal transposition. If passed a decimal
     number, the resulting note-names will be scaled to the nearest degree of
     the current tuning.

ARGUMENTS

     - A chord object.
     - A positive or negative integer or decimal number indicating the number of
       semitones by which the pitches of the given chord object are to be
       transposed.

RETURN VALUE

     Returns a chord object.

EXAMPLE

    ;; Returns a chord object
    (let ((chrd (make-chord '(c4 e4 g4))))
      (transpose chrd 3))

    =>
    CHORD: auto-sort: T, marks: NIL, micro-tone: NIL
    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: (
    [...]
    )

    ;; Accepts positive and negative integers and decimal numbers
    (let ((chrd (make-chord '(c4 e4 g4))))
      (pitch-list-to-symbols (data (transpose chrd 3))))

    => (EF4 G4 BF4)

    (let ((chrd (make-chord '(c4 e4 g4))))
      (pitch-list-to-symbols (data (transpose chrd -3))))

    => (A3 CS4 E4)

    (let ((chrd (make-chord '(c4 e4 g4))))
      (pitch-list-to-symbols (data (transpose chrd -3.17))))

    => (AQF3 CQS4 EQF4)

SYNOPSIS

    (defmethod transpose ((c chord) semitones &key ignore1 ignore2 ignore3)

## sclist/chord [ Classes ]

[ Top ] [ sclist ] [ Classes ]

NAME

     chord

     File:             chord.lsp

     Class Hierarchy:  named-object -> linked-named-object -> sclist -> chord

     Version:          1.0.6

     Project:          slippery chicken (algorithmic composition)

     Purpose:          Implementation of the chord class that is simply an
                       sclist whose data is a list of pitch instances.

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

     Creation date:    July 28th 2001

     $$ Last modified: 12:52:03 Wed Jan 13 2016 GMT

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