 
   ([root scale-name] (scale root scale-name (range 1 8)))
   ([root scale-name degrees]
-     (let [root (resolve-note root)
+     (let [root (note root)
            degrees (resolve-degrees degrees)]
        (cons root (map #(+ root (nth-interval scale-name %)) degrees)))))
 

           :B  11 :b  11})


(defn resolve-note
  "Resolves note to MIDI number format. Resolves upper and lower-case keywords
  and strings in MIDI note format. If given an integer or nil, returns them
  unmodified. All other inputs will raise an exception.

  Usage examples:

  (resolve-note \"C4\")  ;=> 60
  (resolve-note \"C#4\") ;=> 61
  (resolve-note \"eb2\") ;=> 39
  (resolve-note :F#7)    ;=> 102
  (resolve-note :db5)    ;=> 73
  (resolve-note 60)      ;=> 60
  (resolve-note nil)     ;=> nil"

  [note]
  (cond
   (nil? note) nil
   (integer? note) (if (>= note 0)
                    note
                    (throw (IllegalArgumentException.
                            (str "Unable to resolve note: " note ". Value is out of range. Lowest value is 0"))))
   (keyword? note) (resolve-note (name note))
   (string? note) (let [midi-note-re #"\A([a-gA-G][#b]?)([-0-9]+\Z)"
                        separated (re-find midi-note-re note)
                        _ (when (nil? separated)
                            (throw (IllegalArgumentException.
                                    (str "Unable to resolve note: " note ". Does not appear to be in MIDI format i.e. C#4"))))

                        [_ pitch-class octave] separated
                        octave (Integer. octave)
                        _ (when (< octave -1)
                            (throw (IllegalArgumentException.
                                    (str "Unable to resolve note: " note ". Octave is out of range. Lowest octave value is -1"))))
                        interval (NOTE (keyword pitch-class))

                        _ (when (nil? interval)
                            (throw (IllegalArgumentException.
                                    (str "Unable to resolve note: " note ". Not a valid pitch class such as C or Db"))))]
                    (+ interval 12 (* 12 octave)))
   :else (throw (IllegalArgumentException. (str "Unable to resolve note: " note ". Wasn't a recognised format (either an integer, keyword, string or nil)")))))

;; * Each note in a scale acts as either a generator or a collector of other notes,
;; depending on their relations in time within a sequence.

  (chord :Bb4 :dim)   ; b flat diminished -> #{70 73 76}
  "
  ([root chord-name]
     (let [root (note root)
           chord (resolve-chord chord-name)]
       (set (map #(+ % root) chord)))))

