2018-07-16 22:39:51 +00:00
|
|
|
(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)
|
2018-07-17 03:12:32 +00:00
|
|
|
|
2018-07-16 22:39:51 +00:00
|
|
|
;; (:=: noteA noteB) represents noteA played simultaneously with noteB
|
|
|
|
;; (:+: noteA noteB) represents noteA played followed by noteB
|
2018-07-17 03:12:32 +00:00
|
|
|
|
|
|
|
;; 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
|