Last active
December 24, 2015 16:09
-
-
Save jackrusher/6825636 to your computer and use it in GitHub Desktop.
My first attempt at an aleatoric composition with Overtone. An example of the audio output is here: https://soundcloud.com/jackrusher/heart-murmur
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 overtone-playground.heart-murmur | |
(:use overtone.core | |
overtone.inst.sampled-piano | |
overtone.samples.piano)) | |
;; (boot-server) | |
;; (sampled-piano) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reproducible randomness | |
(def ^:dynamic ^java.util.Random *rando* (java.util.Random. seed)) | |
(defn seeded-rand | |
([] (.nextDouble *rando*)) | |
([x] (* x (.nextDouble *rando*))) | |
([x y] (+ x (* (- y x) (.nextDouble *rando*))))) | |
(defn seeded-rand-int [n] (int (seeded-rand n))) | |
(defn seeded-rand-nth [coll] (nth coll (seeded-rand-int (count coll)))) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
(def m (metronome 90)) | |
(defn play-chords [m b beats chord-fn] | |
(doseq [dur beats] | |
(doseq [c (map note (chord-fn))] | |
(at (m (+ b dur)) (sampled-piano c (+ (seeded-rand) 0.1)))))) | |
(defn improv-chords [tone-groups] | |
(into [] (map seeded-rand-nth tone-groups))) | |
(defn eights-and-rests | |
"Plays sequences of notes and chords in steady eights with some | |
serendipity in the dynamics, nils are treated as 8th note rests." | |
[m b & notes] | |
(let [idv (map vector (iterate inc 0) notes)] | |
(doseq [[idx noteSet] idv] | |
(if (vector? noteSet) | |
(doseq [n noteSet] | |
(when (keyword? n) | |
(at (m (+ b idx)) (sampled-piano (note n) (+ 1 (* 2.5 (seeded-rand))))))) | |
(when (keyword? noteSet) | |
(at (m (+ b idx)) (sampled-piano (note noteSet) (+ 1 (* 2.5 (seeded-rand)))))))))) | |
(defn improv-melody [m b tone-groups] | |
(apply eights-and-rests | |
(concat [m b] | |
(mapcat (fn [tones] (take 8 (repeatedly #(vector (seeded-rand-nth tones))))) | |
tone-groups)))) | |
(do | |
;; one composition per seed value | |
(def ^:dynamic ^java.util.Random *rando* (java.util.Random. 1888)) | |
(play-chords m (m) [0 4 8 12] | |
(partial improv-chords [[:C2 :D2 :E2 :G2] | |
[:B3 :D3 :E3 :G3] | |
[:B4 :D4 :E4 :F#4 :G4]])) | |
(improv-melody m (m) [[:B4 :D5 :G5 :B5 :C5 nil nil nil nil] | |
[:C5 :G5 :A5 :E5 :A5 nil nil nil nil]]) | |
(play-chords m (+ (m) 16) [0 2 4 8 10 12 14] | |
(partial improv-chords [[:B2 :D2 :E2 :G2] | |
[:B3 :D3 :E3 :G3] | |
[:B4 :D4 :E4 :F#4]])) | |
(improv-melody m (+ (m) 16) [[:B4 :D5 :G5 :F#5 :C5 nil nil nil] | |
[:C5 :E4 :A5 :E5 :B6 nil nil]]) | |
(play-chords m (+ (m) 32) [0 2 4 8 10 12 14] | |
(partial improv-chords [[:B2 :D#2] | |
[:B3 :D#3 :F#3 :A#3] | |
[:B4 :D#4 :F#4]])) | |
(improv-melody m (+ (m) 32) [[:B4 :D#5 :F#5 :A#5 :C#5 nil nil nil] | |
[:B5 :G#5 :A#5 :E5 :B6 nil nil]]) | |
(play-chords m (+ (m) 48) [0 2 4 8 10 12 14] | |
(partial improv-chords [[:C2 :D2 :E2 :G2] | |
[:B3 :D3 :E3] | |
[:B4 :E4 :G4]])) | |
(improv-melody m (+ (m) 48) [[:B4 :D5 :G5 :F5 :C5 nil nil nil] | |
[:C5 :E4 :A5 :E5 :B6 nil nil]]) | |
(play-chords m (+ (m) 64) [0 2 4 8 12] | |
(partial improv-chords [[:C2 :E2 :G2] | |
[:B3 :G3 :E3] | |
[:B4 :D4 :G4]])) | |
(improv-melody m (+ (m) 64) [[:B4 :D5 :G5 :F5 :C5 nil nil nil] | |
[:C5 :E4 :G5 :A5 :E5 nil nil]]) | |
(improv-melody m (+ (m) 80) [[:C5 :E4 :G5 :A5 :E5 nil nil]]) | |
(apply eights-and-rests (concat [m (+ (m) 88)] [[:C2 :G4 :E5]]))) | |
;;(stop) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment