palette/set-palette [ Classes ]

[ Top ] [ palette ] [ Classes ]

NAME

 set-palette
 
 File:             set-palette.lsp

 Class Hierarchy:  named-object -> linked-named-object -> sclist -> 
                   circular-sclist -> assoc-list -> recursive-assoc-list ->
                   palette -> set-palette

 Version:          1.0.0-beta1

 Project:          slippery chicken (algorithmic composition)

 Purpose:          Implementation of the set-palette class which extends the
                   palette class by simply instantiating the sets given in
                   the palette.  

                   Note that the sets in this palette may refer to
                   previously defined sets in order to obviate retyping note
                   lists.  Hence the reference to bcl-chord2 in the
                   bcl-chord3 set of the example below will instantiate a
                   set based on a transposed clone of that set previously
                   stored as bcl-chord2.  

                     (make-set-palette 
                      'test
                      '((bcl-chord1
                         ((bf1 ef2 aqf2 c3 e3 gqf3 gqs3 cs4 d4 g4 a4 cqs5
                               dqf5 gs5 b5) 
                          :subsets
                          ((tc1 (ds2 e3 a4))
                           (tc2 (bf1 d4 cqs5))
                           (qc1 (aqf2 e3 a4 dqf5 b5))
                           (qc2 (bf1 c3 gqs3 cs4 cqs5)))
                          :related-sets
                          ((missing (bqs0 eqs1 f5 aqs5 eqf6 fqs6 
                                          bqf6 dqs7 fs7)))))
                        (bcl-chord2
                         ((bf1 d2 fqf2 fqs2 b2 c3 f3 g3 bqf3 bqs3 fs4 gs4 a4
                           cs5 gqf5) 
                          :subsets
                          ((tc1 (d2 g3 cs5))
                           (tc2 (eqs2 f3 bqf3))
                           (qc1 (eqs2 c3 f3 fs4 gqf5))
                           (qc2 (d2 fqs2 bqs3 gs4 a4)))
                          :related-sets
                          ((missing (aqs0 dqs1 ds5 gqs5 dqf6 eqf6 aqf6 cqs7
                                          e7))))) 
                        (bcl-chord3 
                         (bcl-chord2 :transposition 13))))


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

 Creation date:    August 14th 2001

 $$ Last modified: 14:51:09 Mon May 14 2012 BST

 SVN ID: $Id: set-palette.lsp 1764 2012-05-17 11:49:59Z medward2 $

set-palette/cmn-display [ Methods ]

[ Top ] [ set-palette ] [ Methods ]

FUNCTION

 Generate printable music notation output (.EPS) of the given set-palette
 object, including separate notation of the SUBSETS and RELATED-SETS slots,
 using the Common Music Notation (CMN) interface. The method requires at
 least the name of the given set-palette object, but has several additional
 optional arguments for customizing output.

 NB: Some of the keyword arguments are CMN attributes and share the same
     name as the CMN feature they effect.

ARGUMENTS

 - A set-palette object.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :file. The file path, including the file name, of the file to be
   generated.
 - :4stave. T or NIL to indicate whether the note-heads of the output should
   be printed on 4 staves (or 2). T = 4. Default = NIL.
 - :text-x-offset. Number (positive or negative) to indicate the horizontal
   offset of any text in the output. A value of 0.0 results in all text
   being lined up left-flush with the note-heads below it. Units here and
   below are relative to CMN staff size. Default = -0.5. 
 - :text-y-offset. Number (positive or negative) to indicate the vertical
   offset of any text in the output.
 - :font-size. A number indicating the size of any text font used in the
   output. This affects text only and not the music (see :size below for
   changing the size of the music).
 - :break-line-each-set. T or NIL to indicate whether each set-palette
   object should be printed on a separate staff or consecutively on the same
   staff. T = one staff per set-palette object. Default = T.
 - :line-separation. A number to indicate the amount of white space between
   lines of music (systems), measured as a factor of the staff
   height. Default = 3. This is a direct CMN attribute.
 - :staff-separation. A number to indicate the amount of white space between
   staves belong to the same system, measured as a factor of the staff
   height. Default = 3. This is a direct CMN attribute.
 - :transposition. Nil or a number (positive or negative) to indicate the
   number of semitones by which the pitches of the given set-palette object
   should be transposed before generating the CMN output. Default = NIL (0).
 - :size. A number to indicate the size of the music-font in the CMN
   output. This affects music only, not text.
 - :use-octave-signs. T or NIL. Default = NIL.
 - :automatic-octave-signs. T or NIL. Default = NIL.
 - :include-missing-chromatic. T or NIL to indicate whether to also print
   any chromatic pitches from the complete-set that are not present in the
   given set-palette object. T = print. Default = T.
 - :include-missing-non-chromatic. T or NIL to indicate whether to also
   print any microtonal pitches from the complete-set that are not
   present in the given set-palette object. T = print.  Default = T.

RETURN VALUE

 slippery chicken prints a series of status lines in the listener, and
 outputs an EPS file.

EXAMPLE

;; A typical example with some specified keyword values for file, font-size,
;; break-line-each-set, size, include-missing-chromatic and
;; include-missing-non-chromatic 
(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((c3 g3 cs4 e4 fs4 a4 bf4 c5 d5 f5 gf5 af5 ef6)))
                  (2
                   ((c3 g3 cs4 e4 fs4 a4 bf4 c5 d5 f5 gf5 af5 ef6)
                    :subsets
                    ((tc1 (d2 g3 cs5))
                     (tc2 (eqs2 f3 bqf3))
                     (tc3 (b2 bqs3 gqf5)))))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (cmn-display msp
               :file "/tmp/sp-output.eps"
               :font-size 8
               :break-line-each-set nil
               :size 10
               :include-missing-chromatic nil
               :include-missing-non-chromatic nil))

SYNOPSIS

(defmethod cmn-display ((sp set-palette)
                        &key
                        ;; 10.3.10: display on 4 staves (treble+15 bass-15)?
                        (4stave nil)
                        (file "/tmp/cmn.eps")
                        (text-x-offset -0.5)
                        (text-y-offset nil)
                        (font-size 10.0)
                        (break-line-each-set t)
                        (line-separation 3)
                        (staff-separation nil)
                        (transposition nil) ;; in semitones
                        (size 20)
                        (use-octave-signs nil)
                        (automatic-octave-signs nil)
                        (include-missing-chromatic t)
                        (include-missing-non-chromatic t))

set-palette/find-sets-with-pitches [ Methods ]

[ Top ] [ set-palette ] [ Methods ]

FUNCTION

 Return a list of sets (as complete-set objects) from a given set-palette
 object based on whether they contain specified pitches.

 NB: Only sets which contain all of the specified pitches will be returned. 

ARGUMENTS

 - A set-palette object.
 - A list of pitches, either as pitch objects or note-name symbols.

 OPTION ARGUMENTS
 - T or NIL to indicate whether to print the notes of each successful set as
   they are being examined.

RETURN VALUE

 A list of complete-set objects.

EXAMPLE

;; Find sets that contain a single pitch
(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((g3 c4 e4 g4)))
                  (2
                   ((c4 d4 e4 g4)))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (find-sets-with-pitches msp '(c4)))

=>
(
COMPLETE-SET: complete: NIL
[...]
data: (BF3 C4 D4 F4)
[...]
COMPLETE-SET: complete: NIL
[...]
data: (C4 F4 A4 C5)
[...]
COMPLETE-SET: complete: NIL
[...]
data: (C4 D4 E4 G4)
[...]
COMPLETE-SET: complete: NIL
[...]
data: (G3 C4 E4 G4)
)

;; Search for a set of two pitches, printing the successfully matched sets
(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((g3 c4 e4 g4)))
                  (2
                   ((c4 d4 e4 g4)))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (print (find-sets-with-pitches msp '(c4 f4) t)))

=>
(2 1): (C4 F4 A4 C5)
(3 2): (BF3 C4 D4 F4)
(
COMPLETE-SET: complete: NIL
[...]
data: (BF3 C4 D4 F4)
COMPLETE-SET: complete: NIL
[...]
data: (C4 F4 A4 C5)
)

SYNOPSIS

(defmethod find-sets-with-pitches ((sp set-palette) pitches &optional print)

set-palette/force-micro-tone [ Methods ]

[ Top ] [ set-palette ] [ Methods ]

FUNCTION

 Change the value of the MICRO-TONE slot of all pitch objects in a given
 set-palette object to the specified <value>.

ARGUMENTS

 - A set-palette object.

OPTIONAL ARGUMENTS

 - An item of any type that is to be the new value of the MICRO-TONE slot of
   all pitch objects in the given sc-set object (generally T or
   NIL). Default = NIL. 

RETURN VALUE

 Always returns T.

EXAMPLE

;; Create a set-palette object whose individual sets contain some micro-tones
;; and print the contents of all the MICRO-TONE slots to see the values. Then
;; apply the force-micro-tone method and print the slots again to see the
;; changes. 

(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((bf1 ef2 aqf2 c3 e3 gqf3 gqs3 cs4 d4 g4 a4 cqs5 dqf5 gs5 b5)))
                  (2
                   ((bf1 d2 fqf2 fqs2 b2 c3 f3 g3 bqf3 bqs3 fs4 gs4 a4 cs5 gqf5)
                    :subsets
                    ((tc1 (d2 g3 cs5))
                     (tc2 (eqs2 f3 bqf3))
                     (tc3 (b2 bqs3 gqf5)))))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (print (loop for i in (data msp) 
            collect (loop for j in (data (data i))
                       collect (loop for p in (data j)
                                  collect (micro-tone p)))))
  (force-micro-tone msp t)
  (print (loop for i in (data msp) 
            collect (loop for j in (data (data i))
                       collect (loop for p in (data j)
                                  collect (micro-tone p))))))

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

(((T T T T T T T T T T T T T T T) (T T T T T T T T T T T T T T T))
 ((T T T T T T T T T T T T T T T) (T T T T T T T T T T T T T T T))
 ((T T T T T T T T T T T T T T T) (T T T T T T T T T T T T T T T)))

SYNOPSIS

(defmethod force-micro-tone ((sp set-palette) &optional value)

set-palette/gen-max-coll-file [ Methods ]

[ Top ] [ set-palette ] [ Methods ]

DATE

 26 Dec 2009

FUNCTION

 Write a text file from a given set-palette object suitable for reading into
 Max/MSP's coll object. The resulting text file has one line for each set in
 the palette, with the coll index being the ID of the set. The rest of the
 line is a list of frequency/amplitude pairs (or MIDI note numbers if
 required).

ARGUMENTS

 - A set-palette object.
 - The name (and path) of the .txt file to write.

OPTIONAL ARGUMENTS

 - T or NIL to indicate whether MIDI note numbers or frequencies should be
   generated. T = MIDI. Default = NIL (frequencies).

RETURN VALUE

EXAMPLE

;; Generates frequencies by default
(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((g3 c4 e4 g4)))
                  (2
                   ((c4 d4 e4 g4)))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (gen-max-coll-file msp "/tmp/msp-mcf.txt"))

;; Set the optional argument to T to generate MIDI note numbers instead
(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((g3 c4 e4 g4)))
                  (2
                   ((c4 d4 e4 g4)))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (gen-max-coll-file msp "/tmp/msp-mcf.txt" t))

SYNOPSIS

(defmethod gen-max-coll-file ((sp set-palette) file &optional midi)

set-palette/gen-midi-chord-seq [ Methods ]

[ Top ] [ set-palette ] [ Methods ]

FUNCTION

 Generate a MIDI file in which each set of the given set-palette object is
 played at 1 second intervals.

ARGUMENTS

 - A set-palette object.
 - The name and path for the MIDI file to be generated.

RETURN VALUE

 Always returns T

EXAMPLE

(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((bf1 ef2 aqf2 c3 e3 gqf3 gqs3 cs4 d4 g4 a4 cqs5 dqf5 gs5 b5)))
                  (2
                   ((bf1 d2 fqf2 fqs2 b2 c3 f3 g3 bqf3 bqs3 fs4 gs4 a4 cs5 gqf5)
                    :subsets
                    ((tc1 (d2 g3 cs5))
                     (tc2 (eqs2 f3 bqf3))
                     (tc3 (b2 bqs3 gqf5)))))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (gen-midi-chord-seq msp "/tmp/msp-gmchs.mid"))

SYNOPSIS

(defmethod gen-midi-chord-seq ((sp set-palette) midi-file)

set-palette/make-set-palette [ Functions ]

[ Top ] [ set-palette ] [ Functions ]

FUNCTION

 Create a set-palette object.

ARGUMENTS

 - A symbol that is to be the ID of the resulting set-palette object.
 - A recursive list of key/data pairs, of which the deepest level of data
   will be a list of note-name symbols.

OPTIONAL ARGUMENTS

 - keyword argument :recurse-simple-data. T or NIL to indicate whether to
   interpret two-element data lists as recursive palettes. Default = T.
 - keyword argument :warn-note-found. T or NIL to indicate whether to print
   warnings when specified data is not found with subsequent calls to
   the get-data method.

RETURN VALUE

 A set-palette object.

EXAMPLE

;;; Create a set-palette object
(make-set-palette 
 'test
 '((1 ((1
        ((bf1 ef2 aqf2 c3 e3 gqf3 gqs3 cs4 d4 g4 a4 cqs5 dqf5 gs5 b5)
         :subsets
         ((tc1 ((ds2 e3 a4) "a-tag"))
          (tc2 (bf1 d4 cqs5))
          (tc3 (c3 cs4 gs5)))))
       (2
        ((bf1 d2 fqf2 fqs2 b2 c3 f3 g3 bqf3 bqs3 fs4 gs4 a4 cs5 gqf5)
         :subsets
         ((tc1 (d2 g3 cs5))
          (tc2 (eqs2 f3 bqf3))
          (tc3 (b2 bqs3 gqf5)))))
       (3
        ((cqs2 fs2 g2 c3 d3 fqs3 gqf3 cs4 ds4 e4 gs4 dqf5 f5 a5 bqs5)
         :subsets
         ((tc1 (cqs2 c3 f5))
          (tc2 (fs2 e4 bqs5))
          (tc3 (d3 ef4 a5)))))))
   (2 ((1 ((1 1) :transposition 5))
       (2 ((1 2) :transposition 5))
       (3 ((1 3) :transposition 5))))
   (3 ((1 ((1 1) :transposition -2))
       (2 ((1 2) :transposition -2))
       (3 ((1 3) :transposition -2))))))

=>
SET-PALETTE: 
PALETTE: 
RECURSIVE-ASSOC-LIST: recurse-simple-data: T
                      num-data: 9
                      linked: NIL
                      full-ref: NIL
ASSOC-LIST: warn-not-found T
CIRCULAR-SCLIST: current 0
SCLIST: sclist-length: 3, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: TEST, tag: NIL, 
data: (
[...]

;;; NB A simple list of sets (with unique id slots) can also be passed.

SYNOPSIS

(defun make-set-palette (id palette 
                         &key (recurse-simple-data t) (warn-not-found t))

set-palette/recursive-set-palette-from-ring-mod [ Functions ]

[ Top ] [ set-palette ] [ Functions ]

FUNCTION

 Create a set-palette object consisting of sub palette-objects whose pitch
 content is generated based on ring modulation routines applied to the
 specified pitches.

ARGUMENTS

 - A list of note-name symbols, each of which will serve as the reference
   pitch from which a new set-palette object is made using the
   set-palette-from-ring-mod method.
 - A symbol that will be the ID for the top-level set-palette object. The
   IDs of the new set-palette objects contained in the top-level object are
   generated from the note-name symbols of the reference-pitches, with the
   IDs of the pitch sets contained with them then generated by sequential
   numbers.

OPTIONAL ARGUMENTS

 keyword arguments:
 - :partials. A list of integers that are the partials which the method is
   to ring modulate, with 1 being either the reference-note or the bass note
   that would have the reference-note as the highest partial in the given
   list. Default = '(1 3 5 7).
 - :warn-no-bass. T or NIL to indicate whether to issue a warning when
   ring-mod-bass fails to find suitable bass notes for the generated sets. T
   = warn. Default = T.
 - :do-bass. T or NIL to indicate whether to add notes created by the
   ring-mod-bass function to the resulting set-palette obect. T = create and
   add bass notes. Default = T.
 - :remove-octaves. T or NIL to indicate whether to remove the upper
   instances of any octave-equivalent pitches from the resulting set-palette
   object. T = remove. Default = NIL.
 - :min-bass-notes. An integer that is the minimum number of bass notes to
   be generated and added to the resulting set-palette object. Default = 1.
 - :ring-mod-bass-octave. An integer that is the MIDI octave reference
   number (such as the 4 in 'C4), indicating the octave from which the bass
   note(s) are to be taken.

RETURN VALUE

 - A set-palette object (recursive)

EXAMPLE

;; Simple useage with default keyword argument values
(recursive-set-palette-from-ring-mod '(a4 b4 c4) 'rspfrm-test)

=>
SET-PALETTE: 
PALETTE: 
RECURSIVE-ASSOC-LIST: recurse-simple-data: T
                      num-data: 3
                      linked: NIL
                      full-ref: NIL
ASSOC-LIST: warn-not-found T
CIRCULAR-SCLIST: current 0
SCLIST: sclist-length: 3, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: RSPFRM-TEST, tag: NIL, 
data: (
NAMED-OBJECT: id: A4, tag: NIL, 
data: 
SET-PALETTE: 
PALETTE: 
RECURSIVE-ASSOC-LIST: recurse-simple-data: T
                      num-data: 21
                      linked: NIL
                      full-ref: NIL
ASSOC-LIST: warn-not-found T
CIRCULAR-SCLIST: current 0
SCLIST: sclist-length: 21, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: A4, tag: NIL, 
data: (
COMPLETE-SET: complete: NIL
[...]

SYNOPSIS

(defun recursive-set-palette-from-ring-mod (reference-notes id &key
                                            (warn-no-bass t)
                                            (ring-mod-bass-octave 0)
                                            (do-bass t)
                                            remove-octaves
                                            (min-bass-notes 1)
                                            (partials '(1 3 5 7)))

set-palette/ring-mod [ Functions ]

[ Top ] [ set-palette ] [ Functions ]

FUNCTION

 Ring modulate two frequencies and return the resulting pitch and harmonic
 partials thereof. 

ARGUMENTS

 - A first pitch, either as a numeric hertz frequencey or a note-name
   symbol.  
 - A second pitch, either as a numeric hertz frequencey or a note-name
   symbol. The second value needn't be higher than first.

OPTIONAL ARGUMENTS

 - keyword argument :return-notes. T or NIL to indicate whether to return
   the results as note-name symbols or frequency numbers. T = note-name
   symbols. Default = NIL.
 - keyword argument :pitch1-partials. An integer that indicates how many
   harmonic partials of the first pitch are to be included in the
   modulation. Default = 3.
 - keyword argument :pitch2-partials. An integer that indicates how many
   harmonic partials of the second pitch are to be included in the
   modulation. Default = 2.
 - keyword argument :min-freq. A number that is the the minimum frequency
   (hertz) that may be returned. Default = 20.
 - keyword argument :max-freq. A number that is the the maximum frequency
   (hertz) that may be returned. Default = 20000.
 - keyword argument :round. T or NIL to indicate whether frequency values
   returned are first rounded to the nearest hertz. T = round. Default = T
 - keyword argument :remove-duplicates. T or NIL to indicate whether any
   duplicate frequencies are to be removed from the resulting list before
   returning it. T = remove. Default = T. 
 - keyword argument :print. T or NIL to indicate whether resulting data is
   to be printed as it is being generated. T = print. Default = NIL.
 - keyword argument :remove-octaves. T or NIL to indicate whether octave
   repetitions of pitches will be removed from the resulting list before
   returning it, keeping only the lowest instance of each pitch. This
   argument can also be set as a number or a list of numbers that indicates
   which octave repetitions will be allowed, the rest being removed. For
   example, :remove-octaves '(1 2) will remove all octave repetitions of a
   given pitch except for those that are 1 octave and 2 octaves above the
   given pitch; thus '(c1 c2 c3 c4 c5) would return '(c1 c2 c3), removing c4
   and c5. Default = NIL.
 - keyword argument :scale. A variable that indicates which scale to use
   when converting frequencies to note-names. Default = cm::*scale* i.e. the
   value to which the Common Music scale is set, which in slippery chicken
   is *quarter-tone* by default.

RETURN VALUE

 A list of note-name symbols or frequencies.

EXAMPLE

;; Apply ring modulation to 'C4 and 'D4, using 5 partials of the first pitch
;; and 3 partials of the second, removing octave repetitions, and returning the
;; results as rounded hertz-frequencies
(ring-mod 'c4 'd4
          :pitch1-partials 5
          :pitch2-partials 3
          :min-freq 60
          :max-freq 2000
          :remove-octaves t)

=> (64.0 96.0 166.0 198.0 230.0 358.0 427.0 459.0 491.0 555.0 619.0 817.0
    1079.0 1143.0 1340.0 1372.0 1404.0 1666.0 1895.0 1927.0)

;; Applying ring modulation to two frequencies, returning the results as
;; note-name symbols within the chromatic scale.
(ring-mod '261.63 '293.66 
          :return-notes t
          :remove-duplicates nil
          :scale cm::*chromatic-scale*)

=> (C1 C2 G3 BF3 E4 B4 CS5 AF5 AF5 CS6 CS6 F6)

SYNOPSIS

(defun ring-mod (pitch1 pitch2 ;; hertz or notes
                 &key (return-notes nil) (pitch1-partials 3) (pitch2-partials 2)
                 (min-freq 20) (max-freq 20000) (round t) (remove-duplicates t)
                 (print nil) remove-octaves (scale cm::*scale*))

set-palette/ring-mod-bass [ Functions ]

[ Top ] [ set-palette ] [ Functions ]

FUNCTION

 Using ring-modulation techniques, invent (sensible) bass note(s) from a
 list of frequencies.  

ARGUMENTS

 - A list of numbers that are hertz frequencies from which the bass note(s)
   are to be generated.

OPTIONAL ARGUMENTS

 - keyword argument :bass-octave. An integer that is an octave indicator
   (e.g. the 4 in 'C4). The method will only return any
   frequencies/note-names generated that fall in this octave. Default = 0.
 - keyword argument :low. A note-name symbol that is the lowest possible
   pitch of those returned. This argument further restricts the :bass-octave
   argument. Thus a :bass-octave value of 1 could be further limted to no
   pitches below :low 'DS1. Default = 'A0.
 - keyword argument :high. A note-name symbol that is the highest possible
   pitch of those returned. This argument further restricts the :bass-octave
   argument. Thus a :bass-octave value of 1 could be further limted to no
   pitches above :high 'FS1. Default = 'G3.
 - keyword argument :round. T or NIL to indicate whether the frequencies
   returned are rounded to integer values. T = round. Default = T.
 - keyword argument :warn. T or NIL to print a warning when no bass can be
   created from the specified frequencies/note-names. T = print
   warning. Default = T.
 - keyword argument :return-notes. T or NIL to indicate whether the
   resulting pitches should be returned as note-names instead of
   frequencies. T = return as note-names. Default = NIL. 
 - keyword argument :scale. A variable pointing to the scale to which any
   translation of frequencies into note-names symbols should take place. By
   default this value is set to cm::*scale*, which is automatically set by
   slippery chicken to 'quarter-tone at initilisation. To return e.g. pitches
   rounded to chromatic note-names set this argument to cm::*chromatic-scale*. 

RETURN VALUE

 Returns a list of frequencies by default.

 Setting the :return-notes keyword argument to T will cause the method to
 return note-name symbols instead.

EXAMPLE

;; Simple usage with default keyword argument values
(ring-mod-bass '(261.63 293.66 329.63 349.23))

=> (28 29 32)

;; Return as note-names instead, in quarter-tone scale by default
(ring-mod-bass '(261.63 293.66 329.63 349.23)
               :return-notes t)

=> (A0 BF0 BQS0) 

;; Set the :scale argument to cm::*chromatic-scale* to return equal-tempered
;; note-name symbols instead
(ring-mod-bass '(261.63 293.66 329.63 349.23)
               :return-notes t
               :scale cm::*chromatic-scale*)

=> (A0 BF0 C1)

;; Return pitches from bass octave 1 rather than default 0
(ring-mod-bass '(261.63 293.66 329.63 349.23 392.00)
               :return-notes t
               :scale cm::*chromatic-scale*
               :bass-octave 1)

=> (CS1 D1 F1 G1 A1 B1)

;; Further limit the notes returned by setting :low and :high values
(ring-mod-bass '(261.63 293.66 329.63 349.23 392.00)
               :return-notes t
               :scale cm::*chromatic-scale*
               :bass-octave 1
               :low 'e1
               :high 'a1)

=> (F1 G1)

;; Set the :round argument to NIL to return decimal-point frequencies
(ring-mod-bass '(261.63 293.66 329.63 349.23 392.00)
               :bass-octave 1
               :low 'e1
               :high 'a1
               :round NIL)

=> (42.76999999999998 43.45666666666667 43.80000000000001 49.16999999999999)

;; The method prints a warning by default if no bass note can be made
(ring-mod-bass '(261.63))

=>
NIL
WARNING: set-palette::ring-mod-bass: can't get bass from (261.63)!

;; This warning can be supressed by setting the :warn argument to NIL
(ring-mod-bass '(261.63) :warn nil)

=> NIL

SYNOPSIS

(defun ring-mod-bass (freqs &key (bass-octave 0) (low 'a0) (high 'g3) (round t)
                      (warn t) (return-notes nil) (scale cm::*scale*))

set-palette/set-palette-from-ring-mod [ Functions ]

[ Top ] [ set-palette ] [ Functions ]

FUNCTION

 Create a new set-palette object from the pitches returned by applying ring 
 modulation procedures (difference and sum tones of partials).

ARGUMENTS

 - A note-name symbol that is the central pitch from which we perform the
   ring-modulation.  See :partials below.
 - A symbol that is to be the ID for the new set-palette object.

OPTIONAL ARGUMENTS

 - keyword argument :partials. A list of integers that are the partials
   which the method uses to ring modulate.  We create partials ascending
   from the reference-note but also ascending from a fundamental calculated
   so that reference-note would be the highest partial in the partials list.
   E.g. if reference-note were 'a4 (440Hz) and :partials was '(1 2) we'd
   have partial frequencies of 440 and 880, as these are the ascending
   partials 1 and 2 from 440, but also have 220, as that is the fundamental
   for which 440 would be the highest partial out of (1 2).  
   Default = '(1 3 5 7).
 - keyword argument :warn-no-bass. T or NIL to indicate whether to issue a
   warning when ring-mod-bass fails to find suitable bass notes for the
   generated sets. T = warn. Default = T.
 - keyword argument :do-bass. T or NIL to indicate whether to add notes
   created by the ring-mod-bass function to the resulting set-palette
   obect. T = create and add bass notes. Default = T.
 - keyword argument :remove-octaves. T or NIL to indicate whether to remove
   the upper instances of any octave-equivalent pitches from the resulting
   set-palette object. T = remove. Default = NIL.
 - keyword argument :min-bass-notes. An integer that is the minimum number
   of bass notes to be generated and added to the resulting set-palette
   object. Default = 1.
 - keyword argument :ring-mod-bass-octave. An integer that is the MIDI
   octave reference number (such as the 4 in 'C4), indicating the octave
   from which the bass note(s) are to be taken.

RETURN VALUE

 A set-palette object.

EXAMPLE

;; Simple useage with default keyword argument values
(set-palette-from-ring-mod 'a4 'spfrm-test)

=>
SET-PALETTE: 
PALETTE: 
RECURSIVE-ASSOC-LIST: recurse-simple-data: T
                      num-data: 21
                      linked: NIL
                      full-ref: NIL
ASSOC-LIST: warn-not-found T
CIRCULAR-SCLIST: current 0
SCLIST: sclist-length: 21, bounds-alert: T, copy: T
LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL
NAMED-OBJECT: id: SPFRM-TEST, tag: NIL, 
data: (
[...]

SYNOPSIS

(defun set-palette-from-ring-mod (reference-note id &key
                                  (warn-no-bass t)
                                  (do-bass t)
                                  remove-octaves
                                  (min-bass-notes 1)
                                  (ring-mod-bass-octave 0)
                                  (partials '(1 3 5 7)))

set-palette/set-palette-p [ Functions ]

[ Top ] [ set-palette ] [ Functions ]

FUNCTION

 Test whether a given object is a set-palette object.

ARGUMENTS

 - A lisp object

EXAMPLE

(let ((msp (make-set-palette 
            'test
            '((1 ((1
                   ((bf1 ef2 aqf2 c3 e3 gqf3 gqs3 cs4 d4 g4 a4 cqs5 dqf5 gs5 b5)))
                  (2
                   ((bf1 d2 fqf2 fqs2 b2 c3 f3 g3 bqf3 bqs3 fs4 gs4 a4 cs5 gqf5)
                    :subsets
                    ((tc1 (d2 g3 cs5))
                     (tc2 (eqs2 f3 bqf3))
                     (tc3 (b2 bqs3 gqf5)))))))
              (2 ((1 ((1 1) :transposition 5))
                  (2 ((1 2) :transposition 5))))
              (3 ((1 ((1 1) :transposition -2))
                  (2 ((1 2) :transposition -2))))))))
  (set-palette-p msp))

=> T

RETURN VALUE

 t or nil

SYNOPSIS

(defun set-palette-p (thing)