diff --git a/src/music.clj b/src/music.clj index e1832b8..13c97c4 100644 --- a/src/music.clj +++ b/src/music.clj @@ -70,13 +70,16 @@ :Abb 7 :Ab 8 :A 9 :A# 10 :A## 11 :Bbb 9 :Bb 10 :B 11 :B# 12 :B## 13)) -(defn abs-pitch [pitch-class octave] +(defn abs-pitch "Returns the absolute pitch of a pitch class at an octave" - (+ (* 12 octave) (pc-to-int pitch-class))) + ([pitch-class octave] (abs-pitch [pitch-class octave])) + ([[pitch-class octave]] + (+ (* 12 octave) (pc-to-int pitch-class)))) -(defn pitch [abs-pitch] +(defn pitch "Returns the pitch class and octave represented by the absolute pitch. In cases of enharmonic equivalence, returns the sharp rather than the flat." + [abs-pitch] (let [scale [:C :C# :D :D# :E :F :F# :G :G# :A :A# :B] octave (quot abs-pitch 12) index (rem abs-pitch 12)] @@ -85,8 +88,24 @@ (defn trans [n [pitch-class octave]] (pitch (+ (abs-pitch pitch-class octave) n))) -(defn line [[m & ms :as music]] +(defn line "Combines musics via the sequential (:+) operator" - (if (nil? (seq music)) + [[m & ms :as musics]] + (if (nil? (seq musics)) (rest 0) [:+ m (line ms)])) + +(defn chord + "Combines musics via the simultaneous (:=) operator" + [[m & ms :as musics]] + (if (nil? (seq musics)) + (rest 0) + [:= m (line ms)])) + +(defn max-pitch [[p & ps :as pitches]] + (if (nil? (seq pitches)) + (pitch 0) + (let [max-ps (max-pitch ps)] + (if (> (abs-pitch p) (abs-pitch max-ps)) + p + max-ps))))