(ns music) ;; an octave is an int, e.g. 4 ;; a pitch class is a keyword from :Abb to G## ;; a pitch is a [pitch class, octave] vector, e.g. [:C 4] is middle C ;; a duration is a rational number, e.g. 1/8 ;; a note has a duration, optionally a pitch, and optionally any other necessary keys (e.g. loudness) ;; {:duration 1/8 :pitch [:A# 3]} is a note. {:duration 1/4} is a note (really, a rest) ;; (:=: noteA noteB) represents noteA played simultaneously with noteB ;; (:+: noteA noteB) represents noteA played followed by noteB ;; what do the above functions return? Whatever that thing is, a note is a "subtype" of it ;; since the :=: and :+: operations can be applied to their return values ;; one solution would be to have [noteA noteB] represent noteA and noteB played sequentially ;; and [[noteA noteB]] represent noteA and noteB played simultaneously -- this would ;; mean that :=: and :+: would have to act on vectors ;; this would allow arbitrary musical phrases, e.g. [noteA [noteB noteC] noteD], but what ;; would deeper nesting mean? ;; (modify noteA control) merges the control map into the noteA map ;; control maps have keys like ::tempo, ::transpose, ::instrument, ::phrase, ::player, ::keysig