Created
October 24, 2017 21:11
-
-
Save mackenziestarr/64cf243fe124fe1392adaf165efc6b3b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns twelve-tone.core | |
(:use overtone.live)) | |
;; reference: http://www.carolingianrealm.info/Music.php?MusicID=29 | |
;; choose 12 notes | |
(def prime (shuffle (range 0 12))) | |
;; mathy function for generating the tone rows | |
(defn generate-tone-rows [prime] | |
(let [note-count (count prime) | |
inversion (map #(mod (- note-count %) note-count) prime) | |
matrix (for [x prime | |
y inversion | |
:let [z (mod (+ x y) 12)]] | |
z)] | |
(partition note-count matrix))) | |
(def tone-rows (generate-tone-rows prime))) | |
;; the above call produces something like this: | |
;;[[0 11 5 10 3 7 1 6 8 9 2 4] | |
;; [1 0 6 11 4 8 2 7 9 10 3 5] | |
;; [7 6 0 5 10 2 8 1 3 4 9 11] | |
;; [2 1 7 0 5 9 3 8 10 11 4 6] | |
;; [9 8 2 7 0 4 10 3 5 6 11 1] | |
;; [5 4 10 3 8 0 6 11 1 2 7 9] | |
;; [11 10 4 9 2 6 0 5 7 8 1 3] | |
;; [6 5 11 4 9 1 7 0 2 3 8 10] | |
;; [4 3 9 2 7 11 5 10 0 1 6 8] | |
;; [3 2 8 1 6 10 4 9 11 0 5 7] | |
;; [10 9 3 8 1 5 11 4 6 7 0 2] | |
;; [8 7 1 6 11 3 9 2 4 5 10 0]] | |
;; the composition starts from :a3 as the root | |
(def root (note :a3)) | |
;; these a note length values => milliseconds | |
;; from: https://msu.edu/course/asc/232/song_project/dectalk_pages/note_to_%20ms.html | |
(def rhythm [545 818 2180 1635 1090 273 136]) | |
(def melody | |
(partition 2 (interleave (apply concat (shuffle tone-rows)) | |
(cycle (shuffle rhythm))))) | |
;; the above expression produces [note milliseconds] tuples from fusing together all the | |
;; tone rows in a random sequence with accompanying rhythm values | |
;; looks like this: | |
;;((0 2180) | |
;; (11 818) | |
;; (5 545) | |
;; (10 1090) | |
;; ... | |
;; ) | |
(def harmony | |
(partition 2 (interleave (apply concat (shuffle tone-rows)) | |
(cycle (shuffle rhythm))))) | |
;; these are defining the instruments | |
(definst sine-blip [freq 400] | |
(let [snd (mix (sin-osc (* freq [0.99 1.01]))) | |
env (env-gen (perc 0.02 0.7) :action FREE)] | |
(free-verb (* 0.8 env snd) 0.7))) | |
(definst saw-blip [freq 400] | |
(let [snd (mix (saw (* freq [0.99 1.01]))) | |
env (env-gen (perc 0.02 0.7) :action FREE)] | |
(free-verb (* 0.3 env snd) 0.7))) | |
;; this is a thing that takes the format of `melody` and `harmony` and | |
;; schedules the notes to be played in the future using a pattern | |
;; called "temporal recursion" | |
(defn play | |
([line sound] | |
(play (now) line sound)) | |
([clock line sound] | |
(let [[note time] (first line)] | |
(at time | |
(sound (midi->hz (+ root note)))) | |
(apply-at (+ clock time) #'play [(+ clock time) (next line) sound])))) | |
;; finally the magic, lets play the tune! | |
(do | |
(play melody sine-blip) | |
(play harmony saw-blip)) | |
(recording-start "~/Desktop/12tone.wav") | |
(recording-stop) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment