Skip to content

Instantly share code, notes, and snippets.

@candera
Created June 23, 2013 19:35
Show Gist options
  • Save candera/5846245 to your computer and use it in GitHub Desktop.
Save candera/5846245 to your computer and use it in GitHub Desktop.
Sketch of symbolic composition of sound operations
(defn ->op
"Create an operation that just samples that sound
without additional processing."
[s]
(let [s* (gensym "sound")]
`{:bindings {~s* ~s}
:duration (.duration ~s*)
:channels (.channels ~s*)
:amplitude (.amplitude ~s* ~'t ~'c)}))
(->op '(read-sound "foo.wav"))
;=>
{:duration (.duration sound7679)
:bindings {sound7679 (read-sound "foo.wav")}
:amplitude (.amplitude sound7679 t c)
:channels (.channels sound7679)}
(defn gain-op [gain op]
(update-in op [:amplitude]
(fn [e] `(* ~gain ~e))))
(gain-op 0.5 (->op '(read-sound "foo.wav")))
;=>
{:duration (.duration sound7697),
:bindings {sound7697 (read-sound "foo.wav")},
:amplitude (clojure.core/* 0.5 (.amplitude sound7697 t c)),
:channels (.channels sound7697)}
(defn multiply-op [op1 op2]
{:bindings (merge (:bindings op1) (:bindings op2))
:duration `(max ~(:duration op1) ~(:duration op2))
:channels `(.channels s1)
:amplitude `(* ~(:amplitude op1) ~(:amplitude op2))})
(multiply-op (gain-op 0.5 (->op 's1)) (->op 's2))
;=>
{:bindings {sound7727 s1, sound7728 s2},
:duration
(clojure.core/max (.duration sound7727) (.duration sound7728)),
:channels (.channels user/s1),
:amplitude
(clojure.core/*
(clojure.core/* 0.5 (.amplitude sound7727 t c))
(.amplitude sound7728 t c))}
;; Now we just need something to take an operation and compile it into
;; a sound.
;; E.g.
(compile (multiply-op (->op (read-sound "hi.wav"))
(->op s2)))
;=>
(let [s1 (read-sound "hi.wav")]
(sound (max (.duration s1) (.duration s2))
(fn [t c] (* (.amplitude s1 c) (.amplitude s2 c)))
(.channels s1))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment