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. This can include
 duplicate pitches for things like violin fingered and open string
 unisons. If you don't want pitch duplications, call the rm-duplicates
 method after calling this method.

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 automatically change the dissonance
 slot so use with caution. 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 ...). You can also call rm-diss-cen to
 delete centroid and dissonance slot values (this exists in the set-palette
 class too). 

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.

EXAMPLE

(loop for chord in '((c4 e4 g4)
                     (d4 fs4 a4)
                     (c4 ef4 g4)
                     (c2 e2 g2)
                     (c3 e3 g3)
                     (c4 e4 g4 b4)
                     (c4 e4 g4 b4 cs4))
   collect (calculate-dissonance (make-chord chord) :num-partials 12))
-->
(0.402377778595695d0 0.3699311905936456d0 0.4174836004632471d0
 1.8766497834038562d0 1.0522737914732592d0 0.7389679913974341d0
 1.59662137873394d0)

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 automatically change the centroid slot so use
 with caution. You can call rm-diss-cen to delete centroid and dissonance
 slot values (this exists in the set-palette class too). 

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. 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. Two further values are returned: the list of common pitches and a
 list of their pitch symbols.

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/morph [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

 May 3rd 2016, Edinburgh

DESCRIPTION

 Attempt to morph between two chords by selecting some notes from each
 according to the amount given.

ARGUMENTS

 - the first chord object
 - the second chord object
 - the amount to morph from chord 1 to 2. This should be a number between 0
 and 1 where 0 would mean all chord 1, 1 would mean all chord 2 and anything
 else is an actual morph.

RETURN VALUE

 A new chord object representing a mixture of pitches from the two
 chords. The length of this will depend on the relative lengths of the two
 chords but the minimum will be the length of the smallest chord and the
 maximum the length of the largest chord (in terms of number of pitches).

 NB If you call this method on an sc-set object the subsets and related-sets
 slots will be NIL (i.e. not copied over/morphed from either of the two
 arguments). 

EXAMPLE

(print-simple 
 (morph (make-chord '(c4 e4 g4 b4)) (make-chord '(df4 f4 af4 c5)) 0.5))
--> C4 F4 G4 C5 

SYNOPSIS

(defmethod morph ((c1 chord) (c2 chord) amount)

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
                             &optional 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 clone of the current chord object rather than replacing data.

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 (destructively t) do-related-sets)

chord/wrap [ Methods ]

[ Top ] [ chord ] [ Methods ]

DATE

 March 5th 2016, Edinburgh

DESCRIPTION

 Take the highest pitch and wrap it around to the bottom, placing it at the
 same interval to the former lowest pitch as the highest pitch is to the
 next-to-highest pitch. Then we shift (transpose) the chord so that the
 next-to-highest pitch is the former highest pitch.

 NB The lowest and highest notes of the chord will always remain the same no
 matter how many times this operation is performed. 

ARGUMENTS

 - A chord object

OPTIONAL ARGUMENTS

 - the number of times to perform this operation

RETURN VALUE

 The original chord object with the new pitches (clone in advance if
 necessary) 

EXAMPLE

(get-pitch-symbols (wrap (make-chord '(c4 e4 g4 b4))))
=> (C4 E4 GS4 B4)

(get-pitch-symbols (wrap (make-chord '(c4 fs4 b4 f5))))
=> (C4 GF4 C5 F5)

(get-pitch-symbols (wrap (make-chord '(df3 c4 fs4 b4 f5))))
=> (DF3 G3 FS4 C5 F5)

(get-pitch-symbols (wrap (make-chord '(df3 c4 fs4 b4 f5)) 2))
=> (DF3 GF3 C4 B4 F5)

SYNOPSIS

(defmethod wrap ((c chord) &optional (num-times 1))

sclist/chord [ Classes ]

[ Top ] [ sclist ] [ Classes ]

NAME

 chord

 File:             chord.lsp

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

 Version:          1.0.8

 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:  15:07:45 Mon Aug  7 2017 BST

 SVN ID: $Id$