Skip to content

Instantly share code, notes, and snippets.

@rogerallen
Last active December 18, 2015 15:19
Show Gist options
  • Save rogerallen/5803099 to your computer and use it in GitHub Desktop.
Save rogerallen/5803099 to your computer and use it in GitHub Desktop.
Overtone Translation of Vi Hart's Sound Braid. See http://www.youtube.com/watch?v=VB6a4nI0BPA
;; Overtone Translation of Vi Hart's Sound Braid by Roger Allen
;; http://www.youtube.com/watch?v=VB6a4nI0BPA
;;
;; Listen to what this sounds like here: http://goo.gl/HSzgM
;;
(ns vihart-braid
(:require [overtone.live :as o]
[overtone.synth.stringed :as strings]
[leipzig.canon :as lc]
[leipzig.live :as ll]
[leipzig.melody :as lm]
[leipzig.scale :as ls]))
;; instrument routines...
(defn pick [amp {pitch :pitch, start :time, length :duration, pan :pan}]
(let [synth-id (o/at start (strings/ektara pitch :amp amp :gate 1 :pan pan))]
(o/at (+ start length) (o/ctl synth-id :gate 0))))
(defmethod ll/play-note :melody [note] (pick 0.6 note))
;; utility for Vi's panning technique
(defn add-pan
"given a min and max pitch and notes, pan from -0.99 to 0.99 from depending on the pitch"
[min-pitch max-pitch ns]
(let [pans (map #(* 0.9 (- (* 2 (/ (- (:pitch %) min-pitch) (- max-pitch min-pitch))) 1)) ns)]
(->> ns (lm/having :pan pans))))
;; gather her strands of notes into a braid
(defn make-braid [N]
(let [strand (lm/phrase [ 1 1 2, 3 1, 2 2]
[nil 0 1, 2 3, 4 3])
strand-0 (add-pan -4 4 strand)
strand-1 (add-pan -4 4 (lc/mirror strand-0))
strand-a (lm/times N (->> strand-0 (lm/then strand-1)))
strand-b (lm/times N (->> strand-1 (lm/then strand-0)))]
(->> strand-a
(lm/with (lm/after 4 strand-b))
(lm/with (lm/after 8 strand-a)))))
(defn play-song [speed key song]
(->> song
(lm/where :part (lm/is :melody))
(lm/where :time speed)
(lm/where :duration speed)
(lm/where :pitch key)
ll/play))
;; Vi Hart's version
(play-song (lm/bpm 120) (comp ls/low ls/C ls/major) (make-braid 5))
(comment
;; but with Overtone & Leipzig you can change things about...
(play-song (lm/bpm 172) (comp ls/low ls/D ls/flat ls/mixolydian) (make-braid 3))
(play-song (lm/bpm 92) (comp ls/low ls/C ls/minor) (make-braid 3))
)
@ctford
Copy link

ctford commented Jun 25, 2013

Not sure if you realised, but you don't necessarily need to set a :part to play notes - play-note is an ordinary multimethod, so you can provide a :default arrangement.

@rogerallen
Copy link
Author

Oh, thanks for that Chris. I didn't realize the :default option existed for play-note. I'm still learning Clojure bit-by-bit very slowly... (and I also didn't get notice that you made this comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment