ISF Logo   IS Forum
Forum Index Register Members List Events Mark Forums Read Help

Go Back   International Skeptics Forum » General Topics » History, Literature, and the Arts
 


Welcome to the International Skeptics Forum, where we discuss skepticism, critical thinking, the paranormal and science in a friendly but lively way. You are currently viewing the forum as a guest, which means you are missing out on discussing matters that are of interest to you. Please consider registering so you can gain full use of the forum features and interact with other Members. Registration is simple, fast and free! Click here to register today.
Reply
Old 21st January 2018, 03:46 AM   #81
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
http://www.nybooks.com/contributors/adam-shatz/


As someone who has used pitch structures to build pieces in more or less straightforward ways, I have mixed feelings about mystifications of various kinds.

Here there are multiple levels of ********, plus there is real music and a real life. You can't really tease it all out, except to note that the critic adds a level of incomprehension, as far as I can tell.

I mean that Wadada Leo Smith can play the trumpet. He has a nice tone. I didn't hear a lot of substance in his Monk pieces, the 2 I listened to.

The rest is woolly mystification and image-building (or just acting naturally) and being a natural man or something.

He's playing with Iver, a pianist who also seems to lack substance -- only every time I've listened.

These are so-so musicians who make for good critical write-ups. Their projects have some intellectual charisma.

There's not much to say about Smith's "score" which is the painting of one his "Symphonies." I use the sniffy scare quotes because the painting is a score of a symphony in name only. It's not a fraud because it's not a deception. It's obviously not a score of a symphony.

We're not in a zone of fraud, we're in a sort of gauzy zone of image, which the musically illiterate critic is buying into. Seems not unusual for the "free jazz" scene, from what I can tell over the years. Words that sound serious like "Unit Structure" and "Symphony". Upon examination, the substance disappears.

I don't understand how this sad game continues.

Too bad we live in a time when people can't just enjoy listening to someone playing nice spacey smokey b.s. on a trumpet. He hasta puff it up to earn a living, I guess.

Not a symphony, though. That's what the word pretentious means.

Last edited by calebprime; 21st January 2018 at 03:53 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 11th February 2018, 01:56 PM   #82
Dani
Master Poster
 
Dani's Avatar
 
Join Date: Feb 2007
Location: Sometimes
Posts: 2,044
Originally Posted by calebprime View Post
Dani, I was looking for the actual scales, beyond only pitches that are excluded. Figuring out which single pitches are excluded is first step. Then figure out which combinations of pitches are excluded. Then which scales are possible. (Conventional, according to this arbitrary (but good!) definition.

This would be a bit of work, especially if one hasn't been doing it in a while. It gets better with practice.





Microtonal Scales to the rescue!

I hadn't realized how incredibly good and useful 69Dodge's program is for exactly this, as well as every other musical calculation. And freeware, too. amazing.


Conventional 1-octave scales for given situations:

(note: program gives only names of scale-groups, so everything is called Lydian, for example.)

Code:
Bb, D, F, Ab:

Octatonic-Diminished  Harmonic Minor       Ascending Melodic Minor  
(A# B C# D E F G G#)  (Bb B D Eb F Gb Ab)  (Bb C D Eb F Gb Ab)      
                                           (Bb C D E F G Ab)        

Harmonic Major        Lydian                                        
(A# B C# D F F# G#)   (Bb C D Eb F G Ab)                            
(Bb B D Eb F G Ab)    




Bb, D, Ab:

Octatonic-Diminished  Harmonic Minor       Ascending Melodic Minor  
(A# B C# D E F G G#)  (Bb B D Eb F Gb Ab)  (A# B C# D E F# G#)      
                                           (Bb C D Eb F Gb Ab)      
                                           (Bb C D E F G Ab)        

Harmonic Major        Lydian               Whole-Tone               
(A# B C# D F F# G#)   (Bb C D Eb F G Ab)   (A# C D E F# G#)         
(Bb B D Eb F G Ab)                                                  




Bb, C#, D, A:      

Harmonic Minor     Harmonic Major      Augmented 1-3     
(Bb C# D E F G A)  (Bb C# D E F# G A)  (Bb C# D F Gb A)  




Bb, C#, D, Ab:

Octatonic-Diminished  Ascending Melodic Minor  Harmonic Major       
(A# B C# D E F G G#)  (A# B C# D E F# G#)      (A# B C# D F F# G#)  



Bb, B, C#, D:

Octatonic-Diminished  Harmonic Minor      Ascending Melodic Minor  
(A# B C# D E F G G#)  (A# B C# D E F# G)  (A# B C# D E F# G#)      

Harmonic Major                                                     
(A# B C# D F F# G#)

Incidentally, the competence you'd develop with scales in this kind of work is exactly the same as if you'd taken The Lydian Chromatic Concept at NEC, except stripped of all the good and bad stuff that George Russell brought to it. This approach is strictly logical -- it's trivial for a computer. I spoke with one sax player who had taken a little Lydian Chrom. and boy was she hopelessly confused about helping herself with theory! A little knowledge is temporarily very confusing for some students, I guess. I don't mean to sound snotty, but it was strange to see her tie herself in knots trying to understand what scales to play on chords.
I didn't even know about the Lydian Chromatic Concept. Imagine! I'm also confused. Very confused. Is there anything to the Lydian Chromatic Concept, aside from viewing things from a different perspective, compared to the Ionian Chromatic Concept*?

Also. Why does the fourth sound so bad over a major chord? I mean, the real reason! Ok: it's a half step away from the major third, it's also the most distant fifth if you stack perfect fifths on top of the root, and there's a potential tritone with the seventh (which is more stable... again... because it's much closer in the circle/cycle of fifths?).

Is there a link for this software you're talking about?

*Dani neologism taken from Cluelessland.
Dani is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 12th February 2018, 05:48 AM   #83
varwoche
Penultimate Amazing
 
varwoche's Avatar
 
Join Date: Feb 2004
Location: Puget Sound
Posts: 11,071
Random food for thought from Quincy Jones on Coltrane:

Originally Posted by Jones
Every time I used to see Coltrane he’d have Nicolas Slonimsky’s book ... Everything that Coltrane ever played was in that thesaurus. In fact, right near the front of that book, there’s a 12-tone example — it’s “Giant Steps.” Everyone thinks Coltrane wrote that, he didn’t. It’s Slonimsky. That book started all the jazz guys improvising in 12-tone ... You can’t get further out than 12-tone, and “Giant Steps” is 12-tone.
Atonality enters into the interview.
__________________
To survive election season on a skeptics forum, one must understand Hymie-the-Robot.
varwoche is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 12th February 2018, 06:20 AM   #84
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
see other thread. sorry Q, Giant Steps just ain't 12-tone. Either in tech or in spirit or any kind of broad strokes.

It is built on the elaboration of a symmetrical scheme, the augmented chord Eb-B-G. Some people call this a "3-tonic" system.

But that's not 12-tone, not even close.

You can't even turn the end melody g,f,bb -- b,a,d -- eb,db,db -- g,f,bb into 12-tone.

Last edited by calebprime; 12th February 2018 at 06:24 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 12th February 2018, 06:24 AM   #85
varwoche
Penultimate Amazing
 
varwoche's Avatar
 
Join Date: Feb 2004
Location: Puget Sound
Posts: 11,071
Originally Posted by calebprime View Post
see other thread. sorry Q, Giant Steps just ain't 12-tone. Either in tech or in spirit or any kind of broad strokes.

It is built on the elaboration of a symmetrical scheme, the augmented chord Eb-B-G. Some people call this a "3-tonic" system.

But that's not 12-tone, not even close.
I'm too clueless to express an opinion, other than this comports with my limited understanding.
__________________
To survive election season on a skeptics forum, one must understand Hymie-the-Robot.
varwoche is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 12th February 2018, 06:26 AM   #86
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
QJ is certainly right about the importance of the influence of Slonimsky, but even so, it wouldn't take away from Coltrane's originality or his achievement. He was a player, not a theoretician.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 12th February 2018, 08:09 AM   #87
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Originally Posted by Dani View Post
I didn't even know about the Lydian Chromatic Concept. Imagine! I'm also confused. Very confused. Is there anything to the Lydian Chromatic Concept, aside from viewing things from a different perspective, compared to the Ionian Chromatic Concept*?

Also. Why does the fourth sound so bad over a major chord? I mean, the real reason! Ok: it's a half step away from the major third, it's also the most distant fifth if you stack perfect fifths on top of the root, and there's a potential tritone with the seventh (which is more stable... again... because it's much closer in the circle/cycle of fifths?).

Is there a link for this software you're talking about?

*Dani neologism taken from Cluelessland.


software: save the code in the spoiler. This is the most recent source code for Microtonal Scales.



Code:
#lang racket/gui

(require racket/gui/base
         racket/random
;         racket/unsafe/ops
         (only-in rnrs/base-6 mod)
;         (only-in framework finder:get-file
;                            finder:put-file)
         )

(define-namespace-anchor namespace-anchor)
(define the-namespace (namespace-anchor->namespace namespace-anchor))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;(define-setting modulus 24)
;(define-setting length-min 5)  ; minimum number of notes in scale
;(define-setting length-max 8)  ; maximum number of notes in scale
;
;; wolf intervals, between any two notes in scale
;(define-setting wolves '(13 15))
;
;(define-setting wolf-max 5)  ; this many wolves are ok, but no more
;
;(define-setting distance-2-min 1) ; minimum difference between any 2 consecutive notes in scale
;(define-setting distance-3-min 3) ; minimum difference between the lowest and highest notes
;                                  ;   of any 3 consecutive notes in scale
;; never use these notes
;(define-setting bad-notes '(1 13 23))
;
;; Scale must not contain any of these cells.
;; Each cell is specified as a list of numbers.
;; The first number is the range, i.e., the number
;; of consecutive notes in the scale that are
;; considered together when checking for the presence
;; of the cell.  The rest of the numbers in the list
;; are the notes of the cell. 
;(define-setting bad-cells '((3 0 3 4)))
;
;; only these intervals are allowed between consecutive notes in scale
;; (but if the list is empty, all intervals are allowed)
;(define-setting allowed-intervals '(1 3 5))
;
;; #t : scale must contain at least one of each allowed interval
;; #f : scale need not contain every allowed interval
;(define-setting require-all-allowed-intervals #t)
;
;; #t : don't display scale if adding any note to it results in some other displayed scale
;; #f : do
;(define-setting require-completeness #t)
;
;; if you don't care about balance, set both balance-in-min and balance-out-min to 0
;(define-setting balance-notes '(0 2 4 6 8 10 12 14 16 18 20 22))
;(define-setting balance-in-min  1)  ; at least this many notes in scale must come from balance-notes
;(define-setting balance-out-min 3)  ; at least this many notes in scale must come from outside balance-notes
;
;; #t : display multiple spellings if they're all equally good
;; #f : never display more than one spelling
;(define-setting multiple-spellings #f)
;
;; if more than this number of scales are found,
;; don't display them by default
;(define-setting scales-max 100)
;
;; allowed values are: length packing wolves balance distance rotation
;; any number of them, in any order
;; earlier ones are more important than later ones
;; any of them may be immediately followed by an asterisk to indicate reverse order
;; for example, length* means longer first instead of the usual shorter first
;(define-setting sort-order '(packing))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define settings '())

; the (set! symbol ...) is to convince the compiler that the variable is not constant,
; so that it can be changed later by copy-settings-from-gui-to-vars.
(define-syntax-rule (define-setting symbol label type default)
  (begin
    (define symbol 'whatever)
    (set! symbol 'whatever)
    (set! settings (cons (list 'symbol label 'type default) settings))))

(define setting-symbol first)
(define setting-label second)
(define setting-type third)
(define setting-default fourth)

(define-setting modulus                       "modulus:"                                         number       "24")
(define-setting wolves                        "wolf intervals (between any two notes):"          list         "13 15")
(define-setting multiple-spellings            "display multiple spellings:"                      boolean      #f)
(define-setting scale-tolerance               "acceptable error when naming scales (cents):"     number       "0")
(define-setting sort-order                    "sort order:"                                      list         "length rotation wolves packing")
(define-setting multi-column                  "abbreviated multiple-column output:"              boolean      #f)
(define-setting output-format                 "output format:"                                   choice       '("numbers" "letters" "intervals" "keyboard"))
(define-setting column-count                  "number of output columns:"                        number       "3")

(define-setting keyboard-notes-raw            "keyboard notes:"                                  list         "")
(define-setting first-note                    "first note of scale:"                             number       "0")
(define-setting length-min                    "minimum scale length:"                            number       "6")
(define-setting length-max                    "maximum scale length:"                            number       "8")
(define-setting wolf-min                      "minimum number of wolves:"                        number       "0")
(define-setting wolf-max                      "maximum number of wolves:"                        number       "1")
(define-setting bad-cells-raw                 "bad cells:"                                       list-of-list "(4 0 1 2)")
(define-setting bad-cell-max                  "maximum number of bad cells:"                     number       "0")
(define-setting good-cells-raw                "good cells:"                                      list-of-list "")
(define-setting good-cell-min                 "minimum number of good cells:"                    number       "0")
(define-setting distance-2-min                "minimum interval between consecutive notes:"      number       "2")
(define-setting distance-3-min                "minimum interval between alternate notes:"        number       "5")
(define-setting require-completeness          "require completeness:"                            boolean      #t)
(define-setting bad-intervals                 "bad intervals (between consecutive notes):"       list         "")
(define-setting bad-interval-max              "maximum number of bad intervals:"                 number       "0")
(define-setting good-intervals                "good intervals (between consecutive notes):"      list         "")
(define-setting good-interval-min             "minimum number of good intervals:"                number       "0")
(define-setting allowed-intervals             "allowed intervals between consecutive notes:"     list         "")
(define-setting require-all-allowed-intervals "require all allowed intervals:"                   boolean      #f)
(define-setting required-notes                "required notes:"                                  list         "")
(define-setting forbidden-notes               "forbidden notes:"                                 list         "1 13 15 23")
(define-setting balance-notes                 "balance notes:"                                   list         "0 2 4 6 8 10 12 14 16 18 20 22")
(define-setting balance-in-min                "minimum number of notes from balance:"            number       "1")
(define-setting balance-out-min               "minimum number of notes not from balance:"        number       "1")
(define-setting scales-max                    "maximum number of scales to display:"             number       "100")

(define-setting scale-contents2               "scale:"                                           string       "")
(define-setting scale-interpretation          "scale is specified as:"                           choice       '("notes" "intervals" "name"))
(define-setting reorder-notes                 "put notes in order before looking up name:"       boolean      #t)
(define-setting display-supersets             "display all known supersets of scale:"            boolean      #f)

(define-setting scale-contents3               "scale:"                                           list         "0")
(define-setting common-notes                  "allowed common notes:"                            list         "")
(define-setting max-additional-common-notes   "maximum number of additional common notes:"       number       "0")
(define-setting complement-source             "source of possible complements:"                  choice       '("the scale above" "all named scales"))

(define-setting motif                         "motif:"                                           list         "")
(define-setting multiplier-special            "evenly spaced multiplier:"                        boolean      #f)
(define-setting multiplier                    "multiplier:"                                      list         "0")
(define-setting multiplicand-order            "order of multiplication:"                         choice       '("motif times multiplier" "multiplier times motif" "both"))
(define-setting from-cycle                    "map from cycle:"                                  list         "1")
(define-setting to-cycle                      "map to cycle:"                                    list         "1")
(define-setting mm-order                      "order of operations:"                             choice       '("map, then multiply" "multiply, then map"))
(define-setting identify-results              "identify results:"                                boolean      #f)
(define-setting from-table                    "map from table:"                                  list-box     '())
(define-setting to-table                      "map to table:"                                    list-box     '())

(define-setting row-length                    "row length:"                                      number       "12")
(define-setting mof-bad-cells-raw             "bad cells:"                                       list-of-list "")
(define-setting mof-bad-cell-max              "maximum number of bad cells:"                     number       "0")
(define-setting mof-good-cells-raw            "good cells:"                                      list-of-list "")
(define-setting mof-good-cell-min             "minimum number of good cells:"                    number       "0")
(define-setting mof-bad-intervals             "bad intervals (between consecutive notes):"       list         "")
(define-setting mof-bad-interval-max          "maximum number of bad intervals:"                 number       "0")
(define-setting mof-good-intervals            "good intervals (between consecutive notes):"      list         "")
(define-setting mof-good-interval-min         "minimum number of good intervals:"                number       "0")
(define-setting distinct-interval-min         "minimum number of different intervals:"           number       "")
(define-setting interval-repetition-max       "maximum number of same consecutive intervals:"    number       "")
(define-setting self-eq-standard              "self-equivalence filter - standard:"              boolean      #t)
(define-setting self-eq-5m                    "self-equivalence filter - 5m:"                    boolean      #f)
(define-setting self-eq-tolerance             "self-equivalence filter tolerance:"               number       "0")
(define-setting filter-duplicates             "remove near-duplicates:"                          boolean      #f)
(define-setting duplicate-tolerance           "near-duplicate tolerance:"                        number       "0")
(define-setting wrap-row                      "wrap when counting cells and intervals:"          boolean      #t)
(define-setting spacing-row-length            "virtual row length, for computing spacing:"       number       "13")
(define-setting motif-length                  "motif length:"                                    number       "12")
(define-setting standard-transforms           "look for standard transformations of motif:"      boolean      #t)
(define-setting 5m-transforms                 "look for 5m transformations of motif:"            boolean      #f)
(define-setting spacing-min                   "minimum spacing:"                                 number       "")
(define-setting spacing-max                   "maximum spacing:"                                 number       "")
(define-setting spacing-error-min             "minimum number of violations of min/max spacing:" number       "0")
(define-setting spacing-error-max             "maximum number of violations of min/max spacing:" number       "0")
(define-setting 1-space-min                   "minimum number of 1-spaces:"                      number       "0")
(define-setting 1-space-max                   "maximum number of 1-spaces:"                      number       "0")
(define-setting motif-min                     "minimum number of occurrences of motif in row:"   number       "")
(define-setting wrap-spacing                  "wrap when computing spacing:"                     boolean      #t)
(define-setting rows-max                      "maximum number of rows to display:"               number       "100")
(define-setting results-file                  "file of results to search within:"                string       "")

(set! settings (reverse settings))

(define (padding str len)
  (make-string (- len (string-length str))
               #\space))

(define (setting-length s)
  (string-length (setting-label s)))

(define (display-setting s len)
  (let ((label (setting-label s)))
    (display (padding label len))
    (display label))
  (display #\space)
  (display (eval (setting-symbol s) the-namespace)))

(define first-setting
  (vector 'modulus 'keyboard-notes-raw 'scale-contents2 'scale-contents3 'motif 'row-length 'the-end))

(define (get-settings tab)
  (define (not-yet n)
    (lambda (s) (not (eq? (setting-symbol s) (vector-ref first-setting n)))))
  (takef (dropf settings (not-yet tab))
         (not-yet (+ 1 tab))))

(define (display-settings tab)
  (let* ((ss (append (get-settings 0) (get-settings tab)))
         (len (apply max (map setting-length ss))))
    (for-each (lambda (s)
                  (display-setting s len)
                  (newline))
                ss)
    (newline)))

(define gui-fields (make-hash))

(define the-frame (new frame% (label "microtonal scales")))

(define the-tabs (new tab-panel%
                      (parent the-frame)
                      (choices '("common" "generate" "identify" "complement" "mmm" "mof"))
                      (callback (lambda (tp e)
                                  (send tp change-children
                                        (lambda (x)
                                          (case (send tp get-selection)
                                            ((0) (list common-panel))
                                            ((1) (list generate-panel))
                                            ((2) (list identify-panel))
                                            ((3) (list complement-panel))
                                            ((4) (list mmm-panel))
                                            ((5) (list mof-panel)))))))))

(send the-tabs set-selection 1)

(define (make-tab-panel show?)
  (new vertical-panel%
       (parent the-tabs)
       (style (if show? '() '(deleted)))))

(define (make-tab-pane p)
  (new horizontal-pane%
       (parent p)))

(define common-panel     (make-tab-panel #f))
(define generate-panel   (make-tab-panel #t))
(define identify-panel   (make-tab-panel #f))
(define complement-panel (make-tab-panel #f))
(define mmm-panel        (make-tab-panel #f))
(define mof-panel        (make-tab-panel #f))

(define common-pane     (make-tab-pane common-panel))
(define generate-pane   (make-tab-pane generate-panel))
(define identify-pane   (make-tab-pane identify-panel))
(define complement-pane (make-tab-pane complement-panel))
(define mmm-pane        (make-tab-pane mmm-panel))
(define mof-pane        (make-tab-pane mof-panel))

(define (make-column p (subcolumn #f))
  (let* ((column (new vertical-pane%
                      (parent p)
                      (border (if subcolumn 0 5))))
         (column-top (new horizontal-pane%
                          (parent column)
                          (stretchable-height subcolumn))))
    (let ((labels (new vertical-pane%
                       (parent column-top)
                       (stretchable-width #f)))
          (fields (new vertical-pane%
                       (parent column-top)
                       (alignment '(left center)))))
      (list column labels fields))))

(define column-whole first)
(define column-labels second)
(define column-fields third)

(define column-0-0 (make-column common-pane))
(define column-0-1 (make-column common-pane))
(define column-1-0 (make-column generate-pane))
(define column-1-1 (make-column generate-pane))
(define column-2   (make-column identify-pane))
(define column-3   (make-column complement-pane))
(define column-4-0a (make-column mmm-pane))
(define column-4-0b (make-column (column-whole column-4-0a) #t))
(define column-4-1 (make-column mmm-pane))
(define column-5-0 (make-column mof-pane))
(define column-5-1 (make-column mof-pane))

(define-values (check-box-height text-field-height choice-height)
  (let ((frame (new frame% (label "test"))))
    (let ((cb (new check-box% (parent frame) (label "")))
          (tf (new text-field% (parent frame) (label #f)))
          (ch (new choice% (parent frame) (label #f) (choices '("hi")))))
      (let ((cb-margin (send cb vert-margin))
            (tf-margin (send tf vert-margin))
            (ch-margin (send ch vert-margin)))
        (let-values (((dummy1 cb-height) (send cb get-graphical-min-size))
                     ((dummy2 tf-height) (send tf get-graphical-min-size))
                     ((dummy3 ch-height) (send ch get-graphical-min-size)))
          (let ((max-height (max (+ cb-margin cb-height)
                                 (+ tf-margin tf-height)
                                 (+ ch-margin ch-height))))
            (values (- max-height cb-margin)
                    (- max-height tf-margin)
                    (- max-height ch-margin))))))))

(define (add-gui-field setting column)
  (let ((labels-pane (column-labels column))
        (fields-pane (column-fields column)))
    (let* ((field-label (new message%
                             (parent (new pane%
                                          (parent labels-pane)
                                          (alignment '(right center))))
                             (label (setting-label setting))))
           (field-class (case (setting-type setting)
                          ((boolean)                         check-box%)
                          ((number string list list-of-list) text-field%)
                          ((choice)                          choice%)
                          ((list-box)                        list-box%)))
           (the-field (cond
                        ((eq? field-class check-box%) (new check-box%
                                                           (parent fields-pane)
                                                           (label "")
                                                           (min-height check-box-height)))
                        ((eq? field-class text-field%) (new text-field%
                                                            (parent fields-pane)
                                                            (label #f)
                                                            (min-height text-field-height)))
                        ((eq? field-class choice%) (new choice%
                                                        (parent fields-pane)
                                                        (label #f)
                                                        (choices (setting-default setting))
                                                        (min-height choice-height)))
                        ((eq? field-class list-box%) (new list-box%
                                                         (parent fields-pane)
                                                         (label #f)
                                                         (style '(multiple))
                                                         (choices (setting-default setting)))))))
      (when (member field-class (list check-box% text-field%))
        (send the-field set-value (setting-default setting)))
      (hash-set! gui-fields (setting-symbol setting) the-field))))

(let recur ((ss settings)
            (col column-0-0))
  (when (pair? ss)
    (let ((s (car ss)))
      (add-gui-field s col)
      (recur (cdr ss) (case (setting-symbol s)
                        ((column-count)      column-1-0)
                        ((good-cell-min)     column-1-1)
                        ((scales-max)        column-2)
                        ((display-supersets) column-3)
                        ((complement-source) column-4-0a)
                        ((identify-results)  column-4-0b)
                        ((to-table)          column-5-0)
                        ((wrap-row)          column-5-1)
                        (else                col))))))

(define (make-help-field col txt)
  (let ((help-field (new text-field%
                         (parent (column-whole col))
                         (label #f)
                         (style '(multiple))
                         (enabled #f))))
    (send help-field set-value txt)))

(make-help-field column-0-1 "Sort order may be any combination of:\n\n   length packing wolves\n   balance distance rotation\n\nAny of them may be immediately followed by an asterisk, in which case the usual order will be reversed.  For example, length* means longer scales will come first, instead of shorter ones.")

(make-help-field column-1-0 "Each cell is written as a parenthesized list of numbers.  The first number is the number of consecutive notes of the scale being considered within which the cell must be found if it is to count.  The rest of the numbers are the notes of the cell.")

(make-help-field column-4-1 "The fields 'map from cycle' and 'map to cycle' can each contain one, two, or three numbers.  One number means just that number.  Two numbers means all numbers between the two (including the two).  Three numbers means all numbers you get by starting from the first and repeatedly adding the third until reaching the second.\n\nIf 'evenly spaced multiplier' is unchecked, the 'multiplier' field should contain the list of pitches to be multiplied by the motif.  If checked, the 'multiplier' field indirectly represents a list of pitches.  It should contain three numbers: the first pitch of the list, the spacing between successive pitches, and the number of pitches.")

(define (nesting-level x)
  (cond
    ((pair? x) (+ 1 (nesting-level (car x))))
    ((null? x) 1)
    (else 0)))

(define (increase-nesting-level str n)
  (string-append (make-string n #\( )
                 str
                 (make-string n #\) )))

(define (nest str n)
  (let ((x (read (open-input-string str))))
    (if (eof-object? x)
        (if (zero? n) 0 '())
        (read (open-input-string (increase-nesting-level str (- n (nesting-level x))))))))

(define (nest-appropriately val type)
  (case type
    ((string boolean
      choice list-box)    val)
    ((number)       (nest val 0))
    ((list)         (nest val 1))
    ((list-of-list) (nest val 2))))  

(define (get-field-value sym)
  (let ((f (hash-ref gui-fields sym)))
    (cond
      ((is-a? f choice%)         (send f get-string-selection))
      ((is-a? f list-box%)       (send f get-selections))
      ((or (is-a? f text-field%)
           (is-a? f check-box%)) (send f get-value)))))

(define (set-list-box-selections box ns)
  (if (null? ns)
      (when (positive? (send box get-number))
        (send box set-selection 0)
        (send box select 0 #f))
      (begin
        (send box set-selection (car ns))
        (for-each (lambda (n) (send box select n))
                  (cdr ns)))))

(define (set-field-value sym val)
  (let ((f (hash-ref gui-fields sym)))
    (cond
      ((is-a? f choice%)         (send f set-string-selection val))
      ((is-a? f list-box%)       (set-list-box-selections f val))
      ((or (is-a? f text-field%)
           (is-a? f check-box%)) (send f set-value val)))))

(define (copy-settings-from-gui-to-vars)
  (for-each (lambda (s)
              (let* ((sym (setting-symbol s))
                     (val (nest-appropriately (get-field-value sym) (setting-type s))))
                (eval `(set! ,sym ',val) the-namespace)))
            settings))

(define (get-data-from-gui)
  (map (lambda (s)
         (let ((sym (setting-symbol s)))
           (list sym (get-field-value sym))))
       settings))

(define (set-gui-from-data data)
  (for-each (lambda (x)
              (set-field-value (car x) (cadr x)))
            data))

; writer is a function of one argument, an output port, and writes stuff to it
(define (save-to-file writer)
  (let ((file (put-file)))
    (when file
      (call-with-output-file file writer #:mode 'text #:exists 'replace))))

; reader is a function of one argument, an input port, and reads stuff from it
(define (load-from-file reader)
  (let ((file (get-file)))
    (when file
      (call-with-input-file file reader))))

(define (write-list lst p)
  (displayln "(" p)
  (for-each (lambda (x) (writeln x p))
            lst)
  (displayln ")" p))

(define (save-settings-to-file)
  (save-to-file (lambda (p) (write-list (get-data-from-gui) p))))

(define (load-settings-from-file)
  (load-from-file (lambda (p) (set-gui-from-data (read p)))))

(define (write-results p)
  (write-list settings-in-use p)
  (write-list found-scales p))  

(define (normalize-results-path path)
  (path->string (simple-form-path path)))

(define (set-loaded-results-path path set-results-file)
  (let ((s (normalize-results-path path)))
    (set! loaded-results-path s)
    (when set-results-file
      (set-field-value 'results-file s))))

(define (read-results path button-pressed)
  (call-with-input-file path
    (lambda (p)
      (let ((data (read p)))
        (when button-pressed
          (set-gui-from-data data)))
      (set! loaded-results (read p))))
  (set-loaded-results-path path button-pressed))

(define (save-results-to-file)
  (save-to-file write-results))

(define (load-results-from-file)
  (let ((file (get-file)))
    (when file
      (read-results file #t))))

(define (save-and-load-results)
  (let ((file (put-file)))
    (when file
      (call-with-output-file file write-results #:mode 'text #:exists 'replace)
      (set-gui-from-data settings-in-use)
      (set! loaded-results found-scales)
      (set-loaded-results-path file #t))))

(define (clear-results)
  (set-field-value 'results-file "")
  (set! loaded-results '())
  (set! loaded-results-path ""))

(define please-stop #f)

(define stop-buttons '())

(define (set-going-state b)
  (for-each (lambda (button) (send button enable b))
            stop-buttons)
  (for-each (lambda (button) (send button enable (not b)))
            other-buttons))

(define (make-go-button p f)
  (new button%
       (parent p)
       (label "go")
       (callback (lambda (b e)
                   (set-going-state #t)
                   (set! please-stop #f)
                   (thread (lambda ()
                             (dynamic-wind
                              (lambda () 'whatever)
                              f
                              (lambda () (set-going-state #f)))))))))

(define (make-stop-button p)
  (let ((button  (new button%
                      (parent p)
                      (label "stop")
                      (enabled #f)
                      (callback (lambda (b e)
                                  (set! please-stop #t))))))
    (set! stop-buttons (cons button stop-buttons))
    button))

(define (make-buttons-pane p)
  (new horizontal-pane%
       (parent p)
       (alignment '(center center))
       (border 5)
       (stretchable-height #f)))

(define buttons-pane-0 (make-buttons-pane common-panel))

(define save-settings-button (new button%
                                  (parent buttons-pane-0)
                                  (label "save settings")
                                  (callback (lambda (b e)
                                              (save-settings-to-file)))))

(define load-settings-button (new button%
                                  (parent buttons-pane-0)
                                  (label "load settings")
                                  (callback (lambda (b e)
                                              (load-settings-from-file)))))

(define buttons-pane-1 (make-buttons-pane generate-panel))

(define generate-go-button (make-go-button buttons-pane-1 (lambda () (generate))))
(define generate-stop-button (make-stop-button buttons-pane-1))

(define buttons-pane-2 (make-buttons-pane identify-panel))

(define identify-button (new button%
                             (parent buttons-pane-2)
                             (label "identify")
                             (callback (lambda (b e)
                                         (set! please-stop #f)
                                         (thread identify)))))

(define list-button (new button%
                         (parent buttons-pane-2)
                         (label "list")
                         (callback (lambda (b e)
                                     (thread list-known-scales)))))

(define buttons-pane-3 (make-buttons-pane complement-panel))

(define complement-button (new button%
                               (parent buttons-pane-3)
                               (label "complement")
                               (callback (lambda (b e)
                                           (set! please-stop #f)
                                           (thread complement)))))

(define buttons-pane-4 (make-buttons-pane mmm-panel))

(define mmm-button (new button%
                        (parent buttons-pane-4)
                        (label "mmm")
                        (callback (lambda (b e)
                                    (set! please-stop #f) ; necessary if display-scales gets called
                                    (thread mmm)))))

(define buttons-pane-5 (make-buttons-pane mof-panel))

(define save-results-button (new button%
                                 (parent buttons-pane-5)
                                 (label "save results")
                                 (callback (lambda (b e)
                                             (save-results-to-file)))))

(define load-results-button (new button%
                                 (parent buttons-pane-5)
                                 (label "load results")
                                 (callback (lambda (b e)
                                             (load-results-from-file)))))

(define save-load-button (new button%
                              (parent buttons-pane-5)
                              (label "save and load results")
                              (callback (lambda (b e)
                                          (save-and-load-results)))))

(define clear-results-button (new button%
                                  (parent buttons-pane-5)
                                  (label "clear results")
                                  (callback (lambda (b e)
                                              (clear-results)))))

(define mof-go-button (make-go-button buttons-pane-5 (lambda () (mof))))
(define mof-stop-button (make-stop-button buttons-pane-5))

(define other-buttons (list save-settings-button
                            load-settings-button
                            generate-go-button
                            identify-button
                            list-button
                            complement-button
                            mmm-button
                            save-results-button
                            load-results-button
                            save-load-button
                            clear-results-button
                            mof-go-button))

; A note is represented as a nonnegative integer less than modulus.

; A scale is represented as a list of notes.  As it's being built,
;   it's in decreasing order.  Once it's complete, it's reversed
;   into increasing order before being added to 'found-scales'.
;   (Sort of.  See function note-comparer.)

(define found-scales '())   ; initially empty list, onto which scales are consed as they are found
(define allowed-notes '())  ; notes that may be included in a scale
(define bad-cells '())      ; bad cells, after being preprocessed
(define good-cells '())     ; good cells, after being preprocessed
(define keyboard-notes '())
(define keyboard #f)        ; vector, of length modulus, mapping notes to keyboard keys

(define (interval a b)
  (modulo (- b a) modulus))

; transpose note n by k, where modulus is m
(define (transpose-note m n k)
  (modulo (+ n k) m))

; transpose scale s by k, where modulus is m
(define (transpose-scale m s k)
  (map (lambda (n) (transpose-note m n k))
       s))

; invert note n, where modulus is m
(define (invert-note m n)
  (modulo (- n) m))

; invert scale s, where modulus is m
(define (invert-scale m s)
  (map (lambda (n) (invert-note m n))
       s))

(define (invert-scale-m s)
  (invert-scale modulus s))

(define note-names
  '#(("A"              )  ;  0
     ("A+"  "A#-" "Bb-")  ;  1
     ("A#"  "Bb"       )  ;  2
     ("A#+" "Bb+" "B-" )  ;  3
     ("B"              )  ;  4
     ("B+"  "C-"       )  ;  5
     ("C"              )  ;  6
     ("C+"  "C#-" "Db-")  ;  7
     ("C#"  "Db"       )  ;  8
     ("C#+" "Db+" "D-" )  ;  9
     ("D"              )  ; 10
     ("D+"  "D#-" "Eb-")  ; 11
     ("D#"  "Eb"       )  ; 12
     ("D#+" "Eb+" "E-" )  ; 13
     ("E"              )  ; 14
     ("E+"  "F-"       )  ; 15
     ("F"              )  ; 16
     ("F+"  "F#-" "Gb-")  ; 17
     ("F#"  "Gb"       )  ; 18
     ("F#+" "Gb+" "G-" )  ; 19
     ("G"              )  ; 20
     ("G+"  "G#-" "Ab-")  ; 21
     ("G#"  "Ab"       )  ; 22
     ("G#+" "Ab+" "A-" )  ; 23
))

; A name code represents, e.g., F#+, as
; a list of three numbers, one for the F,
; one for the # and one for the +.
;
;  first number: A through G are 0 through 6, respectively.
; second number: b is -1, # is +1, none is 0.
;  third number: - is -1, + is +1, none is 0.

(define code-values
  '((#\A . 0)
    (#\B . 1)
    (#\C . 2)
    (#\D . 3)
    (#\E . 4)
    (#\F . 5)
    (#\G . 6)))

; assumes name is properly capitalized
; i.e., first letter is capital, rest aren't
(define (name->code name)
  (let ((lst (string->list name)))
    (let ((letter (car lst))
          (accidentals (cdr lst)))
      (list
        (cdr (assoc letter code-values))
        (cond
          ((member #\b accidentals) -1)
          ((member #\# accidentals) +1)
          (else 0))
        (cond
          ((member #\- accidentals) -1)
          ((member #\+ accidentals) +1)
          (else 0))))))

(define (code->name code)
  (let ((x (car code))
        (y (cadr code))
        (z (caddr code)))
    (string-append
      (string (car (list-ref code-values x)))
      (case y
        ((-1) "b")
        ((+1) "#")
        (else ""))
      (case z
        ((-1) "-")
        ((+1) "+")
        (else "")))))

; same structure as note-names, i.e. vector of lists,
; except with each name replaced by the corresponding code
(define name-codes
  (vector-map (lambda (name-list) (map name->code name-list))
    note-names))

(define note-values
  '((#\A .  0)
    (#\B .  4)
    (#\C .  6)
    (#\D . 10)
    (#\E . 14)
    (#\F . 16)
    (#\G . 20)
    (#\# .  2)
    (#\b . -2)
    (#\+ .  1)
    (#\- . -1)))

(define (string->note s)
  (apply +
    (map (lambda (c) (cdr (assoc c note-values)))
         (let ((cs (string->list s)))
           (cons (char-upcase (car cs))
             (map char-downcase (cdr cs)))))))

(define (minimum less xs)
  (foldl (lambda (x m) (if (less x m) x m))
    (car xs) (cdr xs)))

; returns a function that compares two lists lexicographically,
;   returning true if the first precedes the second.
; corresponding elements of the lists are compared using 'less'.
(define (comparer less)
  (letrec ((f (lambda (a b)
                (or (and (null? a) (pair? b))
                    (and (pair? a) (pair? b)
                         (or (less (car a) (car b))
                             (and (not (less (car b) (car a)))
                                  (f (cdr a) (cdr b)))))))))
    f))

(define (sorter key less)
  (lambda (lst)
    (sort lst less #:key key #:cache-keys? #t)))

(define (rotate-scale m s)
  (let ((t (append (cdr s) (list (car s)))))
    (transpose-scale m t (- (car t)))))

; list of rotations of scale
; scale itself is the first one
(define (all-rotations m scale)
  (let recur ((n (- (length scale) 1))
              (rs (list (rotate-scale m scale))))
    (if (zero? n)
        rs
        (recur (- n 1) (cons (rotate-scale m (car rs)) rs)))))

(define (all-rotations-m scale)
  (all-rotations modulus scale))

(define (least-rotation m scale)
  (minimum (comparer <) (all-rotations m scale)))

(define (least-rotation-m scale)
  (least-rotation modulus scale))

(define (scale-sorter x)
  (case x
    ((length)    (sorter length <))
    ((length*)   (sorter length >))
    ((packing)   (sorter values (comparer <)))
    ((packing*)  (sorter values (comparer >)))
    ((wolves)    (sorter count-all-wolves <))
    ((wolves*)   (sorter count-all-wolves >))
    ((balance)   (sorter count-balance-out <))
    ((balance*)  (sorter count-balance-out >))
    ((distance)  (sorter least-distance-3 <))
    ((distance*) (sorter least-distance-3 >))
    ((rotation)  (sorter least-rotation-m (comparer <)))
    ((rotation*) (sorter least-rotation-m (comparer >)))
    (else (string-append "I don't know how to sort by " (symbol->string x) "."))))

; name of scale followed by its intervals
(define scale-list-1
  '(
    ("Whole-Tone"              2 2 2 2 2 2)
    ("Augmented 1-3"           1 3 1 3 1 3)
    ("Lydian"                  2 2 2 1 2 2 1)
    ("Harmonic Major"          1 3 1 2 2 1 2)
    ("Harmonic Minor"          2 1 2 2 1 3 1)
    ("Ascending Melodic Minor" 2 1 2 2 2 2 1)
    ("Octatonic-Diminished"    1 2 1 2 1 2 1 2)
    ("Rast"                    4 3 3 4 4 3 3)
    ("Dastgah-e Chahargah"     3 5 2 4 3 5 2)
    ("Sikah Baladi"            3 4 3 4 3 4 3)
    ("Nahfat"                  3 3 4 4 4 2 4)
;   ("Mahur"                   4 3 3 4 4 4 2)
    ("Saba"                    3 3 2 6 2 4 4)
    ("Sabr Jadid"              3 3 2 6 2 6 2)
    ("Suznak"                  4 3 3 4 2 6 2)
;   ("Qarjighar"               3 3 4 2 6 2 4)
;   ("Hizam"                   3 4 2 6 2 4 3)
    ("Nawa"                    2 4 4 4 3 3 4)
    ("Higaz-kar"               2 5 3 4 2 5 3)
    ("Dastgah"                 3 5 2 4 2 4 4)
;   ("Naghmeh Esfahan"         4 2 4 4 3 5 2)
    ("Aug-ara"                 3 6 1 5 2 6 1)
    ("Buselik"                 4 1 5 4 2 6 2)
    ("Neuter"                  4 2 6 2 2 5 3)
    ("Ushaq&Yi"                4 3 3 4 4 2 4)
;   ("Su'ar"                   3 4 4 2 4 4 3)
;   ("Ushaq Masri"             4 2 4 4 3 3 4)
;   ("'Ushshaq Turki"          3 3 4 4 2 4 4)
;   ("Jahargah"                4 4 2 4 4 3 3)
    ("Daniel"                  4 4 2 3 1 4 6)
    ("Oceans Eleven HF2"       3 4 4 3 5 2 3)
    ("Oceans Eleven Tropicana" 3 4 4 3 3 2 5)
    ("Oceans Eleven Squeeze"   5 2 4 3 3 2 5)
    ("Cicada Climbs Wall"      8 3 3 2 5 3)
    ("Cicada Sox Six"          8 3 3 2 3 5)
    ("Cal's Hex 3437"          3 4 3 7 4 3)
    ("Cal's Hex 3433"          3 3 4 7 3 4)
    ("Cal's Hex 3434"          3 4 3 4 3 7)  
    ("31 LYDIAN GROUP"         5 5 5 3 5 5 3)
    ("31 No-Wolf 7-of-Oct"     3 5 2 6 2 8 5)
    ("31 Harmonic Major"       5 5 3 5 3 7 3)
    ("31 Harmonic Major2"      5 5 3 5 2 8 3)
    ("31 Melodic Minor Up"     3 5 5 5 5 3 5)
    ("31 Harmonic Minor"       5 3 5 5 3 7 3)
    ("Kanakangi-0125789"       1 1 3 2 1 1 3)
    ("Ratnangi-012578T"        1 1 3 2 1 2 2)
    ("Ganamurti-0124679"       1 1 2 2 1 2 3)
    ("Vanaspati-012579T"       1 1 3 2 2 1 2)
    ("Manavati-012579E"        1 1 3 2 2 2 1)
    ("Tanarupi-01257TE"        1 1 3 2 3 1 1)
    ("Senavati-0135789"        1 2 2 2 1 1 3)
    ("Dhenuka-013578B"         1 2 2 2 1 3 1)
    ("Kokilapriya-013579B"     1 2 2 2 2 2 1)
    ("Rupavati-01357TE"        1 2 2 2 3 1 1)
    ("Gayak-0145789"           1 3 1 2 1 1 3)
    ("Mayam-014578E"           1 3 1 2 1 3 1)
    ("Hatak-01457TE"           1 3 1 2 3 1 1)
    ("Varu-02357TE"            2 1 2 2 3 1 1)
    ("Nagan-02457TE"           2 2 1 2 3 1 1)
    ("Yaga-0345789"            3 1 1 2 1 1 3)
    ("Gangey-034578E"          3 1 1 2 1 3 1)
    ("Chalanata-03457TE"       3 1 1 2 3 1 1)
    ("Salagam-0126789"         1 1 4 1 1 1 3)
    ("Jalarn-012678T"          1 1 4 1 1 2 2)
    ("Jhala-012678E"           1 1 4 1 1 3 1)
    ("Navam-012679T"           1 1 4 1 2 1 2)
    ("Pavani-012679E"          1 1 4 1 2 1 2)
    ("Rhagu-01267TE"           1 1 4 1 3 1 1)
    ("Sadvid-013679T"          1 2 3 1 2 1 2)
    ("Suvarn-013679E"          1 2 3 1 2 2 1)
    ("Dvya-01367TE"            1 2 3 1 3 1 1)
    ("Dhava-0146789"           1 3 2 1 1 1 3)
    ("Naman-014678T"           1 3 2 1 1 2 2)
    ("Sucha-0346789"           3 1 2 1 1 1 3)
    ("Jioti-034678T"           3 1 2 1 1 2 2)
    ("Target"                  4 3 4 3 5 2 3)
    ("Nice"                    3 2 5 7 4 3)
    ("118-Harmonic11L"         20 18 16 15 14 12 23)
    ("118-Mu-Trane11"          20 18 16 15 49)
    ("Mu-Trane11qt"            4 4 3 3 10)
    ("WideLydian190"           34 34 34 10 34 34 10)
    ("HybridLydian190"         33 33 33 11 33 33 14)
    ("MedLydian190"            32 32 32 15 32 32 15)
    ("5LimJI-Lydian190"        32 33 28 18 32 29 18)
    ("NarrowLydian190"         30 30 30 20 30 30 20)
    ("Large Dorian 136"        24 8 16 8 24 24 8 24)
    ("Melodic Minor 136"       23 10 23 24 23 20 13)
    ("Harmonic171 8-15"        29 26 24 21 20 18 17 16)
    ("Harmonic 7n 171 8-14"    29 26 24 21 20 18 33)
    ("Harmonic 6n 171 8-14"    29 26 24 21 38 33)
    ("5-note Equal"            1 1 1 1 1)
    ("7-note Equal"            1 1 1 1 1 1 1)
    ("8-note Equal"            1 1 1 1 1 1 1 1)
    ("9-note Equal"            1 1 1 1 1 1 1 1 1)
    ("10-note Equal"           1 1 1 1 1 1 1 1 1 1)
    ("11-note Equal"           1 1 1 1 1 1 1 1 1 1 1)
    ("12-note Equal"           1 1 1 1 1 1 1 1 1 1 1 1)
    ("17-note Equal"           1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    ("19-note Equal"           1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    ))

; name of scale, then its modulus, then its notes
(define scale-list-2
  '(
    ("row 9" 12  0  3 11  2 10  8  5  1  4  9  6  7)
    ("row 8" 12  0  3  6  2  9  4  5 11 10  8  1  7)
    ("row 7" 12  0  2  8 11  7  3  4 10  9  6  1  5)
    ("row 6" 12  0  1  8 10  7  5  2  9 11  6  3  4)
    ("row 5" 12  0 10  6  9  5  2 11  8  7  4  1  3)
    ("row 4" 12  0  8  5  7  4  1 10  6  9  3 11  2)
    ("row 3" 12  0  9  2  6  4 10 11  5  7  3  8  1)
    ("row 2" 12  0  6  3  5  2 11  8  4  7  1  9 10)
    ("row 1" 12  0  4  1  3  8 11  5  2  9  7 10  6)
    
    ("mof8"  12  0  4 11  6  8  2  3  5  7 10  1  9)
    ("mof7"  12  0  4 11  5  8  1  3 10  7  9  6  2)
    ("mof6A" 12  0  4 10  5  8  1  2 11  6  9  7  3)
    ("mof6B" 12  0  4  9  6  8  2  1 11  5 10  7  3)
    ("mof5"  12  0  4  7  5  8  1 11  6  3  9  2 10)
    ("mof4A" 12  0  4  7  2  8 10 11  5  3  6  1  9)
    ("mof4B" 12  0  4  7  2  8 10 11  1  3  6  9  5)
    ("mof3"  12  0  4  6  3  8 11 10  5  2  7  1  9)
    ("mof2A" 12  0  4  1 10  8  6  5 11  9  2  7  3)
    ("mof2B" 12  0  4  1 10  8  6  5  3  9  2 11  7)

    ("mallalieu" 12 0 1 4 2 9 5 11 3 8 10 7 6)
    ))

; return a list whose first element is the scale's modulus
; and whose remaining elements are its notes
(define (intervals->notes is)
  (let recur ((is is)
              (ns '(0)))
    (if (null? is)
        (cons (car ns)             ; modulus
              (reverse (cdr ns)))  ; notes
        (recur (cdr is)
          (cons (+ (car ns) (car is))
                ns)))))

; lst is not empty
; return list of results of calling f on pairs of elements of lst:
;    first and second, second and third, ..., last and first
; result has same length as lst (so, when lst has one element, x,
;    result is a list with the single element (f x x))
(define (map2 f lst)
  (let ((a (car lst)))
    (let recur ((lst lst))
      (if (null? (cdr lst))
          (list (f (car lst) a))
          (cons (f (car lst) (cadr lst))
                (recur (cdr lst)))))))

; like map2, except don't call f on last and first
; result is therefore shorter than lst by one
(define (map2a f lst)
  (if (null? (cdr lst))
      '()
      (cons (f (car lst) (cadr lst))
            (map2a f (cdr lst)))))

(define (notes->intervals ns)
  (map2 interval ns))

(define (divide-by-gcd lst)
  (let ((k (apply gcd lst)))
    (map (lambda (j) (/ j k))
         lst)))

; first element of scale is the modulus, rest are the notes
; same for return value
(define (normalize scale)
  (divide-by-gcd (cons (car scale) (least-rotation (car scale) (cdr scale)))))

; maps modulus-prefixed scale to name
(define known-scales (make-hash))

; first element of scale is its modulus, rest are its notes
(define (add-scale name scale)
  (let ((normalized-scale (normalize scale)))
    (hash-update! known-scales normalized-scale
                  (lambda (x) (or x name))
                  #f)))

; first element of scale is its modulus, rest are its notes
(define (add-scale-and-inverse name scale)
  (let ((m (car scale))
        (notes (cdr scale)))
    (add-scale name scale)
    (add-scale (string-append name "*") (cons m (invert-scale m notes)))))

; first element of s is scale's name, rest are its intervals
(define (add-scale-from-intervals s)
  (add-scale-and-inverse (car s) (intervals->notes (cdr s))))

; first element of s is scale's name, next is its modulus, rest are its notes
(define (add-scale-from-notes s)
  (add-scale-and-inverse (car s) (cdr s)))

(for-each add-scale-from-intervals scale-list-1)
(for-each add-scale-from-notes     scale-list-2)

; first element of scale is the modulus, rest are the notes
; return value is just notes
(define (convert-to-mod-1 scale)
  (map (lambda (n) (/ n (car scale)))
       (cdr scale)))

(define (interval-1 a b)
  (mod (- b a) 1))

; transpose note n by k, where modulus is 1
(define (transpose-note-1 n k)
  (mod (+ n k) 1))

; transpose scale s by k, where modulus is 1
(define (transpose-scale-1 s k)
  (map (lambda (n) (transpose-note-1 n k))
       s))

; s is mod 1
(define (rotate-scale-1 s)
  (let ((t (append (cdr s) (list (car s)))))
    (transpose-scale-1 t (- (car t)))))

; scale is mod 1
(define (all-rotations-1 scale)
  (let recur ((n (- (length scale) 1))
              (rs (list (rotate-scale-1 scale))))
    (if (zero? n)
        rs
        (recur (- n 1) (cons (rotate-scale-1 (car rs)) rs)))))

; s1 and s2 are mod 1 and have the same length
; return the largest difference between any two corresponding
;   notes of scales s1 and s2 (i.e., the first notes of the two
;   scales, or their second notes, or third, etc.), if the scales
;   are transposed so as to minimize that largest difference
(define (scale-difference s1 s2)
  (let* ((intervals (map interval-1 s1 s2))
         (interval-diffs (filter positive? (map2 interval-1 (sort intervals >)))))
    (if (null? interval-diffs)
        0
        (/ (apply min interval-diffs) 2))))

; s1 and s2 are mod 1 and have the same length
; return least difference between any rotation of s1 and any rotation of s2
(define (least-scale-difference s1 s2)
  (apply min (map (lambda (s) (scale-difference s1 s))
                  (all-rotations-1 s2))))

(define (min-scorers-w-score f lst)
  (let* ((scored-lst (map (lambda (x) (cons (f x) x))
                          lst))
         (min-score (foldl (lambda (x a) (min a (car x)))
                      (caar scored-lst) (cdr scored-lst))))
    (filter (lambda (x) (equal? (car x) min-score))
            scored-lst)))

; return a list of those items x of lst for which (f x) is least
(define (min-scorers f lst)
  (map cdr (min-scorers-w-score f lst)))

; return a possibly-empty list of the nearest scales to scale
; each element of the return value has the form: (difference scale . scale-name)
(define (nearest-known-scales scale)
  (let* ((len (length scale))
         (scales (filter (lambda (s-n) (= len (length (cdar s-n))))
                         (hash->list known-scales))))
    (if (null? scales)
        '()
        (let ((s (convert-to-mod-1 (cons modulus scale))))
          (min-scorers-w-score (lambda (s-n)
                                 (least-scale-difference s (convert-to-mod-1 (car s-n))))
                               scales)))))

(define (scale-name s)
  (let ((ss (nearest-known-scales s))
        (d (/ scale-tolerance 1200)))
    (if (null? ss)
        #f
        (let ((diff (caar ss))
              (name (cddar ss)))
          (cond
            ((> diff d) #f)
            ((zero? diff) name)
            (else (string-append name " [" (number->string (round (* diff 1200))) "]")))))))

; list of transpositions of scale where the first note,
; then the second, then the third, etc. becomes n
(define (all-transpositions-to m scale n)
  (map (lambda (k) (transpose-scale m scale (- n k)))
       scale))

(define (sort-numbers lst)
  (sort lst <))

(define (all-transpositions scale)
  (build-list modulus (lambda (i) (sort-numbers (transpose-scale modulus scale i)))))

(define (all-transformations scale)
  (append (all-transpositions scale)
          (all-transpositions (invert-scale modulus scale))))

; x and y are lists of numbers, each in increasing order
; is x a subset of y?
(define (subset? x y)
  (cond
    ((null? x) #t)
    ((null? y) #f)
    ((< (car x) (car y)) #f)
    ((< (car y) (car x)) (subset? x (cdr y)))
    (else (subset? (cdr x) (cdr y)))))

; x and y are lists of numbers, each in increasing order and containing no duplicates
; result satisfies the same conditions
(define (intersection x y)
  (cond
    ((or (null? x) (null? y)) '())
    ((< (car x) (car y)) (intersection (cdr x) y))
    ((< (car y) (car x)) (intersection x (cdr y)))
    (else (cons (car x) (intersection (cdr x) (cdr y))))))

; x and y are lists of numbers, each in increasing order and containing no duplicates
; result satisfies the same conditions
(define (set-difference x y)
  (cond
    ((null? x) '())
    ((null? y) x)
    ((< (car x) (car y)) (cons (car x) (set-difference (cdr x) y)))
    ((< (car y) (car x)) (set-difference x (cdr y)))
    (else (set-difference (cdr x) (cdr y)))))

; x and y are lists of numbers, each in increasing order and containing no duplicates
; result satisfies the same conditions
(define (symmetric-difference x y)
  (cond
    ((null? x) y)
    ((null? y) x)
    ((< (car x) (car y)) (cons (car x) (symmetric-difference (cdr x) y)))
    ((< (car y) (car x)) (cons (car y) (symmetric-difference x (cdr y))))
    (else (symmetric-difference (cdr x) (cdr y)))))

; x, y and common are lists of numbers, each in increasing order and containing no duplicates
(define (complement? x y common n)
  (<= (length (set-difference (intersection x y) common))
      n))

; first element of each scale is its modulus, rest are its notes.
; return the two scales after converting them to have the same modulus.
(define (convert-to-same-modulus scale-1 scale-2)
  (let ((m1 (car scale-1))
        (m2 (car scale-2)))
    (let ((m3 (lcm m1 m2)))
      (let ((k1 (/ m3 m1))
            (k2 (/ m3 m2)))
        (values (map (lambda (n) (* n k1))
                     scale-1)
                (map (lambda (n) (* n k2))
                     scale-2))))))

; subset is in increasing order
; return a list of 3-element lists,
;   each sublist consisting of (1) the subset,
;   (2) the name of a superset, and (3) a list of modes
;   of that superset.  Each elements of (3) might be #f
;   instead of a mode.  A mode is a list of numbers.
(define (known-supersets subset)
  (let ((subset1 (divide-by-gcd subset)))
    (hash-map known-scales
              (lambda (scale name)
                (let-values (((subset2 scale2) (convert-to-same-modulus subset1 scale)))
                  (let ((notes (cdr subset2)))
                    (list subset2 name
                          (map (lambda (s)
                                 (and (subset? notes (sort s <))
                                      s))
                               (all-transpositions-to (car scale2) (cdr scale2) (car notes))))))))))

; first element of scale is the modulus, rest are the notes
(define (print-known-supersets scale)
  (let* ((ss (known-supersets scale))
         (ss2 (filter (lambda (x) (ormap values (third x)))
                      ss))
         (ss3 (map (lambda (x) (list (first x) (second x) (filter values (third x))))
                   ss2)))
    (if (null? ss3)
        (display "given scale is not a subset of any known scale\n\n")
        (for-each (lambda (x)
                    (let ((subset (first x))
                          (name (second x))
                          (modes (third x)))
                      (display "given scale, ")
                      (display (cdr subset))
                      (display " mod ")
                      (display (car subset))
                      (display ", is a subset of these modes of ")
                      (display name)
                      (display ":\n")
                      (for-each (lambda (mode)
                                  (display "   ")
                                  (display mode)
                                  (newline))
                                modes)
                      (newline)))
                  ss3))))

(define (preprocess-cell c)
  (let* ((range (- (car c) 1))
         (normal (cdr c))
         (inverted (invert-scale modulus normal))
         (len (- (length normal) 1)))
    (list range len normal inverted)))

; extract the parts of a preprocessed cell
(define cell-range    first)
(define cell-len      second)
(define cell-normal   third)
(define cell-inverted fourth)

(define (vector-increment! v i)
  (vector-set! v i (+ 1 (vector-ref v i))))

; measures the extent to which letters are repeated
(define (repetitiveness x)  ; x: list of name codes
  (let ((v (make-vector 7 0)))
    (for-each (lambda (c) (vector-increment! v (car c)))
      x)
    (apply + (map (lambda (x) (* x x))
                  (vector->list v)))))

; number of flats or number of sharps, whichever is smaller
(define (inconsistency x)  ; x: list of name codes
  (let ((v (make-vector 3 0)))
    (for-each (lambda (c) (vector-increment! v (+ 1 (cadr c))))
      x)
    (min (vector-ref v 0)
         (vector-ref v 2))))

(define (best-spellings scale)
  (let* ((all-spellings (apply cartesian-product
                          (map (lambda (n) (vector-ref name-codes n))
                               scale)))
         (best (min-scorers inconsistency
                 (min-scorers repetitiveness all-spellings))))
    (map (lambda (scale) (map code->name scale))
         best)))

(define (display-spellings s)
  (let ((spellings (best-spellings s)))
    (for-each (lambda (x) (display x) (newline))
      (if multiple-spellings
          spellings
          (list (car spellings))))))

; return a list of lists, such that appending
; them all together yields lst, and such that,
; if p and q are any two elements of the same
; list, (f p) equals (f q)
; 
; e.g.
; (split (lambda (n) (modulo n 10))
;        '(1 11 21 22 12 0 1 2 5 25 15 35))
; yields ((1 11 21) (22 12) (0) (1) (2) (5 25 15 35))
(define (split f lst)
  (if (null? lst)
      '()
      (let recur ((lst (cdr lst))
                  (a '())              ; list of lists
                  (b (list (car lst))) ; list
                  (x (f (car lst))))
        (if (null? lst)
           (reverse (cons (reverse b) a))
           (let ((y (f (car lst))))
             (if (equal? x y)
                 (recur (cdr lst)           a          (cons (car lst) b) y)
                 (recur (cdr lst) (cons (reverse b) a)  (list (car lst))  y)))))))

; return a list of lists, each of which is of length n
; and the elements of which are taken, in order, from lst.
; the last list ends in enough elements equal to filler
; to bring its length up to n.
(define (split-n n lst filler)
  (let recur ((lst lst)
              (a '()) ; list of lists
              (b '()) ; list
              (k 0))  ; length of b
    (cond
      ((= k n)
       (recur lst (cons (reverse b) a) '() 0))
      ((and (null? lst) (zero? k))
       (reverse a))
      ((null? lst)
       (recur lst a (cons filler b) (+ 1 k)))
      (else
       (recur (cdr lst) a (cons (car lst) b) (+ 1 k))))))

(define (display-scale-numbers s)
  (display s))

(define (display-scale-letters s)
  (display (car (best-spellings (case modulus
                                  ((12) (map (lambda (n) (* n 2)) s))
                                  ((24) s))))))

(define (display-scale-intervals s)
  (let ((x (notes->intervals s)))
    (display (append x x))))

(define (display-scale-keyboard s)
  (let ((n-keys (length keyboard-notes)))
    (let recur ((s s)
                (offset 0))
      (when (pair? s)
        (let* ((note (car s))
               (key (+ (vector-ref keyboard note)
                       offset
                       (if (>= note first-note) 0 n-keys))))
          (if (< key 12)
              (begin (display key) (display " " ) (recur (cdr s) offset))
              (begin               (display "| ") (recur s (- offset 12)))))))))

(define (display-scale s quit)
  (when please-stop
    (newline)
    (displayln "printing interrupted")
    (quit))
  (let ((name (scale-name s)))
    (when name (displayln name)))
  (display "notes: ")
  (display-scale-numbers s)
  (newline)
  (display "intervals: ")
  (display-scale-intervals s)
  (newline)
  (case modulus
    ((12) (display-spellings (map (lambda (n) (* n 2)) s)))
    ((24) (display-spellings s)))
  (when (> modulus 12)
    (display-scale-keyboard s)
    (newline))
  (display "number of wolves: ")
  (display (count-all-wolves s))
  (newline))

(define (display-scales ss)
  (call/cc (lambda (c)
             (for-each (lambda (s)
                         (display-scale s c)
                         (newline))
                       ss))))

(define (equalize-heights row)
  (let ((height (apply max (map length row))))
    (map (lambda (group)
           (append group (build-list (- height (length group))
                                     (lambda (n) ""))))
         row)))

; scales: list of scales
(define (display-scales-columns scales)
  (let* ((stringify (lambda (scale)
                      (with-output-to-string
                          (lambda ()
                            (let ((f (case output-format
                                       (("numbers")   display-scale-numbers)
                                       (("letters")   (if (member modulus '(12 24))
                                                          display-scale-letters
                                                          display-scale-numbers))
                                       (("intervals") display-scale-intervals)
                                       (("keyboard")  display-scale-keyboard))))
                              (f scale))))))

         ; list of groups, each of which is a list of scales
         (rotation-groups (split least-rotation-m scales))

         ; same, except with each scale converted to a string
         ; also, add name if it has one
         (groups (map (lambda (group)
                        (let ((scale-strings (map stringify group))
                              (name (scale-name (car group))))
                          (if name (cons name scale-strings) scale-strings)))
                      rotation-groups))

         ; list of rows, each of which is a list of groups.
         ; the number of groups in each row is column-count.
         ; the groups of a row will be displayed left to right.
         ; rows will be displayed top to bottom.
         (rows (split-n column-count groups '("")))

         ; list of column widths.
         ; each is the length of the longest string in that column.
         (column-widths (if (null? rows)
                            '()
                            (apply map (lambda column (apply max (map string-length (flatten column))))
                                   rows))))
    (define (display-line strs)
      (for-each (lambda (str width)
                  (display str)
                  (display (padding str width)))
                strs
                (map (lambda (n) (+ n 2)) column-widths)))

    (define (display-row r)
      (apply for-each (lambda line
                        (display-line line)
                        (newline))
             (equalize-heights r)))

    (for-each (lambda (r)
                (display-row r)
                (newline))
              rows)))

(define (print-scales scales)
  (let ((sorted-scales ((apply compose1 (map scale-sorter sort-order)) scales)))
    (if multi-column
        (display-scales-columns sorted-scales)
        (display-scales sorted-scales))))

(define (display-note n)
  (display n)
  (case modulus
    ((12) (display " ") (display (vector-ref note-names (* n 2))))
    ((24) (display " ") (display (vector-ref note-names n)))))

(define (display-any x)
  (cond
    ((number? x)                     (display-note x))
    ((and (pair? x) (pair? (car x))) (display-scales x))
    ((pair? x)                       (display-scale x))))

(define (display-now x)
  (display x)
  (flush-output))

(define found!
  (let ((then (current-seconds)))
    (lambda (s)
      (set! found-scales (cons s found-scales))
      (let ((now (current-seconds)))
        (when (> now then)
          (set! then now)
          (display-now #\.))))))

; notes is a list of allowable notes, in increasing order
; notes-len is the length of notes
; scale is the scale so far, in decreasing order
; scale-len is the length of scale
; n-wolf is the number of wolf intervals in scale
; n-balance is the number of notes in scale that are in balance-notes
; n-bad-cell is the number of occurrences in scale of bad cells
; n-good-cell is the number of occurrences in scale of good cells
; n-bad-interval is the number of occurrences in scale of bad intervals
; n-good-interval is the number of occurrences in scale of good intervals

; call found! for every scale that follows the rules and
;   which can be made by adding to 'scale' any number (> 0)
;   of notes from 'notes'
(define (find-scales notes notes-len scale scale-len n-wolf n-balance n-bad-cell n-good-cell n-bad-interval n-good-interval)
  (when (and (not please-stop)
             (positive? notes-len)
             (< scale-len length-max)
             (>= (+ scale-len notes-len) length-min))
    (let ((n (car notes))
          (notes (cdr notes))
          (notes-len (- notes-len 1)))
      (when (not (member n required-notes))
        (find-scales notes notes-len scale scale-len n-wolf n-balance n-bad-cell n-good-cell n-bad-interval n-good-interval))
      (when (and (allowed-intervals-ok? n scale)
                 (distances-ok? n scale scale-len))
        (let ((n-wolf (+ n-wolf (count-wolves n scale)))
              (n-bad-cell (+ n-bad-cell (count-cells bad-cells n scale scale-len)))
              (n-bad-interval (+ n-bad-interval (count-intervals bad-intervals n scale))))
          (when (and (<= n-wolf wolf-max)
                     (<= n-bad-cell bad-cell-max)
                     (<= n-bad-interval bad-interval-max))
            (let ((n-balance (+ n-balance (if (member n balance-notes) 1 0)))
                  (n-good-cell (+ n-good-cell (count-cells good-cells n scale scale-len)))
                  (n-good-interval (+ n-good-interval (count-intervals good-intervals n scale)))
                  (scale (cons n scale))
                  (scale-len (+ 1 scale-len)))
              (find-scales notes notes-len scale scale-len n-wolf n-balance n-bad-cell n-good-cell n-bad-interval n-good-interval)
              (when (and (>= scale-len length-min)
                         (>= n-wolf wolf-min)
                         (balance-ok? scale-len n-balance)
                         (contains-required-notes? scale)
                         (final-distances-ok? scale)
                         (final-allowed-intervals-ok? scale)
                         (<= (+ n-bad-cell (final-count-cells bad-cells scale scale-len))
                             bad-cell-max)
                         (>= (+ n-good-cell (final-count-cells good-cells scale scale-len))
                             good-cell-min)
                         (<= (+ n-bad-interval (final-count-intervals bad-intervals scale))
                             bad-interval-max)
                         (>= (+ n-good-interval (final-count-intervals good-intervals scale))
                             good-interval-min))
                (found! (reverse scale))))))))))

(define (count-intervals intervals n scale)
  (if (member (interval (car scale) n) intervals)
      1
      0))

(define (final-count-intervals intervals scale)
  (count-intervals intervals first-note scale))

(define (contains-required-notes? scale)
  (subset? required-notes (sort scale <)))

(define (distances-ok? n scale len)
  (and (>= (interval (car scale) n) distance-2-min)
       (or (<= len 1)
           (and (>= (interval (cadr scale) n) distance-3-min)
                (>= (interval n (list-ref scale (- len 2))) distance-3-min)))))

(define (final-distances-ok? scale)
  (and (>= (interval (car scale) first-note) distance-2-min)
       (>= (interval (cadr scale) first-note) distance-3-min)))

(define (allowed-intervals-ok? n scale)
  (or (null? allowed-intervals)
      (member (interval (car scale) n)
        allowed-intervals)))

(define (final-allowed-intervals-ok? scale)
  (or (null? allowed-intervals)
      (and (member (interval (car scale) first-note)
             allowed-intervals)
           (if require-all-allowed-intervals
               (let ((intervals (notes->intervals (reverse scale))))
                 (andmap (lambda (i) (member i intervals))
                   allowed-intervals))
               #t))))

(define (count-cells-1 c note scale len)
  (if (< len (cell-len c))
      0
      (let ((notes (sort-numbers (cons note (take scale (min len (cell-range c))))))
            (cell-transpositions (map sort-numbers
                                      (append (all-transpositions-to modulus (cell-normal   c) note)
                                              (all-transpositions-to modulus (cell-inverted c) note)))))
        (count (lambda (ct) (subset? ct notes))
               cell-transpositions))))

(define (count-cells cells note scale len)
  (apply + (map (lambda (c) (count-cells-1 c note scale len))
                cells)))

(define (final-count-cells-1 c ss len)
  (let ((r (min (cell-range c) (- len 1))))
    (let recur ((s (list-tail ss (- len r)))
                (i r))
      (if (<= i 0)
          0
          (+ (count-cells-1 c (car s) (cdr s) (- len 1))
             (recur (cdr s) (- i 1)))))))

(define (final-count-cells cells scale len)
  (let ((ss (append scale scale)))
    (apply + (map (lambda (c) (final-count-cells-1 c ss len))
                  cells))))

(define (count-wolves n scale)
  (foldl (lambda (note sum)
               (+ sum
                  (if (member (interval note n) wolves) 1 0)
                  (if (member (interval n note) wolves) 1 0)))
    0 scale))

(define (balance-ok? scale-len n-balance)
  (<= balance-in-min n-balance (- scale-len balance-out-min)))

(define (count-all-wolves scale)
  (if (null? scale)
      0
      (+ (count-wolves (car scale) (cdr scale))
         (count-all-wolves (cdr scale)))))

(define (count-balance-out scale)
  (apply + (map (lambda (note) (if (member note balance-notes) 0 1))
                scale)))

(define (least-distance-3 s)
  (let ((t (append (cddr s) (list (car s) (cadr s)))))
    (apply min (map interval s t))))

; r is a pair of numbers, and represents
; the half-open interval between them
(define (in-range x r)
  (and (<= (car r) x) (< x (cdr r))))

; does a precede b in the scale?
; it's more complicated than simply (< a b)
; because the scale starts at first-note and
; goes up to modulus, then wraps around to 0
; and continues up to first-note.
(define (note-comparer)
  (let ((p (cons first-note modulus))
        (q (cons 0 first-note)))
    (lambda (a b)
      (cond
        ((and (in-range a p) (in-range b q)) #t)
        ((and (in-range b p) (in-range a q)) #f)
        (else (< a b))))))
  
; list of scales, each of which is 'scale' plus one allowed note
(define (with-extra-note scale)
  (map (lambda (n) (sort (cons n scale) (note-comparer)))
       allowed-notes))

(define (scale-complete? scale ss)
  (not (ormap (lambda (s)
                (set-member? ss s))
         (with-extra-note scale))))

(define (remove-incompletes scales)
  (let ((ss (list->set scales)))
    (filter (lambda (s)
              (scale-complete? s ss))
      scales)))

(define (make-keyboard)
  (let ((v (make-vector modulus 'bug)))
    (let recur ((notes keyboard-notes)
                (key 0))
      (when (pair? notes)
        (vector-set! v (car notes) key)
        (recur (cdr notes) (+ 1 key))))
    v))

(define (initialize-keyboard no-keyboard)
  (when no-keyboard
    (set! first-note 0))
  (set! keyboard-notes (if (or no-keyboard (null? keyboard-notes-raw))
                           (build-list modulus values)
                           keyboard-notes-raw))
  (set! keyboard (make-keyboard)))

(define (generate)
  (copy-settings-from-gui-to-vars)
  (initialize-keyboard #f)
  (set! first-note (modulo first-note modulus))
  (set! required-notes (sort required-notes <))
  (display-settings 1)
  (display-now "finding scales...")
  (set! allowed-notes (filter (lambda (n) (and (member n keyboard-notes)
                                               (not (member n forbidden-notes))))
                              (build-list (- modulus 1)
                                          (lambda (n) (modulo (+ first-note 1 n) modulus)))))
  (set! good-cells (map preprocess-cell good-cells-raw))
  (set! bad-cells  (map preprocess-cell  bad-cells-raw))
  (set! found-scales '())
  (find-scales allowed-notes (length allowed-notes) (list first-note) 1
               0 (if (member first-note balance-notes) 1 0) 0 0 0 0)
  (if please-stop
      (displayln "interrupted")
      (begin
        (displayln "done")
        (when require-completeness
          (display-now "removing incomplete scales...")
          (set! found-scales (remove-incompletes found-scales))
          (displayln "done"))))
  (newline)
  (let ((n-scale (length found-scales)))
    (display "number of scales found: ")
    (displayln n-scale)
    (newline)
    (set! please-stop #f)
    (print-scales (if (<= n-scale scales-max)
                      found-scales
                      (random-sample found-scales scales-max #:replacement? #f)))))

; scales is a list of pairs, each of which is (modulus-prefixed-list-of-notes . name)
(define (list-scales scales)
  (let* ((ss (sort scales (comparer <) #:key car))
         (notes-list (map (lambda (scale)
                            (with-output-to-string
                                (lambda () (display (car scale)))))
                          ss))
         (name-list (map cdr ss))
         (len (+ 1 (apply max (map string-length notes-list)))))
    (for-each (lambda (notes name)
                (display notes)
                (display (padding notes len))
                (displayln name))
              notes-list
              name-list)
    (newline)))

(define (print-identification m s)
  (let ((t (if reorder-notes (sort-numbers s) s)))
    (if display-supersets
        (print-known-supersets (cons m t))
        (print-scales (all-rotations m t)))))

; scale is a modulus-prefixed list of notes
(define (identify-scale scale)
  (let ((m (car scale))
        (s (cdr scale)))
    (set! modulus m)  ; yuck
    (initialize-keyboard #t)
    (display-settings 2)
    (print-identification m s)))

(define (convert-to-list str)
  (nest-appropriately str 'list))

(define (identify)
  (copy-settings-from-gui-to-vars)
  (case scale-interpretation
    (("notes")     (identify-scale (cons modulus (convert-to-list scale-contents2))))
    (("intervals") (identify-scale (intervals->notes (convert-to-list scale-contents2))))
    (("name")      (let* ((name (string-foldcase scale-contents2))
                          (scales (filter (lambda (s) (string-contains? (string-foldcase (cdr s)) name))
                                          (hash->list known-scales))))
                     (cond
                       ((null? scales) (display "no scale contains '")
                                       (display name)
                                       (displayln "' in its name")
                                       (newline))
                       ((null? (cdr scales)) (identify-scale (caar scales)))
                       (else (let ((exact-matches (filter (lambda (s) (string-ci=? (cdr s) name))
                                                          scales)))
                               (if (null? exact-matches)
                                   (list-scales scales)
                                   (identify-scale (caar exact-matches))))))))))

(define (list-known-scales)
  (list-scales (hash->list known-scales)))

(define (display-complements-from f scales)
  (print-scales
   (remove-duplicates
    (filter (lambda (s)
              (complement? s scale-contents3 common-notes max-additional-common-notes))
            (apply append (map f scales))))))

(define (complement)
  (copy-settings-from-gui-to-vars)
  (initialize-keyboard #t)
  (set! common-notes (sort common-notes <))
  (set! scale-contents3 (sort scale-contents3 <))
  (display-settings 3)
  (case complement-source
    (("the scale above") (display-complements-from all-transformations (list scale-contents3)))
    (("all named scales") (display-complements-from all-transpositions
                           (map cdr (filter (lambda (s) (= modulus (car s)))
                                            (hash-keys known-scales)))))))

; optional name (a string), then modulus, then notes
(define mapping-table-list
  '(
    ("row 9" 12  0  3 11  2 10  8  5  1  4  9  6  7)
    ("row 8" 12  0  3  6  2  9  4  5 11 10  8  1  7)
    ("row 7" 12  0  2  8 11  7  3  4 10  9  6  1  5)
    ("row 6" 12  0  1  8 10  7  5  2  9 11  6  3  4)
    ("row 5" 12  0 10  6  9  5  2 11  8  7  4  1  3)
    ("row 4" 12  0  8  5  7  4  1 10  6  9  3 11  2)
    ("row 3" 12  0  9  2  6  4 10 11  5  7  3  8  1)
    ("row 2" 12  0  6  3  5  2 11  8  4  7  1  9 10)
    ("row 1" 12  0  4  1  3  8 11  5  2  9  7 10  6)
    
    ("mof8"  12  0  4 11  6  8  2  3  5  7 10  1  9)
    ("mof7"  12  0  4 11  5  8  1  3 10  7  9  6  2)
    ("mof6A" 12  0  4 10  5  8  1  2 11  6  9  7  3)
    ("mof6B" 12  0  4  9  6  8  2  1 11  5 10  7  3)
    ("mof5"  12  0  4  7  5  8  1 11  6  3  9  2 10)
    ("mof4A" 12  0  4  7  2  8 10 11  5  3  6  1  9)
    ("mof4B" 12  0  4  7  2  8 10 11  1  3  6  9  5)
    ("mof3"  12  0  4  6  3  8 11 10  5  2  7  1  9)
    ("mof2A" 12  0  4  1 10  8  6  5 11  9  2  7  3)
    ("mof2B" 12  0  4  1 10  8  6  5  3  9  2 11  7)
    
    (171
     0   148 125 102 79  56  33  10  158 135 112 89
     66  43  20  168 145 122 99  76  53  30  7   155
     132 109 86  63  40  17  165 142 119 96  73  50
     27  4   152 129 106 83  60  37  14  162 139 116 
     93  70  47  24  1   149 126 103 80  57  34  11  
     159 136 113 90  67  44  21  169 146 123 100 77)
    
    (171
     0   147 123 99  75  51  27  3   150 126 102 78  
     54  30  6   153 129 105 81  57  33  9   156 132 
     108 84  60  36  12  159 135 111 87  63  39  15  
     162 138 114 90  66  42  18  165 141 117 93  69  
     45  21  168 144 120 96  72  48  24  0   147 123 
     99  75  51  27  3   150 126 102 78  54  30  6)
    
    (171
     0   146 121 96  71  46  21  167 142 117 92  67
     42  17  163 138 113 88  63  38  13  159 134 109 
     84  59  34  9   155 130 105 80  55  30  5   151 
     126 101 76  51  26  1   147 122 97  72  47  22  
     168 143 118 93  68  43  18  164 139 114 89  64  
     39  14  160 135 110 85  60  35  10  156 131 106)
    
    (171
     0   144 117 90  63  36  9   153 126 99  72  45  
     18  162 135 108 81  54  27  0   144 117 90  63  
     36  9   153 126 99  72  45  18  162 135 108 81  
     54  27  0   144 117 90  63  36  9   153 126 99  
     72  45  18  162 135 108 81  54  27  0   144 117 
     90  63  36  9   153 126 99  72  45  18  162 135)
    
    (171
     0   142 113 84  55  26  168 139 110 81  52  23  
     165 136 107 78  49  20  162 133 104 75  46  17  
     159 130 101 72  43  14  156 127 98  69  40  11  
     153 124 95  66  37  8   150 121 92  63  34  5   
     147 118 89  60  31  2   144 115 86  57  28  170 
     141 112 83  54  25  167 138 109 80  51  22  164)
    
    (171
     0   141 111 81  51  21  162 132 102 72  42  12  
     153 123 93  63  33  3   144 114 84  54  24  165 
     135 105 75  45  15  156 126 96  66  36  6   147 
     117 87  57  27  168 138 108 78  48  18  159 129 
     99  69  39  9   150 120 90  60  30  0   141 111 
     81  51  21  162 132 102 72  42  12  153 123 93)
    
    (171
     0   136 101 66  31  167 132 97  62  27  163 128 
     93  58  23  159 124 89  54  19  155 120 85  50  
     15  151 116 81  46  11  147 112 77  42  7   143 
     108 73  38  3   139 104 69  34  170 135 100 65  
     30  166 131 96  61  26  162 127 92  57  22  158 
     123 88  53  18  154 119 84  49  14  150 115 80)
    
    (171
     0   131 91  51  11  142 102 62  22  153 113 73  
     33  164 124 84  44  4   135 95  55  15  146 106 
     66  26  157 117 77  37  168 128 88  48  8   139 
     99  59  19  150 110 70  30  161 121 81  41  1   
     132 92  52  12  143 103 63  23  154 114 74  34  
     165 125 85  45  5   136 96  56  16  147 107 67)
    
    (171
     0   121 71  21  142 92  42  163 113 63  13  134 
     84  34  155 105 55  5   126 76  26  147 97  47  
     168 118 68  18  139 89  39  160 110 60  10  131 
     81  31  152 102 52  2   123 73  23  144 94  44  
     165 115 65  15  136 86  36  157 107 57  7   128 
     78  28  149 99  49  170 120 70  20  141 91  41)
    
    (171
     0   120 69  18  138 87  36  156 105 54  3   123 
     72  21  141 90  39  159 108 57  6   126 75  24  
     144 93  42  162 111 60  9   129 78  27  147 96  
     45  165 114 63  12  132 81  30  150 99  48  168 
     117 66  15  135 84  33  153 102 51  0   120 69  
     18  138 87  36  156 105 54  3   123 72  21  141)
    
    (171
     0   102 33  135 66  168 99  30  132 63  165 96  
     27  129 60  162 93  24  126 57  159 90  21  123 
     54  156 87  18  120 51  153 84  15  117 48  150 
     81  12  114 45  147 78  9   111 42  144 75  6   
     108 39  141 72  3   105 36  138 69  0   102 33  
     135 66  168 99  30  132 63  165 96  27  129 60)
    
    (171
     0   101 31  132 62  163 93  23  124 54  155 85     
     15  116 46  147 77  7   108 38  139 70  0   101 
     31  132 62  163 93  23  124 54  155 85  15  116  
     46  147 77  7   108 38  139 70  0   101 31  132 
     62  163 93  23  124 54  155 85  15  116 46  147                   
     77  7   108 38  139 70  0   101 31  132 62  163)
    
    (171
     0   100 30  130 60  160 90  19  120 49  150 79     
     9   109 39  139 70  0   100 30  130 60  160 90  
     19  120 49  150 79  9   109 39  139 70  0   100 
     30  130 60  160 90  19  120 49  150 79  9   109 
     39  139 70  0   100 30  130 60  160 90  19  120                   
     49  150 79  9   109 39  139 70  0   100 30  130)
    
    (171
     0   101 29  130 60  159 89  19  118 48  149 77     
     7   108 36  137 67  166 96  26  125 55  156 84
     14  115 43  144 74  2   103 33  132 62  163 91  
     21  122 50  151 81  9   110 40  139 70  0   101 
     29  130 60  159 89  19  118 48  149 77  7   108                       
     36  137 67  166 96  26  125 55  156 84  14  115)
    
    (171
     0   100 29  129 58  158 87  16  116 45  145 74      
     3   103 32  132 61  161 90  19  119 48  148 77  
     6   106 35  135 64  164 93  22  122 51  151 80  
     9   109 38  138 67  167 96  25  125 54  154 83  
     12  112 41  141 70  0   100 29  129 58  158 87   
     6   116 45  145 74  3   103 32  132 61  161 90)
    
    (171
     0   100 28  128 57  157 86  15  114 43  143 71      
     0   100 28  128 57  157 86  15  114 43  143 71   
     0   100 28  128 57  157 86  15  114 43  143 71 
     0   100 28  128 57  157 86  15  114 43  143 71 
     0   100 28  128 57  157 86  15  114 43  143 71
     0   100 28  128 57  157 86  15  114 43  143 71)
    
    (171
     0   99  27  126 54  153 81  9   108 36  135 63      
     162 90  18  117 45  144 72  0   99  27  126 54  
     153 81  9   108 36  135 63  162 90  18  117 45  
     144 72  0   99  27  126 54  153 81  9   108 36  
     135 63  162 90  18  117 45  144 72  0   99  27  
     126 54  153 81  9   108 36  135 63  162 90  18)
    
    (171
     0   97  23  120 46  143 69  166 92  18  115 41       
     138 64  161 87  13  110 36  133 59  156 82  8   
     105 31  128 54  151 77  3   100 26  123 49  146 
     72  169 95  21  118 44  141 67  164 90  16  113 
     39  136 62  159 85  11  108 34  131 57  154 80  
     6   103 29  126 52  149 75  0   97  23  120 46)
    
    (171
     0   90  9   99  18  108 27  117 36  126 45  135 
     54  144 63  153 72  162 81  0   90  9   99  18  
     108 27  117 36  126 45  135 54  144 63  153 72  
     162 81  0   90  9   99  18  108 27  117 36  126 
     45  135 54  144 63  153 72  162 81  0   90  9   
     99  18  108 27  117 36  126 45  135 54  144 63)
    
    (171
     0   72  144 45  117 18  90  162 63  135 36  108 
     9   81  153 54  126 27  99  0   72  144 45  117 
     18  90  162 63  135 36  108 9   81  153 54  126 
     27  99  0   72  144 45  117 18  90  162 63  135 
     36  108 9   81  153 54  126 27  99  0   72  144 
     45  117 18  90  162 63  135 36  108 9   81  153)
    
    (171
     0   66  132 27  93  159 54  120 15  81  147 42  
     108 3   69  135 30  96  162 57  123 18  84  150 
     45  111 6   72  138 33  99  165 60  126 21  87  
     153 48  114 9   75  141 36  102 168 63  129 24  
     90  156 51  117 12  78  144 39  105 0   66  132 
     27  93  159 54  120 15  81  147 42  108 3   69)
    
    (171
     0   51  102 153 33  84  135 15  66  117 168 48  
     99  150 30  81  132 12  63  114 165 45  96  147 
     27  78  129 9   60  111 162 42  93  144 24  75  
     126 6   57  108 159 39  90  141 21  72  123 3   
     54  105 156 36  87  138 18  69  120 0   51  102 
     153 33  84  135 15  66  117 168 48  99  150 30)
    
    (171
     0   50  100 150 29  79  129 8   58  108 158 37  
     87  137 16  66  116 166 45  95  145 24  74  124 
     3   53  103 153 32  82  132 11  61  111 161 40  
     90  140 19  69  119 169 48  98  148 27  77  127 
     6   56  106 156 35  85  135 14  64  114 164 43  
     93  143 22  72  122 1   51  101 151 30  80  130)
    
    (171
     0   40  80  120 160 29  69  109 149 18  58  98  
     138 7   47  87  127 167 36  76  116 156 25  65  
     105 145 14  54  94  134 3   43  83  123 163 32  
     72  112 152 21  61  101 141 10  50  90  130 170 
     39  79  119 159 28  68  108 148 17  57  97  137 
     6   46  86  126 166 35  75  115 155 24  64  104)
    
    (171
     0   35  70  105 140 4   39  74  109 144 8   43  
     78  113 148 12  47  82  117 152 16  51  86  121 
     156 20  55  90  125 160 24  59  94  129 164 28  
     63  98  133 168 32  67  102 137 1   36  71  106 
     141 5   40  75  110 145 9   44  79  114 149 13  
     48  83  118 153 17  52  87  122 157 21  56  91)
    
    (171
     0   25  50  75  100 125 150 4   29  54  79  104 
     129 154 8   33  58  83  108 133 158 12  37  62  
     87  112 137 162 16  41  66  91  116 141 166 20  
     45  70  95  120 145 170 24  49  74  99  124 149 
     3   28  53  78  103 128 153 7   32  57  82  107 
     132 157 11  36  61  86  111 136 161 15  40  65)
    
    (171
     0   24  48  72  96  120 144 168 21  45  69  93  
     117 141 165 18  42  66  90  114 138 162 15  39  
     63  87  111 135 159 12  36  60  84  108 132 156 
     9   33  57  81  105 129 153 6   30  54  78  102 
     126 150 3   27  51  75  99  123 147 0   24  48  
     72  96  120 144 168 21  45  69  93  117 141 165)
    
    (171
     0   23  46  69  92  115 138 161 13  36  59  82  
     105 128 151 3   26  49  72  95  118 141 164 16  
     39  62  85  108 131 154 6   29  52  75  98  121 
     144 167 19  42  65  88  111 134 157 9   32  55  
     78  101 124 147 170 22  45  68  91  114 137 160 
     12  35  58  81  104 127 150 2   25  48  71  94)
    ))

(define (common-prefix-len xs ys)
  (if (and (pair? xs)
           (pair? ys)
           (equal? (car xs) (car ys)))
      (+ 1 (common-prefix-len (cdr xs) (cdr ys)))
      0))

(define (make-name t len)
  (with-output-to-string
      (lambda ()
        (display "[")
        (if (string? (car t))
            (display (car t))
            (for-each display (add-between (take t len) " ")))
        (display "]"))))


(define (interleave xs ys)
  (cond
    ((null? xs) ys)
    ((null? ys) xs)
    (else (cons (car xs)
                (cons (car ys)
                      (interleave (cdr xs) (cdr ys)))))))

(define make-named-table cons)
(define table-name car)
(define table-vector cdr)

; vector of named-tables
; the table-vector of each contains mod-1 notes
(define mapping-tables
  (apply vector
         (let* ((nameless (filter (lambda (x) (not (string? (car x)))) mapping-table-list))
                (name-len (if (< (length nameless) 2)
                              3
                              (+ 1 (apply max (map2 common-prefix-len (sort nameless (comparer <)))))))
                (names (map (lambda (t) (make-name t name-len))
                            mapping-table-list))
                (named-tables (map (lambda (name table)
                                     (make-named-table name (apply vector (convert-to-mod-1 (if (string? (car table))
                                                                                                (cdr table)
                                                                                                table)))))
                                   names mapping-table-list)))
           (for-each (lambda (name)
                       (send (hash-ref gui-fields 'from-table) append name)
                       (send (hash-ref gui-fields 'to-table)   append name))
                     names)
           named-tables)))

(define (cycle-table n)
  (make-named-table n (apply vector (convert-to-mod-1 (cons modulus (build-list modulus (lambda (k) (mod (* k n) modulus))))))))

(define (distance a b)
  (min (interval-1 a b)
       (interval-1 b a)))

; index in vector v of note nearest to n
;    among the first len elements of v
(define (pos-in-vector n v len)
  (let recur ((i 0)
              (p #f)
              (min-d 1))
    (if (>= i len)
        p
        (let ((d (distance n (vector-ref v i))))
          (if (< d min-d)
              (recur (+ 1 i) i d)
              (recur (+ 1 i) p min-d))))))

(define (map-between-vectors note v1 v2)
  (round (* modulus (vector-ref v2 (pos-in-vector (/ note modulus) v1 (min (vector-length v1) (vector-length v2)))))))

(define (map-between-tables notes t1 t2)
  (cons (table-name t1)
        (cons (table-name t2)
              (map (lambda (n)
                     (map-between-vectors n (table-vector t1) (table-vector t2)))
                   notes))))

(define (arithmetic-series lo (hi lo) (step 1))
  (if (> lo hi)
      '()
      (cons lo (arithmetic-series (+ lo step) hi step))))

(define (compute-tables cycle table)
  (if (null? table)
      (map cycle-table (apply arithmetic-series cycle))
      (map (lambda (n) (vector-ref mapping-tables n)) table)))

(define (all-mappings notes)
  (map (lambda (args)
         (apply map-between-tables notes args))
       (cartesian-product (compute-tables from-cycle from-table)
                          (compute-tables   to-cycle   to-table))))

(define (display-motif m)
  (display (car m))
  (display "->")
  (display (cadr m))
  (display ": ")
  (display (cddr m))
  (newline))

(define (boulez-multiply xs ys swap-args)
  (let ((xs (if swap-args ys xs))
        (ys (if swap-args xs ys)))
    (map (lambda (y+x)
           (apply transpose-note modulus y+x))
         (cartesian-product ys xs))))

(define (mapbc-then-multiply multiplier swap-args)
  (map (lambda (mapped-motif)
         (cons (car mapped-motif)
               (cons (cadr mapped-motif)
                     (boulez-multiply (cddr mapped-motif) multiplier swap-args))))
       (all-mappings motif)))

(define (multiply-then-mapbc multiplier swap-args)
  (all-mappings (boulez-multiply motif multiplier swap-args)))

(define (mapbc-and-multiply multiplier swap-args)
  ((if (equal? mm-order "map, then multiply")
       mapbc-then-multiply
       multiply-then-mapbc)
   multiplier swap-args))

(define (mmm)
  (copy-settings-from-gui-to-vars)
  (initialize-keyboard #t)
  (display-settings 4)
  (let* ((multiplier (if multiplier-special
                         (build-list (third multiplier)
                                     (lambda (n)
                                       (+ (first multiplier) (* n (second multiplier)))))
                         multiplier))
         (results 'whatever)
         (p (lambda (b)
              (set! results (mapbc-and-multiply multiplier b))
              (for-each display-motif results))))
    (when (member multiplicand-order '("motif times multiplier" "both"))
      (p #f))
    (when (equal? multiplicand-order "both")
      (newline))
    (when (member multiplicand-order '("multiplier times motif" "both"))
      (p #t))
    (when identify-results
      (newline)
      (newline)
      (for-each (lambda (result)
                  (display-motif result)
                  (newline)
                  (print-identification modulus (cddr result))
                  (newline))
                results))))

(define (positions->spacing positions)
  ((if wrap-spacing map2 map2a)
   (lambda (a b) (modulo (- b a) spacing-row-length))
   positions))

; row is a list of distinct notes
; return a function which, given any element of row,
;   returns the position where it occurs in row
(define (position-func row)
  (let ((v (make-vector modulus)))
    (let recur ((row row)
                (n 0))
      (when (pair? row)
        (vector-set! v (car row) n)
        (recur (cdr row) (+ 1 n))))
    (lambda (x) (vector-ref v x))))

; spacing of xs in ys
(define (spacing xs ys)
  (positions->spacing (map (position-func ys) xs)))

; row is a list of notes, not necessarily distinct
; return a function which, given any element of row,
;   returns a list of the positions where it occurs in row
(define (position-list-func row)
  (let ((v (make-vector modulus '())))
    (let recur ((row row)
                (n 0))
      (when (pair? row)
        (vector-set! v (car row) (cons n (vector-ref v (car row))))
        (recur (cdr row) (+ 1 n))))
    (lambda (x) (vector-ref v x))))

; list of spacings of xs in ys
; each spacing is a list of numbers
(define (spacings xs ys)
  (map positions->spacing
       (apply cartesian-product
              (map (position-list-func ys) xs))))

(define (spacing-ok? sp)
  (and (<= spacing-error-min
           (count (lambda (x) (not (<= spacing-min x spacing-max)))
                  sp)
           spacing-error-max)
       (<= 1-space-min
           (count (lambda (x) (= x 1))
                  sp)
           1-space-max)))

(define (some-spacing-ok? xs ys)
  (if (= modulus row-length)
      (spacing-ok? (spacing xs ys))  ; this is just a speed optimization
      (ormap spacing-ok? (spacings xs ys))))  ; this would work correctly in all cases

(define (transpositions row)
  (build-list modulus (lambda (i) (transpose-scale modulus row i))))

; same as (append (reverse a) b), but faster
(define (append-r a b)
  (if (null? a)
      b
      (append-r (cdr a) (cons (car a) b))))

; same as (append-r (map f lst) lst), but faster
(define (append-r-map f lst)
  (let recur ((lst lst)
              (result lst))
    (if (null? lst)
        result
        (recur (cdr lst) (cons (f (car lst)) result)))))

(define (standard-transformations row)
  (append-r-map reverse
                (append-r-map invert-scale-m
                              (transpositions row))))

(define (multiply-note n x)
  (modulo (* n x) modulus))

(define (multiply-row r x)
  (map (lambda (n) (multiply-note n x))
       r))

(define (motif-ok? row)
  (let ((motif (take row motif-length))
        (ok? (lambda (xformed-motif) (some-spacing-ok? xformed-motif row))))
    (>= (+ (if standard-transforms (count ok? (standard-transformations               motif   )) 0)
           (if       5m-transforms (count ok? (standard-transformations (multiply-row motif 5))) 0))
        motif-min)))

; return a list of lists, each of which is the
;   same as lst except that one of its elements
;   (a different one for each sublist) has been
;   moved to the front, with the other elements
;   appearing in the same order as in lst
(define (move-each-to-front lst)
  (let recur ((a '())
              (b lst)
              (r '()))
    (if (null? b)
        r
        (recur
          (cons (car b) a)
          (cdr b)
          (cons (cons (car b) (append-r a (cdr b)))
                r)))))

; call f (for side-effects only) on certain permutations,
;    each of length n, of elements taken from lst
; every permutation starts with (car lst)
; if n is greater than the length of lst, in each permutation
;    all elements of lst are used before any is repeated
; the permutations are constructed one element at a time,
;    and ok? can return #f to indicate that we should bail
;    out early, if it determines that no permutations that
;    start a certain way should be passed to f
; ok? uses data to help make its decision, and it returns
;    new data which will be passed into subsequent calls to it
(define (call-with-permutations lst n f ok? final-ok? data)
  (let recur ((perm (list (car lst))) ; initial part of permutation constructed so far, in reverse
              (n (- n 1))             ; number of elements that still need to be added to perm
              (xs (cdr lst))          ; list of possibilities for the next element
              (data data))            ; summary data computed by ok? based on perm
    (if (zero? n)
        (let ((fwd-perm (reverse perm)))
          (when (apply final-ok? fwd-perm perm data)
            (f fwd-perm)))
        (for-each (lambda (y)
                    (let ((new-data (apply ok? (car y) perm data)))
                      (when new-data
                        (recur (cons (car y) perm) (- n 1) (cdr y) new-data))))
                  (move-each-to-front (if (null? xs) lst xs))))))

(define (partial-row-ok? note row row-len n-bad-cell n-good-cell n-bad-interval n-good-interval last-interval n-interval)
  (let ((i (interval (car row) note)))
    (let ((n-interval (if (= last-interval i) (+ 1 n-interval) 1))
          (last-interval i)
          (n-bad-interval (+ n-bad-interval (count-intervals mof-bad-intervals note row)))
          (n-good-interval (+ n-good-interval (count-intervals mof-good-intervals note row)))
          (n-bad-cell (+ n-bad-cell (count-cells mof-bad-cells note row row-len)))
          (n-good-cell (+ n-good-cell (count-cells mof-good-cells note row row-len)))
          (row-len (+ 1 row-len)))
      (and (not please-stop)
           (<= n-interval interval-repetition-max)
           (<= n-bad-interval mof-bad-interval-max)
           (<= n-bad-cell mof-bad-cell-max)
           (list row-len n-bad-cell n-good-cell n-bad-interval n-good-interval last-interval n-interval)))))

; number of initial elements of list xs that are equal to x
(define (run-length x xs)
  (let recur ((xs xs)
              (n 0))
    (if (or (null? xs)
            (not (equal? x (car xs))))
        n
        (recur (cdr xs) (+ 1 n)))))

(define (final-row-ok? fwd-row row row-len n-bad-cell n-good-cell n-bad-interval n-good-interval last-interval n-interval)
  (and (>= (+ n-good-cell (if wrap-row (final-count-cells mof-good-cells row row-len) 0))
           mof-good-cell-min)
       (>= (+ n-good-interval (if wrap-row (final-count-intervals mof-good-intervals row) 0))
           mof-good-interval-min)
       (let ((intervals ((if wrap-row map2 map2a) interval fwd-row)))
         (and (>= (length (remove-duplicates intervals))
                  distinct-interval-min)
              (or (not wrap-row)
                  (and (<= (+ n-bad-cell (final-count-cells mof-bad-cells row row-len))
                           mof-bad-cell-max)
                       (<= (+ n-bad-interval (final-count-intervals mof-bad-intervals row))
                           mof-bad-interval-max)
                       (<= (let* ((i (interval (car row) (car fwd-row)))
                                  (rl (+ 1 (run-length i intervals))))
                             (min row-len
                                  (if (= i last-interval)
                                      (+ n-interval rl)
                                      rl)))
                           interval-repetition-max)))))))

(define initial-data '(1 0 0 0 0 -1 0))

; call f on row if row passes the tests specified
;   by functions ok? and final-ok?, which work the
;   same as those passed to call-with-permutations
(define (call-with-row row f ok? final-ok? data)
  (let recur ((rr (list (car row)))
              (r (cdr row))              
              (data data))
    (if (null? r)
        (when (apply final-ok? row rr data)
          (f row))
        (let ((new-data (apply ok? (car r) rr data)))
          (when new-data
            (recur (cons (car r) rr) (cdr r) new-data))))))

; x and y are lists of equal length
; return the number of positions at which x and y differ
(define (hamming-distance x y)
  (let recur ((x x)
              (y y)
              (n 0))
    (cond ((null? x)  n)
          ((equal? (car x) (car y))  (recur (cdr x) (cdr y) n))
          (else                      (recur (cdr x) (cdr y) (+ 1 n))))))

(define (near? d x y)
  (<= (hamming-distance x y) d))

(define (near-any? d x ys)
  (ormap (lambda (y) (near? d x y))
         ys))

(define (self-eq? same x y)
  (define (na? a b)
    (near-any? self-eq-tolerance a b))
  (or (na? x (if same (cdr (all-rotations-m y)) (all-rotations-m y)))
      (na? x (all-rotations-m (reverse y)))
      (na? x (all-rotations-m (invert-scale-m y)))
      (na? x (all-rotations-m (reverse (invert-scale-m y))))))

(define (self-equivalent? row)
  (or (and self-eq-standard (self-eq? #t row row))
      (and self-eq-5m       (self-eq? #f row (multiply-row row 5)))))

(define (process-row! row)
  (when (and (motif-ok? row)
             (not (self-equivalent? row)))
    (found! row)))

(define (rotation-transformations row)
  (let ((inverted-row (invert-scale-m row)))
    (append (all-rotations-m row)
            (all-rotations-m (reverse row))
            (all-rotations-m inverted-row)
            (all-rotations-m (reverse inverted-row)))))

(define (remove-near-duplicates rows)
  (let recur ((processed '())
              (unprocessed (map rotation-transformations rows)))
    (if (or please-stop (null? unprocessed))
        (map car (append unprocessed processed))
        (let ((row (caar unprocessed)))
          (if (ormap (lambda (ys) (near-any? duplicate-tolerance row ys))
                     processed)
              (recur                         processed  (cdr unprocessed))
              (recur (cons (car unprocessed) processed) (cdr unprocessed)))))))

(define mof-bad-cells '())
(define mof-good-cells '())

(define settings-in-use '())
(define loaded-results '())
(define loaded-results-path "")

(define (mof)
  (copy-settings-from-gui-to-vars)
  (set! settings-in-use (get-data-from-gui))
  (initialize-keyboard #t)
  (display-settings 5)
  (display-now "finding rows...")
  (set! mof-bad-cells  (map preprocess-cell mof-bad-cells-raw))
  (set! mof-good-cells (map preprocess-cell mof-good-cells-raw))
  (set! found-scales '())
  (if (equal? results-file "")
      (begin
        (set! loaded-results '())
        (set! loaded-results-path "")
        (call-with-permutations (build-list modulus values) row-length
                                process-row! partial-row-ok? final-row-ok? initial-data))
      (let ((path (normalize-results-path results-file)))
        (when (not (equal? path loaded-results-path))
          (read-results results-file #f))
        (call/cc
         (lambda (quit)
           (for-each (lambda (result)
                       (if please-stop
                           (quit)
                           (call-with-row result process-row! partial-row-ok? final-row-ok? initial-data)))
                     loaded-results)))
        (set! found-scales (reverse found-scales))))
  (displayln (if please-stop "interrupted" "done"))
  (newline)
  (let ((n-row (length found-scales)))
    (display "number of rows found: ")
    (displayln n-row)
    (newline)
    (when filter-duplicates
      (display-now "removing near-duplicates...")
      (set! please-stop #f)
      (set! found-scales (remove-near-duplicates found-scales))
      (displayln (if please-stop "interrupted" "done"))
      (newline)
      (set! n-row (length found-scales))
      (display "number of rows remaining: ")
      (displayln n-row)
      (newline))      
    (set! please-stop #f)
    (print-scales (if (<= n-row rows-max)
                      found-scales
                      (random-sample found-scales rows-max #:replacement? #f)))))

(define mallalieu '(0 1 4 2 9 5 11 3 8 10 7 6))

(define (repeat n f)
  (when (> n 0)
    (f)
    (repeat (- n 1) f)))

(define test-x 0)

(define (test)
  (set! test-x 0)
  (call-with-permutations
   (lambda (p) (when (motif-ok? p) (set! test-x (+ 1 test-x))))
   (lambda args '())
   (lambda args '())
   12
   '(0 1 2 3 4 5 6 7 8 9 10 11)
   '()))

(send the-frame show #t)


Download the Dr. Racket operating system from:
https://racket-lang.org


As for Lyd. Chro. it was a book and a course and the fiefdom of George Russell.

Yeah, you get it right in your second paragraph.

There's the logical framework of how scales are constructed and their possiblities. Everyone will find the some little world of scales, there's only
a limited set of possiblities, which through combinations becomes vast.

There are some good insights and some wooly opinions.

If you read the original Lyd. Chro. text, you realize that theorists of jazz like George Russell were really working on their own and didn't conform to academic standards. What Russell was doing was both more and less than academics. It was a composition practice and an approach to soloing, and a discussion of whatever interested Russell in music, without regard for academic caution or rigor.

Having been a theoretic fanatic from an early age, I instinctly stayed away from Russell's course at NEC. This was probably wise. We would have ended up screaming at each other. Now I know vastly more than I did then, but even now I would find it hard to avoid arguing with someone like that, and just getting what you could from him.

I think there was:
1) benefit from study of scale-logic
2) little benefit from his way of thinking about the specifics of "tonal gravity"
3) some benefit in his way of talking about the vertical, the horizontal, and what he thinks different players throughout jazz were doing
4) plenty of inspiration to be found in Russell's charts and his example -- he tried to think big and he was working on his own. I've liked some of his tunes and arrangements.

He was what he called a "vertical" composer, meaning he would layer parts on top each other, to good effect I think. Haven't heard the more advanced stuff in a while.

None of this stuff matters unless you feel you need to know it or do it.

Microtonal Scales crashed your computer or something last time. Let me know if you do get it working and you want further instruction. It's my baby, I'm proud of it, I'd love to see it benefit someone.

It may be no use to you.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 13th February 2018, 04:12 AM   #88
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Yeah, that version wasn't the latest.

The latest I posted yesterday in the 12-tone thread.

It shouldn't crash anybody's computer, because it's a legal program that compiled properly inside Dr. Racket.

But if you set your parameters wrong, you may have to wait for the heat-death of the universe before you get your answer. In that case, pull the plug, make some changes.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 13th February 2018, 01:49 PM   #89
Dani
Master Poster
 
Dani's Avatar
 
Join Date: Feb 2007
Location: Sometimes
Posts: 2,044
Yeah, I also had read that excerpt from the Quincy Jones interview. That exact part, from a whole different source. Funny.

I had no idea what he was talking about. The only thing that could vaguely make sense to me is purely in terms of scale structures. Can you play 12-tone series in a harmonic structure that moves by thirds? Well... yes? (the whole octave gets wrapped up really fast when you divide it in three equal parts). Does it make sense to think in these terms in a Coltrane tune with actual chord changes? Well... no?

Thanks a lot for your feedback, Calebprime. I'll check that link later.

Hi Varwoche!
Dani is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 13th February 2018, 02:27 PM   #90
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Originally Posted by Dani View Post
Yeah, I also had read that excerpt from the Quincy Jones interview. That exact part, from a whole different source. Funny.

I had no idea what he was talking about. The only thing that could vaguely make sense to me is purely in terms of scale structures. Can you play 12-tone series in a harmonic structure that moves by thirds? Well... yes? (the whole octave gets wrapped up really fast when you divide it in three equal parts). Does it make sense to think in these terms in a Coltrane tune with actual chord changes? Well... no?

Thanks a lot for your feedback, Calebprime. I'll check that link later.

Hi Varwoche!
yeah, if you do, I think I posted a later version of the source code in the 12-tone row thread, but it won't make any difference for the scale stuff. This latest version (not so recent, maybe a year old, actually) has tools for 12-tone.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 14th February 2018, 11:05 AM   #91
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Heh, I'm slightly provoked to find the Slonimsky that supposedly is Giant Steps.

Someone on the internet says it's in the preface. good -- that narrows it down considerably.

I think this is just loose talk, because there's nothing that matches in the preface.

There is this, however. I've put in divisions to show chunking: |

e,d,g,a, | g#,f#,b,c# | c,bb,eb,f


I think that's what people are talking about.

If you ignore the harmonization, transpose the passage, remove 3 notes, add different chords, entirely change the musical sense, and change the rhythm, you've got a partial match!

meh.

like most jazz theory and loose talk: meh.

Given that the Slon. is intended to be an encyclopedia of all possible intervallic material, it wouldn't be surprising to find all kinds of matches to all kinds of music. Sure Coltrane studied it, but he didn't even come close to borrowing.


Also, the tune Giant Steps is good because of its entire construction -- the whole thing makes sense. For example the way the main tones resolve melodically in the beginning phrases is a lovely thing that Coltrane put in there that is not just transposing the same set of notes mechanically. I mean how the melodic G resolves to the F# of the B triad.

That's all Coltrane.

Last edited by calebprime; 14th February 2018 at 11:16 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 14th February 2018, 02:52 PM   #92
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
I stumbled on this jazz theory disseration.

It shows how far things have come since George Russell's day, in terms of the professionalism of theory applied to jazz.

https://files.mcclimon.org/projects/dissertation.pdf

It related to my previous discussion with Dani where I said that the trend of theory is this sort of transformation-network stuff.

And, I said that this is sort of by and for theorists. Which is to say that it is all about explanation and lovely pictures.

Whether anyone actually achieved musical insight this way, or whether anyone ever composes with this sort of theory apparatus in her head is anybody's guess. Composers are various. They think about all kinds of things. Probably someone actually thinks this way: He makes diagrams like this to help himself compose?

?? I personally doubt this.

The author is a member of this and that theoretical society. He's a theorist. I really don't know what theorists do besides talk to other theorists.

I say this because the spirit is far from even Schillinger or Slonimsky or Russell or Schoenberg.

They were all composers. Their books give off an entirely different vibe than this pro theory stuff.

It's not bad. It's pretty. I just don't see how it explores new space.

Theorists are too respectful of the music lit. They rarely have ideas that point the way forward.

Or so my prejudice says, as does the experience of my years in the acad. (about 6 years as a student and 6 years teaching at NEC).

It is said that you're old if you're reluctant to learn new things. I say there's an infinite amount of unimportant stuff to get past. You have to choose.

Again, my idea of fairly inspiring theory to read: Other Harmony by Tom Johnson. ( A composer and player). At least it has a merry do-it-yourself vibe.

Last edited by calebprime; 14th February 2018 at 02:55 PM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 18th February 2018, 01:33 PM   #93
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
I thought I'd write some notes in criticism of __Other Harmony__ as they occur to me.

Damn, good theory is hard to find, and this is almost good theory.

--His choice of theorists and the breadth of his musical/cultural awareness: B
Euler, Obouhow, Hauer, Schillinger, Slonimsky, and Messiaen.

He's right: Everyone would write a different book. I wouldn't choose Messiaen or Schillinger or Obouhow or Euler or Hauer, I think, nor would I have organized chapters around theorists. Individuals should be footnotes.

Intro v. : He's entitled to whatever subject and scope he chooses, but he has an awfully odd way of saying that he's limiting his subject to the 12-tone tuning.

"...but all these things are not really harmony." Could you have picked a worse way to say that you're not covering differing tunings -- that this study is "not really harmony?" Shame. What a stupid thing to say.


What a bizarre little chapter Tonality, the first one, is. Did you have a deadline and had to rush to press?

pg. 24. Of course, not really being interested in 12-tone rows, he's convinced that the typology of Jedrezejewski grouping all series into 554 "knots" is some big advance. It's not, I've looked into it. A particular knot has many series with different properties associated with it, and I have yet to see a demonstration of why grouping things this way has any utility at all, other than a feeling of neatness or something. The standard 12-tone inversion square accomplishes the same thing as these diagrams and a lot more besides. If you have no feel for a subject, don't go into it.

pg. 25 He makes the very mistake of referring to Forte numbers, which I've already criticized as unneccessary jargon. Simply call a pc-set by what it is, not some tacked-on number.

pg. 28 He makes a big deal of z-related pairs (same interval counts or "interval vectors" (there's a pretentious term). Yawn. Yes, there are things to learn from the 5m transformation (semitones-to-fourths) and their relationships, but that's basic theory, and deserves a clear little section. It's basic; it's not Forte, or if it was, it's trivial. Z-related my ass. Call it 5m or 5x.

pg. 30. Don't call it Forte 4-22, call it a Mu chord. The add 9 chord isn't some exotic non-standard thing. He makes a tedious little common-tone progression. Show some taste. That example is of no interest.

Euler -- this chapter is sketchy and pointless, mixing some completely uninteresting results with a sketchy and useless little table of equivalences between ratios and notes of the chromatic scale.

So far, not good, if you are like me, and searching for something. What's good is the do-it-yourself attitude, but this is apparently part of the problem.

He can't seem to deal with 12-tone technique as something to be used or adapted or appropriated in the same spirit. Why not? He's part of the generation of composers who felt oppressed and brow-beaten by some kind of short-lived serial orthodoxy. This is his emotional problem, and it's a major weakness. All those techniques can be sifted through and treated with exactly the same spirit that he treats Schillinger, etc. but he can't seem to bear to do it.

The deeper I look, the less interesting his musical mind is. If you're writing a short, sketchy book, you better make each and every thing tell. It should be good and important. Your examples should show this. The Euler examples are terrible.

I'll keep going -- perhaps there's something in here.

Last edited by calebprime; 18th February 2018 at 01:44 PM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 19th February 2018, 12:43 PM   #94
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
_Other Harmony_. pg. 28

Here Johnson had an opportunity to discuss whether inversions should be treated as "the same" in a taxonomy of chords, and he missed some simple things to say, instead launching an attack on one Balsach.

Forte taxonomy doesn't DO anything. You as composer are free to do with it what you want. You are free to group inversions together, choosing the "smallest" form, as does Forte. You are free to invent some simple little notation to distinguish and connect inversions. 037=047i.

047i=037. Problem solved. Done.

A major triad is related to a minor triad by inversion but they're not "the same".

Again: Nothing is at stake with Forte taxonomy. This is a pseudo-problem, and Johnson should know this and say so. It's trivial.

Anyone who thinks she is going to arrive at some grand system, or some grand insights by studying Forte is kidding herself.

I once harbored such illusions when I was maybe 20 -- somehow you could classify all chords according to how consonant or dissonant, and that would lead to a way of progressing and combining, some grand scheme... No. There's nothing there. Nothing of musical importance.

Johnson might have mentioned that as chords get more and more complicated in this system, they mean less and less, and the classification has less and less salience. Chords give way to a few scales and quite a few combinations of pitches that have no particular sound or meaning or use.

Forte is quite useful for 3-to-6-note (7, or 8-note on the outside, rarely) chords simply because it gives clear names that in fact are the chords. You say 0347, or 03479, you hear it, you understand it without ambiguity.

Again, where 0347 fell on his list of 4-note structures is of no interest. This is noise that should be removed from the discourse.

That's what Forte is good for. Oh, that and providing fodder for theorists to teach to bored students who aren't going to use it for anything anyway.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 19th February 2018, 01:42 PM   #95
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Johnson pg. 12. A botched discussion of Mazzola and scale-construction.

Very interesting subject, worst discussion by Johnson, ever.

Mazzola supposedly constructs 32 scales by holding a C and G constant, and -- in this unclear explanation by Johnson, given that this should be easy stuff -- varying the other 5 categories freely.

Then, infelicitously, these are called "the altered scales of C major.??

Johnson, you might have thought about it for a second and realized that some of these scales are not like the others, and some are very familiar, and some have all kinds of prior meaning, and that all equal-tempered scales fit into a system with well-known names. Some are well-formed and some are not.

Why hold the G constant, for that matter?

"The model is more general the the usual list of church modes, or even the Indian ragas". No, it's different, not more general, and it's not particularly useful.

For example, C,Db,E,F#,G,Ab,B is not a "scale" in anything but name.

One of the characteristics of any well-formed scale is that it's an automatic source of harmony, without aural confusion or train-wrecks.

Remember, this was supposed to be a book about harmony, right?


---------------------

Now, on to the revealing vacuity of the Euler section.

The idea is simple: Derive tones from the upward-going overtone series, that is, only multiples, only overtones.

So you get 25, and use that for "minor 6th" or "sharp 5".

I have to wonder if Johnson is suffering from dementia if his grand climax is, get this: A major-7 sharp 11 chord, known to every teenager who ever thought about jazz for five minutes. A garden-variety chord.

Yes, major 7 is 15, yes #11 is 45. No ****, Sherlock.

This man lives in some bubble where he can't tell his bog-standard stupid ideas from his occasionally vaguely-interesting ones.

I'm just getting started. There's crap on every page in this book.

The other Euler examples are bad because they're each more-or-less the same chord, with a note or two different.

So many bad examples, so little insight!

Last edited by calebprime; 19th February 2018 at 01:48 PM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 19th February 2018, 02:37 PM   #96
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
The section on Hauer's tropes is slightly better, but if you cut out the tendentious comparisons to Schoenberg and complaints about being browbeaten by his professors -- none of that of any interest -- it's still sketchy.

Hauer wasn't that bright. He couldn't even define his own pitch-class sets. The texture of his music was simple-minded like a perpetual first prelude.

Now, there are plenty of examples of pairs of intellectual workers, where one was a genius and the other was ordinary, and they both made important contributions at the same time. Watson and Crick. Braque and Picasso.

I'd be happy to be Braque, but not happy to be Hauer.

Schoenberg/Hauer is not like Picasso/Braque.

Schoenberg wrote more than his fair share of tonal and atonal masterpieces, radical music in every case that pushes the boundaries, whether of Wagnerian harmony or of 12-tone construction. His music seethes, flickers, smothers. Serialism was as sketchy an idea as pychoanalysis. Your chances of getting a good piece from it were as remote as being cured by lying on a couch and describing your dreams. It happened, occasionally, rarely.

Dissing Schoenberg as an authority is like dissing Freud, except Schoenberg had some integrity. Easy target.

Hauer is just a footnote.

There's a (moldy) false dilemma here between the world of traditional tonal harmony and Second Viennese School. There was a little thing called Impressionism, remember? Bartok? Even, yecchh, Richard Strauss?

I might wish to think formally, say, about what can be done with complementary 6-note sets. Sessions was said to compose with exclusive hexachords, I don't really know for myself.

This is a poor discussion for showing the boundaries of this kind of construction and the materials, but it is a (poor) introduction, at least.

But Johnson is publishing a cheap book, and you can barely read his hand-written examples, and I'm not sure of their significance. Johnson is the kind of guy who loves cute displays. I don't. You can use your words, and pitches. You don't have to trick it up.

He keeps saying Hauer is as rigorous as Schoenberg (who wasn't really that rigorous, actually, who believed in working at top speed, in white heat and who was impatient with discussion of materials and being too careful about it).

Schoenberg was a better composer than he was a theorist, and for those of us who only hear tonally as do I, there's a radical difference between listening to the more austere pieces like his Trio, and his tonally-inflected serial pieces like the Piano Concerto. The former is painful, the latter is quite beautiful.

A conductor who was on this board some years ago (bipolar, etc.) seemed to not distinguish between what I call radically different sounds. He had absolute pitch, and liked the music of John Tavener! Our difference in taste would be a fundamental difference in music cognition, not just a matter of personal temperament or belief. (I dislike contemporary religious composers, for the most part.)

Last edited by calebprime; 19th February 2018 at 02:38 PM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th February 2018, 04:23 AM   #97
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Slonimsky chapter. My comment: Yes, Slonimsky was good, rigorous, had a great spirit.

A rare semantic quibble from me that I hope leads somewhere thoughtful:

pg 63: "Though the focus of the book is melody, it also provides insights into harmony".

I hate to redefine simple words with obvious meanings, but "melody" is a problem here. I wouldn't say that there are melodies in the book -- they are scale exercises or arpeggios. They are melodic precursors. An arpeggio is as much a harmony as a melody, and so are chord-scales.

Johnson fails to name one of his little exercises with the extremely commonly known name: It's an octotonic scale, Tom. Yikes.

How do you manage to keep your knowledge so compartmentalized?

I was hoping for an appreciation of Slonimsky's constructive brilliance, which anticipates recursion and possibly cellular automaton.

Yes, there's no such thing as octave equivalence. Yes, there's fascinating things to say about multi-octave scales. No, it's not a theoretical conundrum. It's just a bigger possibility space.

You haven't begun to get your house in order with one-octave scales, how can you then build on that confusion to cover multi-octave scales?

An embarrassing end to the chapter, where he lists 3 12-tone "chords". I use scare quotes because they are extravagent monsters which would suffer little if you removed a note, making them 11-note chords.

The embarrassing thing is that he opines that these structures have "probably never been employed in any composition". Durrrrrrrrrrrrr. Ever heard of frickin' Elliott Carter?

You'd expect someone who writes a book would at least check his assertions, especially since he's hostile to the modernist "establishment" -- that barely established, nearly non-existent thing that more or less died off by 1975?
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th February 2018, 07:18 AM   #98
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Nikolai Obukhov, or "Obouhow" in the spelling of this book.

A mystic, which is not a good thing -- Scriabin managed to write some decent music despite being a mystic.

Another nearly content-free chapter.

This man was an early 12-tone composer. That is, he strove to have as many tones sounding at once. He had an ideosyncratic approach to writing "accidentals" (our traditional notation system is pretty stupid but it's adequate and can be stripped of its worst conventions, like key-signatures) which is much more stupid than traditional notation. You want to make sense of it, you have to re-notate it. Great.


I'm listening to some of his music on YouTube. Theramins are stupid.

A 5th-rate composer. Scriabin is a 4th-rater, like the author of this post.


Maybe this is the place for it: Especially when it comes to the shoddy avant-garde, plus ça change, plus c'est la même chose. You can tell I pasted this. The more the avant-garde seems to change, the more it stays the same. Mostly bad.

Last edited by calebprime; 20th February 2018 at 07:19 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th February 2018, 07:50 AM   #99
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Next chapter: Schillinger


Schillinger is anything but content-free.

This chapter is going to take me a little longer than the others, although I can say that Johnson is not attempting an overview or summary, but rather, picking a few things.

You take from Sch. some of his constructive ideas, those things that lead to clarity.

I'm going to review some of it with the purpose of answering Johnson's questions about what seemed mysterious. If I can, that is.

Last edited by calebprime; 20th February 2018 at 07:56 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th February 2018, 09:39 AM   #100
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
A clear section on color and talea.

Then, pg 87. a disastrous paragraph that shows how slovenly the book is.

Johnson is mystified by what Schillinger calls "binomial cycles" and "clockwise transformations". He says so. He apparently can't be arsed to read the ****in' book.

The first is explained in chapter 12 -- Distributive Powers.

The second is explained in the Introduction.

I'm no math genius, I haven't picked this book up in years or studied it seriously, and I was able to answer those two questions to my own satisfaction in about five minutes!

Don't they have these books in Paris? You have to rely on rumors, or something, like this is some samizdat literature?

I'll continue reading, but I'm actually disgusted at the moment.

This book is getting worse and worse the more I read it.

Schillinger remains original and useful, thank you very much.

eta: next chapter: Messiaen: Didn't even occur to him that an 014589 is a "mode of limited transposition?" Hats back on gentleman, an idiot. Zero respect for Messiaen as theorist, so next chapter.

This next chapter is novel content

Last edited by calebprime; 20th February 2018 at 09:54 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th February 2018, 10:08 AM   #101
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
The next chapter is, as far as I can tell, a bad or arbitrary idea which can act as a kind of control or generator, but which has no validity as far as harmony.

You can sum the values of pitches, to produce "heights". This bears a distant resemblance to the idea of symmetrical harmony with sums ("0-sum dyads") that George Perle developed, perhaps, except Perle was interested in systems of systems of sum-chords, and, as far as I know, only interested in the totality of the system as a source of pitches, freely composed.

George Perle's __Twelve-Tone Tonality__ -- one of the most disappointing books I've ever read, have to single it out for scorn. Why? Because it generated crap. You can compose with anything, including crap.

This is just irrelevant. Who cares what a particular chords' literal sums are? That, of all things, is in no way determinative of the sound, descriptive of it, etc.

This is a novel idea because it's stupid.

There are lots of things you can do. The question is whether they mean anything musically.

I think I understand this man's problem. He was a Morton Feldman student. Pretty as his very quiet pieces are, I'd wager that absolutely anything can work in that kind of texture -- it's really the oppposite of a harmonically tight situation. Feldman was an irrationalist. Johnson wants to be some kind of methodical irrationalist, which I have trouble sympathizing with. Another one was Cage -- scrupulous use of the I Ching. It is to be underwhelmed. Feh. Meh. Bleh. Geh.

I'm going to attempt to prove myself wrong: I'm going to have a little Morton Feldman festival right now. Work is done for today. I'll donate $100 to my least favorite institution -- The American Rifle Association -- if I come away admiring Feldman's "harmonies".

There are many composers who don't really want to understand what they're doing -- perhaps if they looked down, they might fall precipitously. Johnson clearly doesn't want to understand, or he wouldn't be making all the mistakes I've been pointing out so laboriously.

Last edited by calebprime; 20th February 2018 at 10:18 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th February 2018, 10:33 AM   #102
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Originally Posted by calebprime View Post
.... He was a Morton Feldman student. Pretty as his very quiet pieces are, I'd wager that absolutely anything can work in that kind of texture -- it's really the oppposite of a harmonically tight situation. Feldman was an irrationalist. ...

I'm going to attempt to prove myself wrong: I'm going to have a little Morton Feldman festival right now. Work is done for today. I'll donate $100 to my least favorite institution -- The American Rifle Association -- if I come away admiring Feldman's "harmonies".

....
I'm going to have to retract this immediately. Feldman does write a nice chord!
I wouldn't want some stupid opinion of mine to contribute to the mayhem.

Still. Repeat notes, spread them out, repeat them, play them softly, orchestrate, etc. and it's not that hard to get this sound. Especially: No bass. Drones, clusters. Chorale effects. That always works.

Rothko Chapel is a tonal piece. It's not Other. Tonal. Drones.

You want to know a real man who could play some harmony that actually moved?

Art Tatum. Not this halting decadent mysterioso crap.

Last edited by calebprime; 20th February 2018 at 10:41 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th February 2018, 11:01 AM   #103
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
I'm just envious because I want to be Morton Feldman. Or Art Tatum. Either one. Art Feldman-Tyson.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 21st February 2018, 03:28 AM   #104
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
I have criticized __Other Harmony__ for sloppy errors, and for inadequately or unfairly or sketchily covering other theorists.

He could write a second edition where those particular many errors are corrected, and the book was brought up to some minimal standard.

Then I would still criticize him for a kind of theoretical complacency. Whether because he is a mellow fellow, or because this book is for beginners, he doesn't seem to reconcile one theoretical area with another, nor examine the consequences enough, nor reject nonsense.

Theory can start in playful wonder, then you need to get it right.

I'm not proposing some kind of theoretical monoculture, but I do think that there are essential things that every composer needs to know if he wants to understand the world. There might be simpler and more complex versions of this: The simple theory is just a summary of the common consensual objects, and the more complex gets into the less-obvious, deeper levels of explanation, such as the study of the relation of ratios to tuning, and tuning to music, and ratios in harmony.

The simpler theory: A complete list of the common simple one-octave scales.
More complex: Add in the Indian raga-structures, and understand how they're different. Understand how some scales work to create harmonies, and some don't.
More complex still: Understand the ratios involved in making these scales. Understand low-interval limits concept.

Common-practice harmony in the 21st century: The simple consensual theory is very large and not so simple, and has to cover everything from The Who to Bach. A survey. Dispel notions such as: There is "forward" and "backward" harmonic motion. "Forward" is 4th-wise.
More complex: Some Schillinger-like systematic approach that goes beyond simply listing and describing what people have done. Because it is a system, it covers every possibility.
More complex still: Generative theories of tonal music, transformation networks

A Forte-like naming system for naming any pitch-class structure, but edited to removed Forte's particular affectations. An add-9 chord is no more "set 4-22" than my wachine machine is a "9 --156" because that's where the machine was listed in the Sears catalog. An 0247 is an 0247 is an 0247. You want that to cover inversions, too? Say so. End of story.

I'm not going to be as explicit, but this basic theory covers rhythm. Resultant rhythms, ratios, theories of limits to the intelligibility of poly-rhythms.

---------------------------

You don't need this stuff to be a good or even great composer or player.

Rather, if everyone had a good deal of this common knowledge, we could move theory discussions beyond muddling around at square one.

You shouldn't have four or five unrelated names for the same bog-standard thing. A major 7 sharp 11 chord should always be called that, and so should an octotonic scale. This is not monoculture, it's just enough consensus to get past square one, which many theory discussions never seem to do.

It should be clear when theory is about establishing a simple common language and when it's about actually generating something.

G7 #11 is the first kind of theory.
Schillinger and serialism, etc. is the second kind.

When you generate something, you always have to check to see whether it falls under the first kind of theory -- whether you re-invented the wheel, or the octotonic scale.

Otherwise, it's clown-car, every-generation-throws-a-hero-up-the-pop-charts. It's yee-haw, rock n' roll, know-nothingism. It's mimimalists refusing to learn from the maximalists and vice-versa.

It's [shudder] genres. Consumer preferences. It's willful ignorance.

Berklee, as a Schillinger school, sort of attempted to come closer to this catholic ideal. NEC was, frankly, pretty poor for theory. Again, Lewin's book GMIaT was never checked out in the 10 years it was on the shelf at NEC. I know because I was the only one.

---------------------------

Certain half-baked notions such as Modes of Limited Transposition should be laid to rest. These modes are not a unity, and they weren't even a complete list. It's like having Objets métalliques dans mon monde -- the coin, the toaster, the automobile, and the thermometer.

Last edited by calebprime; 21st February 2018 at 03:35 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 21st February 2018, 06:21 AM   #105
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940


The problem with having big opinions is that you worry maybe you were wrong. You'll see Perle in this little book collection.

All under review. Maybe I wuz so wronk.

My opinions about __Other Harmony__ while still under development, are pretty well-founded. I did the homework that most people simply don't do.

The purpose is to get clear about this stuff. As a composer, what works, and why? Does Perle's system really provide musical coherence, or is it really a generation method that produces a kind of inevitable result, but nothing the listener can hear or would want to hear? In other words, yet another system that makes it easier for the composer but no easier for anyone else?

With a lot of this stuff, by the time you've made the effort to understand it, you already have a kind of emotional commitment. This is to be avoided, which is really the purpose of my searches. Strip away the b.s., and the personal allegiances.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 23rd February 2018, 05:17 AM   #106
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Originally Posted by calebprime View Post
...
A rare semantic quibble from me that I hope leads somewhere thoughtful:

pg 63: "Though the focus of the book is melody, it also provides insights into harmony".

I hate to redefine simple words with obvious meanings, but "melody" is a problem here. I wouldn't say that there are melodies in the book -- they are scale exercises or arpeggios. They are melodic precursors. An arpeggio is as much a harmony as a melody, and so are chord-scales.

...


The reason this interests me is that some common-sense words like "melody" are really composites of more simple things, more elemental things.

It would be as if you were trying to understand human behavior, and one of the first concepts you were trying to understand is "parties". Parties are complex composite behavior, you'd want to understand it in some simpler terms, if you could. (Let's not get too hung up on that particular analogy.)

"Melody" is a composite of:
-- rhythm, (tempo)
-- sequence,
-- contour,
--register,
-- chord-scale (pitch material),
--directional tones/tension and resolution/starting somewhere, going somewhere else, coming back.
--timbre
--(lyrics, when applicable)
--(singer's other attributes, to get really ridiculous)
--(the attributes of the physical space of the performance -- the acoustics)

Roughly speaking! I haven't completely thought it through, but it seems that each of these elements is logically independent of the others.

We therefore have two ways of speaking. A common-sense way that doesn't try to look under the hood, and a slightly more analytical one that does.

With the one that does, it's as if you were trying to get a machine to generate something like a melody. What are the actual parameters?

An example of a theory that looks a step or two deeper than the surface is Schenkerian analysis, where, rightly or wrongly, one is always concerned with showing what is surface motion and what are structural pillars, important points of arrival, essential harmonies.

The feeling I get from reading Johnson is that his mathematical generative bent is more fully developed than his analytic side, but that seems strange in someone who specializes in generating music from mathematical structures.

Maybe it's simply a composer's egotism: He's much better when he's explaining his own pet ideas, rather than covering other people's work. That's the do-it-yourself side.

So, for example, if he'd wanted to know, Robert Morris did a lot of detailed work on chains of cells, and there was even an obscure computer program that you could buy 15 or 20 years ago that did chains of cells. Hence my disappointment in his 0247 chain example -- it seemed so lazy.

Heck, nous sommes tous égoïstes.

Last edited by calebprime; 23rd February 2018 at 06:06 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 23rd February 2018, 07:38 AM   #107
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Originally Posted by calebprime View Post
...
"Melody" is a composite of:
-- rhythm, (tempo)
-- sequence,
-- contour,
--register,
-- chord-scale (pitch material),
--directional tones/tension and resolution/starting somewhere, going somewhere else, coming back.
--timbre
--(lyrics, when applicable)
--(singer's other attributes, to get really ridiculous)
--(the attributes of the physical space of the performance -- the acoustics)

...
Heck, nous sommes tous égoïstes.
Don't ferget dynamics, there, Chief Always Loud.

Also: breath. phrasing. chunking, inevitability/surprise. novelty/fatigue. gravity.

next up: What is Love?

Last edited by calebprime; 23rd February 2018 at 08:33 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 24th February 2018, 04:11 AM   #108
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Originally Posted by calebprime View Post
...
"Melody" is a composite of:
-- rhythm, (tempo)
-- sequence,
-- contour,
--register,
-- chord-scale (pitch material),
--directional tones/tension and resolution/starting somewhere, going somewhere else, coming back.
--timbre

almost unrelated, but these color the experience:
--(lyrics, when applicable)
--(singer's other attributes, to get really ridiculous)
--(the attributes of the physical space of the performance -- the acoustics)
...[/i]
Originally Posted by calebprime View Post
dynamics,
breath.
phrasing. chunking,
inevitability/surprise. (predictability/unpredictability)
novelty/fatigue or familiarity
gravity.
While I'm adding to what's become a brainstorming list, there's one more useful notion: Poetic units, poetic meter.

That is: iambs and dactyls and whatnot, and number of beats per line.

This is useful the way the notion of contour is, because it is an alternative to thinking in mechanical timing units. It's a perhaps looser, more general way of thinking, based on surface sound.

It's in fact possible to have both kinds of rhythmic thinking going on at once in a piece of music -- mechanically-accurate ticking rhythmic background, with a floating melody that can only be defined by overall stress patterns. Ives or Weather Report or Bartok might be examples. eta: Walking and talking at the same time.

For example, the iamb can be thought of as:
unstressed upbeat | stessed downbeat. or: ta|DA.
Which can work over any number of particular rhythmic grids: The "ta" here could last 5 beats and the "DA" could last 14 beats, or anything that preserves the relative relationship of short-long.

You can have a "line" (or bar unit) with 5 poetic "beats" or accents or stresses that is actually counted in 7.



This is a useful way to describe stress-patterns, as long as you survey it for clarity and maybe clean it up a little for its application to music.

This is not intended to be a competent survey of poetic meter, and in any case, it would need to be examined and adapted slightly for music: It's important to not get hung up on historically-correct definitions for this purpose. What you would not want to do is consult with a poet to understand this.

Last edited by calebprime; 24th February 2018 at 05:16 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 9th April 2018, 06:17 AM   #109
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Gary Giddens is a well-known jazz critic and advocate for Cecil Taylor.

I found this interview to be a good source of insight into how Giddens thinks.

http://jerryjazzmusician.com/2003/03...-cecil-taylor/

It's rich with anecdotes about early controversy (Giddens was asked to resign for bringing Taylor to his school) and listener reactions.

My interests, unfortunately, are inconvenient and uncontrollable. I'm interested in this subject now. Otherwise, I'm quite ambivalent about posting at all.

Needless to say, I draw nearly opposite conclusions from every anecdote from Giddens, and my opinion is much, much less favorable.

I did listen to an early performance with bassist Neidlinger, and I heard a so-so evisceration of an actual tune with changes. Taylor could play changes early on, and yes, a little better than I thought, but like a 4th-rate Monk, and that's putting it nicely. I'm speaking as someone who isn't particularly attached to any style or player, but who has put in the necessary 10k hours (and a lot, lot more) in these things.

I also speak as someone for whom (by now, age 60) most pieces by Schoenberg are at least mostly intelligible, but for whom much of the serial pieces, such as the 3rd and 4th quartets, are quite unpleasant to listen to, and I would say, bad music. That, in a sense, puts a limit on my ears. I'm not a conservative, and I love the Five Pieces for Orchestra, but there is a fairly bright line between music that is intelligible and music that is not, and music that sounds good, and music that doesn't, for me.

I've been doing this too long for the kind of novice peak-experience stories Giddens tells.

Giddens notices that people's faces sag at the 4-minute mark. We interpret this differently. It's not that people ought to learn to listen with more discipline, as Giddens thinks.

I'll leave it there. My world was the world of narcissistic pretentious artists at New England Conservatory, of all shapes and sizes, so it takes one to know one.

Last edited by calebprime; 9th April 2018 at 06:20 AM.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 9th April 2018, 07:36 AM   #110
varwoche
Penultimate Amazing
 
varwoche's Avatar
 
Join Date: Feb 2004
Location: Puget Sound
Posts: 11,071
Replying to the above, plus your comments about Taylor in the other thread...

I've spent a lot of time over the years thinking about the line between structure / no structure, art / ********. A long time ago you made a passing comment about Don Pullen playing with his knuckles (that cracked me up). Once upon a time, I didn't know he did that. And I enjoyed his outside playing on record. Then I saw him live (in Mingus' band) and I had a WTF moment right on the spot. I landed in a conundrum that I've yet to mentally resolve.

I find Taylor to be utterly unlistenable. I can listen to Ornette Coleman (I think; it's been a long time) but not Taylor.
__________________
To survive election season on a skeptics forum, one must understand Hymie-the-Robot.
varwoche is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 9th April 2018, 08:33 AM   #111
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
Ornette Coleman's music often makes me really want to understand what's going on with it -- his use of microtones and wandering modality is amazing to me. Charlie Haden had that absolute pitch too, so he could follow him in that band, I think.

Plus, some catchy tunes.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 1st May 2018, 02:38 AM   #112
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
I don't do Facebook, but my friend the Berklee prof told me of this post by Allan Chase. He was Dean of Faculty when I taught at NEC, and Chase and I played in the same band for about 3 weeks.

I would be interested in anything Chase has to say about Cecil Taylor

Quote:

originally posted by Allan Chase April 20, 4:06 pm

I don't want to be negative, but...there's a lot of nonsense and misinformation about Cecil Taylor and his music online these days. It's coming in many forms: laudatory but wrong, dismissive and wrong, and mixed and partly wrong. I know fact-checking isn't what it used to be, but Alex Ross says in the New Yorker, "A graduate of the New England Conservatory, he was rigorously trained in classical composition and performance." Someday, someone might want to look at the curriculum of the NEC Popular Music program Cecil Taylor was enrolled in. It's right there if you want to know. This idea that he "sounds classical," not like a jazz musician: what is it based on? Almost nothing, I think. For about 14 years, I taught a grad course at NEC called "Jazz Styles: Free Jazz and the Avant Garde." Cecil's music was by far the hardest to teach of any unit in that course, and I certainly didn't presume to explain or summarize it, only to introduce some of it, put it in some historical context, knock down the usual lame first impressions, and incentivize careful listening with assignments. (Having Joe Morris as a guest added a lot of insight I couldn't have provided.) How it worked (in different periods), what is essential and structured vs. what is relatively open, how the process and results worked and how he valued them, etc. are not easy to talk about or self-evident on the surface, as anyone who cares to delve into his and his collaborators' words and listen carefully to the music can tell. Instead of presumptuously explaining it based on their limited perceptions, people ought to be asking lots of questions of the people who played with him, and gathering as much information about his process and material as they can, while they can, as Stephen Haynes and others have been saying.
My highlight


I've read the Morris book. It was extraordinarily content-free.

This really is a peculiar situation for me. After all this time, I still don't know exactly what to think, which is why I'm still interested.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 1st May 2018, 06:21 AM   #113
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
You could state matters of artistic taste as hypotheticals. Would it matter if so-and-so were actually classically-trained, or jazz-trained? If he or she ever played any classical repetoire? If he or she actually ever was a master of traditional jazz? Would it matter if so-and-so were actually playing music with certain content, or an approximation of it -- such as polyrhythms like Carter, or polyrhythms like Ives or Mingus? Or with pitch-content that has some inner rigor? The answer to these and a bunch of other related questions might be: no, it doesn't matter.

Because if even if the artist creating this whirlpool of sound is at some level a pure artist manque', he's also pounded the piano and his listeners into submission without hesitation many times.

Or you might feel that as a listener, no one else has brought you this kind of radical experience.

And there are people who have played with him who revere him. And there is skeletal content in his pieces, the ever-elusive "unit structures".

I would like to hear something I can admire just once. I've checked out the articles only to find nothing there. I've listened maybe 20, maybe 40 times over the years. I hear 3 minutes of addititive groping, then torrential b.s., usually. By 3 minutes, his listeners are exhausted, so they don't care any more, they just zone out.

I think he was a ferocious advocate for the worst aspects of modernism, without his music even having the core content that makes modernism great.

All the bad stuff -- the length, the obscurity, the unintelligibility, the lack of harmony, melody, pulse, meter and form as we've known them, or even if some way we haven't.

But I'm still open to being converted by a single passage.

(And I don't mean some first-3-minutes-thing-with-a-pedal-tone, either. )

An artist manque in one and the same person with a performing demon -- unless things are not what they seem.

The combination is not as strange as it might seem, and again, here's where taste comes in. It may not really matter to many people if he was far sketchier and less gifted than the myth suggested.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Old 20th May 2018, 06:18 AM   #114
calebprime
moleman
 
calebprime's Avatar
 
Join Date: Jul 2006
Posts: 11,940
A man walks down the street
He says why am I short of attention
Got a short little span of attention
And wo my nights are so long
Where's my wife and family
What if I die here
Who'll be my role-model
Now that my role-model is
Gone Gone


http://www.legacy.com/obituaries/bos...770&fhid=25298

I'm trying to account for some of the reasons that my batteries -- as durable as any composer I know -- seem to be running down. One reason is personal failure. Another set of reasons is cultural.


I think that with the death of Peter Row, all my teachers and role-models have passed away.

It's hard not to feel that the ground is crumbling under my feet.

Last week I went into the Harvard Bookstore -- surely a center of elite civilization -- and found not a single book with music notation in the Music section. We live now in a mostly post-literate musical age. (There's still a local bookstore right across from NEC that sells books with notation in them.)

This means only that notational literacy and related things are not part of mainstream culture any more -- it's not the death of civilization.

My Berklee prof friend speaks of musically clueless students who only specialize in manipulating sound on their laptops -- they have no instrumental skills and no theory. How and what do you teach them? They've never heard of Stravinsky or Keith Jarrett.

It doesn't require that one be a prickly cactus or an ogre to become lonely and isolated as a composer. It only seems to require that one be committed to the same things that one was in youth -- basically that it would be really cool to create some really cool art. And really cool meant, essentially, the shiny space-ship. Something swift, sleek and ultimately intelligible if mysterious at first. My idea of what's cool hasn't really changed since my teens, all that much.

And then it only requires that one have moderate success and moderate failure -- just enough success to keep going in the whole shabby and dubious venture.

My constant focus on computer sequencing since the late 70's has been the key to all my important gigs, but it has also been isolating and it is obviously no longer novel or in vogue.

At some late point, your task shifts from building up a body of work to accepting without resentment that this body of work that seemed so precious is really nothing, even if it was the best you had to offer. And the same is true for all the projects so dear to your parents and mentors. It will all crumble and disappear, at this level -- the music of Tom McKinley, of John Bavicchi. Their huge scores used to fill the library. Now the library, of course, doesn't have room for scores like it used to.

It's like something written by Kazuo Ishiguro. __The Remains of the Scores__.
calebprime is offline   Quote this post in a PM   Nominate this post for this month's language award Copy a direct link to this post Reply With Quote Back to Top
Reply

International Skeptics Forum » General Topics » History, Literature, and the Arts

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -7. The time now is 06:16 AM.
Powered by vBulletin. Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

This forum began as part of the James Randi Education Foundation (JREF). However, the forum now exists as
an independent entity with no affiliation with or endorsement by the JREF, including the section in reference to "JREF" topics.

Disclaimer: Messages posted in the Forum are solely the opinion of their authors.