initial checkin
This commit is contained in:
commit
1b001e49ee
|
@ -0,0 +1,11 @@
|
||||||
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
*.log
|
||||||
|
tmp/
|
||||||
|
|
||||||
|
.cpcache/
|
||||||
|
.nrepl-port
|
||||||
|
target/
|
||||||
|
result
|
||||||
|
.clj-kondo
|
||||||
|
native/
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
:paths ["src"]
|
||||||
|
:deps {
|
||||||
|
org.clojure/clojure {:mvn/version "1.11.0"}
|
||||||
|
overtone/overtone {:mvn/version "0.10.6"}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,337 @@
|
||||||
|
(ns tunes.core
|
||||||
|
(:require [overtone.core :as o :refer [connect-external-server]]))
|
||||||
|
|
||||||
|
(defn -main [& args]
|
||||||
|
(println (str "called with: " args)))
|
||||||
|
|
||||||
|
(defn initialize
|
||||||
|
([] (initialize "127.0.0.1" 30300))
|
||||||
|
([port] (initialize "127.0.0.1" port))
|
||||||
|
([ip port] (do (connect-external-server ip port)
|
||||||
|
(require '[tunes.live :as live]))))
|
||||||
|
|
||||||
|
(o/definst tone [freq 440] (o/sin-osc freq))
|
||||||
|
|
||||||
|
(o/definst beep [freq 440 duration 1]
|
||||||
|
(let [env (o/line 1 0 duration :action o/FREE)]
|
||||||
|
(* env (o/sin-osc freq))))
|
||||||
|
|
||||||
|
#_(o/demo (beep 256))
|
||||||
|
#_(o/stop)
|
||||||
|
|
||||||
|
(o/definst bell [freq 440 duration 5
|
||||||
|
h0 1 h1 0.6 h2 0.4 h3 0.25 h4 0.2 h5 0.15]
|
||||||
|
(let [harmonic-series [ 1 2 3 4.15 5.3 6.6 ]
|
||||||
|
proportions [ h0 h1 h2 h3 h4 h5 ]
|
||||||
|
component (fn [harmonic proportion]
|
||||||
|
(* 1/2
|
||||||
|
proportion
|
||||||
|
(o/env-gen (o/perc 0.01 (* proportion duration)))
|
||||||
|
(o/sin-osc (* harmonic freq))))]
|
||||||
|
(o/mix (map component harmonic-series proportions))))
|
||||||
|
|
||||||
|
#_(bell 256)
|
||||||
|
#_(beep 256)
|
||||||
|
|
||||||
|
|
||||||
|
#_(let [env (o/envelope [0 0.5 1 0.25 0] [1 1 1 1] :lin)]
|
||||||
|
(o/demo (o/sin-osc :freq (+ 220 (* 220 (o/env-gen env :action o/FREE))))))
|
||||||
|
|
||||||
|
#_(o/demo (* 0.25 (o/linen (o/impulse 0) 0.1 1 1.9 :action o/FREE) (o/sin-osc)))
|
||||||
|
|
||||||
|
#_(o/demo (let [dur 1
|
||||||
|
env (abs (o/sin-osc:kr (/ 1 dur)))]
|
||||||
|
(o/line:kr 0 1 dur :action o/FREE)
|
||||||
|
(* env (o/saw 220))))
|
||||||
|
|
||||||
|
(defn factors [n]
|
||||||
|
(let [sqrt (Math/sqrt n)]
|
||||||
|
(loop [d 2
|
||||||
|
factors []]
|
||||||
|
(cond (> d sqrt) (conj factors d)
|
||||||
|
(= 0 (mod n d)) (recur (inc d) (conj factors d))
|
||||||
|
:else (recur (inc d) factors)))))
|
||||||
|
|
||||||
|
#_(o/demo (* (o/pan2 (o/sin-osc 240)
|
||||||
|
(o/sin-osc 220))
|
||||||
|
(o/line 1 0 1 :action o/FREE)))
|
||||||
|
|
||||||
|
#_(o/demo 10
|
||||||
|
(o/pan2 (* (o/lf-noise1)
|
||||||
|
(+ 1 (o/env-gen (o/env-sine 1 1))))))
|
||||||
|
|
||||||
|
#_(o/demo (tone))
|
||||||
|
#_(o/demo (beep 220))
|
||||||
|
#_(o/stop)
|
||||||
|
|
||||||
|
#_(o/demo (bell 220))
|
||||||
|
#_(o/demo (* (o/lpf1)))
|
||||||
|
|
||||||
|
#_(o/demo (bell 256 10.0))
|
||||||
|
#_(o/demo (bell 256 1.0 8 4 2 1))
|
||||||
|
#_(o/demo (bell 256 10.0))
|
||||||
|
#_(o/demo (bell 256 10.0))
|
||||||
|
#_(o/demo (bell 500 10.0 0.0))
|
||||||
|
#_(o/demo (bell 400 10.0 0.0 0.0))
|
||||||
|
|
||||||
|
#_(o/demo (bell 400 10.0 0.0 0.0))
|
||||||
|
|
||||||
|
(defn midi->hz [midi]
|
||||||
|
(* 8.1757989156
|
||||||
|
(java.lang.Math/pow 2 (/ midi 12))))
|
||||||
|
|
||||||
|
#_(bell (midi->hz 60))
|
||||||
|
|
||||||
|
(defn ding [midi] (bell (midi->hz midi) 3))
|
||||||
|
|
||||||
|
#_(o/demo (ding 55))
|
||||||
|
|
||||||
|
(defn note [timing pitch] { :time timing :pitch pitch })
|
||||||
|
(defn where [k f notes] (->> notes (map #(update-in % [k] f))))
|
||||||
|
(defn from [offset] (partial + offset))
|
||||||
|
|
||||||
|
#_(require '[tunes.sounds :as sounds])
|
||||||
|
|
||||||
|
(defn play-note [midi]
|
||||||
|
(let [sound (ding midi)]
|
||||||
|
(o/detect-silence sound :action o/FREE)))
|
||||||
|
|
||||||
|
(defn play [notes]
|
||||||
|
(let [scheduled-notes (->> notes (where :time (from (o/now))))]
|
||||||
|
(doseq [{ms :time midi :pitch} scheduled-notes]
|
||||||
|
;; original:
|
||||||
|
#_(o/at ms (sounds/string midi))
|
||||||
|
(o/at ms (play-note midi))
|
||||||
|
;;(o/at ms (sounds/tb303 :note midi :release 0.5))
|
||||||
|
)
|
||||||
|
scheduled-notes))
|
||||||
|
|
||||||
|
(defn even-melody [pitches]
|
||||||
|
(let [times (reductions + (repeat 1000/3))
|
||||||
|
notes (map note times pitches)]
|
||||||
|
(play notes)))
|
||||||
|
|
||||||
|
#_(even-melody (range 70 81))
|
||||||
|
|
||||||
|
(defn sum-n [series n] (reduce + (take n series)))
|
||||||
|
|
||||||
|
(defmacro defscale [names values]
|
||||||
|
`(do
|
||||||
|
~@(map
|
||||||
|
(fn [name value] `(def ~name ~value))
|
||||||
|
names
|
||||||
|
(eval values))))
|
||||||
|
|
||||||
|
(defn scale [intervals]
|
||||||
|
(fn [degree]
|
||||||
|
(if-not (neg? degree)
|
||||||
|
(sum-n (cycle intervals) degree)
|
||||||
|
((comp - (scale (reverse intervals)) -) degree))))
|
||||||
|
|
||||||
|
(def C (from 60))
|
||||||
|
|
||||||
|
(defscale [sharp flat] [inc dec])
|
||||||
|
|
||||||
|
(def major (scale [2 2 1 2 2 2 1]))
|
||||||
|
(def minor (scale [2 1 2 2 1 2 2]))
|
||||||
|
(def blues (scale [3 2 1 1 3 2]))
|
||||||
|
(def pentatonic (scale [3 2 2 3 2]))
|
||||||
|
(def chromatic (scale [1]))
|
||||||
|
|
||||||
|
(defscale [D E F G A B]
|
||||||
|
(map
|
||||||
|
(comp from C major)
|
||||||
|
(rest (range))))
|
||||||
|
|
||||||
|
#_(even-melody
|
||||||
|
(map (comp C sharp minor)
|
||||||
|
(concat (range 0 8) (reverse (range 0 7)))))
|
||||||
|
|
||||||
|
(def row-row-your-boat
|
||||||
|
(let [pitches [0 0 0 1 2
|
||||||
|
2 1 2 3 4
|
||||||
|
7 7 7 4 4 4 2 2 2 0 0 0
|
||||||
|
4 3 2 1 0]
|
||||||
|
durations [1 1 2/3 1/3 1
|
||||||
|
2/3 1/3 2/3 1/3 2
|
||||||
|
1/3 1/3 1/3 1/3 1/3 1/3 1/3 1/3 1/3 1/3 1/3 1/3
|
||||||
|
2/3 1/3 2/3 1/3 2]
|
||||||
|
times (reductions + 0 durations)]
|
||||||
|
(map note times pitches)))
|
||||||
|
|
||||||
|
(def ghost-of-john
|
||||||
|
(let [pitches [0 -1 0 -3 -2 -1 0
|
||||||
|
2 1 2 4 3 2 1 0 1 2 3
|
||||||
|
4 3 4 7 6 4 3 4
|
||||||
|
4 4 3 3 2 2 1 1 0 -1 0]
|
||||||
|
durations [1/4 1/4 1/4 1/4 1/4 1/4 1/2
|
||||||
|
1/4 1/4 1/4 1/8 1/8 1/4 1/4 1/8 1/8 1/8 1/8
|
||||||
|
1/4 1/4 1/4 1/8 1/8 1/4 1/4 1/2
|
||||||
|
1/8 1/8 1/8 1/8 1/8 1/8 1/8 1/8 1/4 1/4 1/2]
|
||||||
|
times (reductions + 0 durations)]
|
||||||
|
(map note times pitches)))
|
||||||
|
|
||||||
|
(def ghost-of-john-2
|
||||||
|
(let [pitches [0 -1 0 -3 -2 -3 -3
|
||||||
|
2 1 2 4 3 2 1 0
|
||||||
|
4 3 4 7 6 4 3 4
|
||||||
|
4 4 3 3 2 2 1 1 0 -1 0]
|
||||||
|
durations [1/4 1/4 1/4 1/4 1/4 1/4 1/2
|
||||||
|
1/4 1/4 1/4 1/8 1/8 1/4 1/4 1/2
|
||||||
|
1/4 1/4 1/4 1/8 1/8 1/4 1/4 1/2
|
||||||
|
1/8 1/8 1/8 1/8 1/8 1/8 1/8 1/8 1/4 1/4 1/2]
|
||||||
|
times (reductions + 0 durations)]
|
||||||
|
(map note times pitches)))
|
||||||
|
|
||||||
|
#_(->> ghost-of-john-2
|
||||||
|
(where :time (bpm 26))
|
||||||
|
(where :pitch (comp F minor))
|
||||||
|
(play))
|
||||||
|
|
||||||
|
#_(o/stop)
|
||||||
|
|
||||||
|
(defn bpm [beats] (fn [beat] (/ (* beat 60 1000) beats)))
|
||||||
|
|
||||||
|
#_(->> row-row-your-boat
|
||||||
|
(where :time (bpm 120))
|
||||||
|
(where :pitch (comp C major))
|
||||||
|
play)
|
||||||
|
|
||||||
|
(defn run [[from & tos]]
|
||||||
|
(if-let [to (first tos)]
|
||||||
|
(let [up-or-down (if (<= from to)
|
||||||
|
(range from to)
|
||||||
|
(reverse (range (inc to) (inc from))))]
|
||||||
|
(concat up-or-down (run tos)))
|
||||||
|
[from]))
|
||||||
|
|
||||||
|
#_(even-melody (map (comp C flat minor)
|
||||||
|
(run [0 4 -1 1 0])))
|
||||||
|
|
||||||
|
(defn accumulate [series]
|
||||||
|
(map (partial sum-n series) (range (count series))))
|
||||||
|
|
||||||
|
(def repeats (partial mapcat #(apply repeat %)))
|
||||||
|
(def runs (partial mapcat run))
|
||||||
|
|
||||||
|
(def melody
|
||||||
|
(let [call
|
||||||
|
[(repeats [[2 1/4] [1 1/2] [14 1/4] [1 3/2]])
|
||||||
|
(runs [[0 -1 3 0] [4] [1 8]])]
|
||||||
|
|
||||||
|
response
|
||||||
|
[(repeats [[10 1/4] [1 1/2] [2 1/4] [1 9/4]])
|
||||||
|
(runs [[7 -1 0] [0 -3]])]
|
||||||
|
|
||||||
|
development
|
||||||
|
[(repeats [[1 3/4] [12 1/4] [1 1/2] [1 1] [1 1/2] [12 1/4] [1 3]])
|
||||||
|
(runs [[4] [4] [2 -3] [-1 -2] [0] [3 5] [1] [1] [1 2] [-1 1 -1] [5 0]])]
|
||||||
|
|
||||||
|
[durations pitches] (map concat call response development)
|
||||||
|
|
||||||
|
times (map (from 1/2) (accumulate durations))]
|
||||||
|
(map note times pitches)))
|
||||||
|
|
||||||
|
(def bass
|
||||||
|
(let [triples (partial mapcat #(repeat 3 %))]
|
||||||
|
(->> (map note
|
||||||
|
(accumulate (repeats [[21 1] [13 1/4]]))
|
||||||
|
(concat (runs [[5 0] [6 0]])))
|
||||||
|
(where :part (constantly :bass)))))
|
||||||
|
|
||||||
|
#_(defn canon [f notes] (concat notes (f notes)))
|
||||||
|
|
||||||
|
(defn canon [f notes]
|
||||||
|
(->> notes
|
||||||
|
f
|
||||||
|
(where :part (constantly :follower))
|
||||||
|
(concat notes)))
|
||||||
|
|
||||||
|
(defn simple [wait]
|
||||||
|
(fn [notes] (->> notes (where :time (from wait)))))
|
||||||
|
|
||||||
|
(defn interval [interval]
|
||||||
|
(fn [notes] (->> notes (where :pitch (from interval)))))
|
||||||
|
|
||||||
|
(def mirror (fn [notes] (->> notes (where :pitch -))))
|
||||||
|
(def crab (fn [notes] (->> notes (where :time -))))
|
||||||
|
(def table (comp mirror crab))
|
||||||
|
|
||||||
|
#_(->> row-row-your-boat
|
||||||
|
#_(canon (simple 4))
|
||||||
|
(where :pitch (comp C blues))
|
||||||
|
(where :time (bpm 120))
|
||||||
|
play)
|
||||||
|
|
||||||
|
#_(->> ghost-of-john
|
||||||
|
(canon (simple 2))
|
||||||
|
#_(canon (simple 4))
|
||||||
|
(where :pitch (comp F minor))
|
||||||
|
(where :time (bpm 30))
|
||||||
|
(play))
|
||||||
|
|
||||||
|
#_(let [tempo 25
|
||||||
|
key (comp F minor)]
|
||||||
|
(play (concat
|
||||||
|
(->> ghost-of-john
|
||||||
|
(canon (simple 2))
|
||||||
|
(canon (simple 8))
|
||||||
|
(canon (comp (simple 2) mirror))
|
||||||
|
(where :pitch key)
|
||||||
|
(where :time (bpm tempo)))
|
||||||
|
(->> ghost-of-john-2
|
||||||
|
(canon (simple 4))
|
||||||
|
(canon (interval -7))
|
||||||
|
(canon (comp (simple 4) canone-alla-quarta))
|
||||||
|
(where :pitch key)
|
||||||
|
(where :time (bpm tempo))))
|
||||||
|
#_(->> ghost-of-john
|
||||||
|
(where :pitch key)
|
||||||
|
(where :time (comp (from 8) (bpm (* 2 tempo))))
|
||||||
|
(play))))
|
||||||
|
|
||||||
|
#_(o/stop)
|
||||||
|
|
||||||
|
#_(->> ghost-of-john-2
|
||||||
|
(canon (simple 2))
|
||||||
|
(canon canone-alla-quarta)
|
||||||
|
(canon (interval -7))
|
||||||
|
(where :pitch (comp F minor))
|
||||||
|
(canon (simple 8))
|
||||||
|
(where :time (bpm 25))
|
||||||
|
(play))
|
||||||
|
|
||||||
|
#_(->> ghost-of-john
|
||||||
|
(canon (comp mirror (interval -2)))
|
||||||
|
(where :pitch (comp C minor))
|
||||||
|
(where :time (bpm 30))
|
||||||
|
(play))
|
||||||
|
|
||||||
|
#_(o/stop)
|
||||||
|
|
||||||
|
(defn canone-alla-quarta [notes]
|
||||||
|
(canon (comp (interval -3) mirror (simple 3))
|
||||||
|
notes))
|
||||||
|
|
||||||
|
#_(->> melody
|
||||||
|
(where :pitch (comp C major))
|
||||||
|
(where :time (bpm 120))
|
||||||
|
play)
|
||||||
|
|
||||||
|
#_(->> melody
|
||||||
|
canone-alla-quarta
|
||||||
|
(concat bass)
|
||||||
|
(where :pitch (comp C sharp minor))
|
||||||
|
(where :time (bpm 60))
|
||||||
|
play)
|
||||||
|
|
||||||
|
#_(o/stop)
|
||||||
|
|
||||||
|
#_(o/definst small-hat [ffreq 200 rq 0.5
|
||||||
|
attack 0 release 0.025 amp 0.3
|
||||||
|
pan 0]
|
||||||
|
(let [snd (o/white-noise)
|
||||||
|
snd (o/hpf snd ffreq)
|
||||||
|
snd (o/rhpf snd (* ffreq 2) rq)
|
||||||
|
snd (* snd (o/env-gen (o/perc attack release 1 -10) :action o/FREE))]
|
||||||
|
(* 2 snd amp)))
|
|
@ -0,0 +1,4 @@
|
||||||
|
(ns tunes.live
|
||||||
|
(:use overtone.core)
|
||||||
|
(:require [overtone.inst.drum :as drum]
|
||||||
|
[tunes.track :as track]))
|
|
@ -0,0 +1,504 @@
|
||||||
|
(ns tunes.sounds
|
||||||
|
(:use overtone.core)
|
||||||
|
(:require [overtone.core :as o]))
|
||||||
|
|
||||||
|
(defn add-overtone [tones n]
|
||||||
|
(conj tones (* (first tones) n)))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
|
||||||
|
(require '[overtone.inst.drum :as drum])
|
||||||
|
|
||||||
|
(demo (pan2 (mix (map (fn [freq amp]
|
||||||
|
(* amp (square freq)))
|
||||||
|
(map (fn [i] (* 110 (Math/pow 2 i))) (range 5))
|
||||||
|
(reverse (range 0 1 0.2))))))
|
||||||
|
|
||||||
|
(demo (drum/kick :env-ratio 8.0 :amp-decay 0.5))
|
||||||
|
|
||||||
|
(demo (pan2 (sin-osc (* (env-gen (envelope [3 1] [0.02] :exp)) 120))))
|
||||||
|
|
||||||
|
(demo (pan2
|
||||||
|
(* (sin-osc (* (env-gen (envelope [3 1] [0.02] :exp)) 50)
|
||||||
|
(* 0.5 Math/PI))
|
||||||
|
(env-gen (perc 0.005 0.5) :action FREE))))
|
||||||
|
|
||||||
|
(demo (pan2 (mix [(* 0.5 (saw 220)) (sin-osc 220)])))
|
||||||
|
|
||||||
|
(demo 20 (pan2 (mix [(pink-noise) (brown-noise)])))
|
||||||
|
|
||||||
|
(demo (drum/dub-kick))
|
||||||
|
|
||||||
|
(stop)
|
||||||
|
|
||||||
|
(demo (pan2 (* (-> (brown-noise)
|
||||||
|
(lpf 440))
|
||||||
|
(env-gen (env-perc)))))
|
||||||
|
|
||||||
|
(demo (klank))
|
||||||
|
|
||||||
|
(demo (pan2 (bpf (white-noise) 180 20)))
|
||||||
|
(demo (pan2 (white-noise)))
|
||||||
|
|
||||||
|
(demo (pan2 (+ (gray-noise) (white-noise))))
|
||||||
|
(demo (pan2 (lpf (mix [(pink-noise) (brown-noise)]) 180)))
|
||||||
|
(demo 3
|
||||||
|
(pan2 (-> (brown-noise)
|
||||||
|
(lpf 120)
|
||||||
|
(rhpf 80))))
|
||||||
|
|
||||||
|
(demo (pan2 (t-ball (brown-noise))))
|
||||||
|
(demo (pan2 (lpf (white-noise) :freq 220)))
|
||||||
|
)
|
||||||
|
|
||||||
|
#_(o/stop)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; translated from: https://github.com/supercollider-quarks/SynthDefPool/blob/master/pool/apad_mh.scd
|
||||||
|
(definst simple-flute [freq 880
|
||||||
|
amp 0.5
|
||||||
|
attack 0.4
|
||||||
|
decay 0.5
|
||||||
|
sustain 0.8
|
||||||
|
release 1
|
||||||
|
gate 1
|
||||||
|
out 0]
|
||||||
|
(let [env (env-gen (adsr attack decay sustain release) gate :action FREE)
|
||||||
|
mod1 (lin-lin:kr (sin-osc:kr 6) -1 1 (* freq 0.99) (* freq 1.01))
|
||||||
|
mod2 (lin-lin:kr (lf-noise2:kr 1) -1 1 0.2 1)
|
||||||
|
mod3 (lin-lin:kr (sin-osc:kr (ranged-rand 4 6)) -1 1 0.5 1)
|
||||||
|
sig (distort (* env (sin-osc [freq mod1])))
|
||||||
|
sig (* amp sig mod2 mod3)]
|
||||||
|
sig))
|
||||||
|
|
||||||
|
(demo (simple-flute 660))
|
||||||
|
|
||||||
|
(stop)
|
||||||
|
|
||||||
|
;;modified version of: https://github.com/supercollider-quarks/SynthDefPool/blob/master/pool/cs80lead_mh.scd
|
||||||
|
(definst cs80lead
|
||||||
|
[freq 880
|
||||||
|
amp 0.5
|
||||||
|
att 0.75
|
||||||
|
decay 0.5
|
||||||
|
sus 0.8
|
||||||
|
rel 1.0
|
||||||
|
fatt 0.75
|
||||||
|
fdecay 0.5
|
||||||
|
fsus 0.8
|
||||||
|
frel 1.0
|
||||||
|
cutoff 200
|
||||||
|
dtune 0.002
|
||||||
|
vibrate 4
|
||||||
|
vibdepth 0.015
|
||||||
|
gate 1
|
||||||
|
ratio 1
|
||||||
|
cbus 1
|
||||||
|
freq-lag 0.1]
|
||||||
|
(let [freq (lag freq freq-lag)
|
||||||
|
cuttoff (in:kr cbus)
|
||||||
|
env (env-gen (adsr att decay sus rel) gate :action FREE)
|
||||||
|
fenv (env-gen (adsr fatt fdecay fsus frel 2) gate)
|
||||||
|
|
||||||
|
vib (+ 1 (lin-lin:kr (sin-osc:kr vibrate) -1 1 (- vibdepth) vibdepth))
|
||||||
|
|
||||||
|
freq (* freq vib)
|
||||||
|
sig (mix (* env amp (saw [freq (* freq (+ dtune 1))])))]
|
||||||
|
sig))
|
||||||
|
|
||||||
|
(definst supersaw [freq 440 amp 1]
|
||||||
|
(let [input (lf-saw freq)
|
||||||
|
shift1 (lf-saw 4)
|
||||||
|
shift2 (lf-saw 7)
|
||||||
|
shift3 (lf-saw 5)
|
||||||
|
shift4 (lf-saw 2)
|
||||||
|
comp1 (> input shift1)
|
||||||
|
comp2 (> input shift2)
|
||||||
|
comp3 (> input shift3)
|
||||||
|
comp4 (> input shift4)
|
||||||
|
output (+ (- input comp1) (- input comp2) (- input comp3) (- input comp4))
|
||||||
|
output (- output input)
|
||||||
|
output (leak-dc:ar (* output 0.25))]
|
||||||
|
(* amp output)))
|
||||||
|
|
||||||
|
(definst ticker
|
||||||
|
[freq 880]
|
||||||
|
(* (env-gen (perc 0.001 0.01) :action FREE)
|
||||||
|
(sin-osc freq)))
|
||||||
|
|
||||||
|
(definst ping
|
||||||
|
[note {:default 72 :min 0 :max 120 :step 1}
|
||||||
|
attack {:default 0.02 :min 0.001 :max 1 :step 0.001}
|
||||||
|
decay {:default 0.3 :min 0.001 :max 1 :step 0.001}]
|
||||||
|
(let [snd (sin-osc (midicps note))
|
||||||
|
env (env-gen (perc attack decay) :action FREE)]
|
||||||
|
(* 0.8 env snd)))
|
||||||
|
|
||||||
|
(definst tb303
|
||||||
|
[note {:default 60 :min 0 :max 120 :step 1}
|
||||||
|
wave {:default 1 :min 0 :max 2 :step 1}
|
||||||
|
r {:default 0.8 :min 0.01 :max 0.99 :step 0.01}
|
||||||
|
attack {:default 0.01 :min 0.001 :max 4 :step 0.001}
|
||||||
|
decay {:default 0.1 :min 0.001 :max 4 :step 0.001}
|
||||||
|
sustain {:default 0.6 :min 0.001 :max 0.99 :step 0.001}
|
||||||
|
release {:default 0.01 :min 0.001 :max 4 :step 0.001}
|
||||||
|
cutoff {:default 100 :min 1 :max 20000 :step 1}
|
||||||
|
env-amount {:default 0.01 :min 0.001 :max 4 :step 0.001}
|
||||||
|
amp {:default 0.5 :min 0 :max 1 :step 0.01}]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
freqs [freq (* 1.01 freq)]
|
||||||
|
vol-env (env-gen (adsr attack decay sustain release)
|
||||||
|
(line:kr 1 0 (+ attack decay release))
|
||||||
|
:action FREE)
|
||||||
|
fil-env (env-gen (perc))
|
||||||
|
fil-cutoff (+ cutoff (* env-amount fil-env))
|
||||||
|
waves (* vol-env
|
||||||
|
[(saw freqs)
|
||||||
|
(pulse freqs 0.5)
|
||||||
|
(lf-tri freqs)])
|
||||||
|
selector (select wave waves)
|
||||||
|
filt (rlpf selector fil-cutoff r)]
|
||||||
|
(* amp filt)))
|
||||||
|
|
||||||
|
(definst mooger
|
||||||
|
"Choose 0, 1, or 2 for saw, sin, or pulse"
|
||||||
|
[note {:default 60 :min 0 :max 127 :step 1}
|
||||||
|
amp {:default 0.3 :min 0 :max 1 :step 0.01}
|
||||||
|
osc1 {:default 0 :min 0 :max 2 :step 1}
|
||||||
|
osc2 {:default 1 :min 0 :max 2 :step 1}
|
||||||
|
osc1-level {:default 0.5 :min 0 :max 1 :step 0.01}
|
||||||
|
osc2-level {:default 0 :min 0 :max 1 :step 0.01}
|
||||||
|
cutoff {:default 500 :min 0 :max 20000 :step 1}
|
||||||
|
attack {:default 0.0001 :min 0.0001 :max 5 :step 0.001}
|
||||||
|
decay {:default 0.3 :min 0.0001 :max 5 :step 0.001}
|
||||||
|
sustain {:default 0.99 :min 0.0001 :max 1 :step 0.001}
|
||||||
|
release {:default 0.0001 :min 0.0001 :max 6 :step 0.001}
|
||||||
|
fattack {:default 0.0001 :min 0.0001 :max 6 :step 0.001}
|
||||||
|
fdecay {:default 0.3 :min 0.0001 :max 6 :step 0.001}
|
||||||
|
fsustain {:default 0.999 :min 0.0001 :max 1 :step 0.001}
|
||||||
|
frelease {:default 0.0001 :min 0.0001 :max 6 :step 0.001}
|
||||||
|
gate 1]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
osc-bank-1 [(saw freq) (sin-osc freq) (pulse freq)]
|
||||||
|
osc-bank-2 [(saw freq) (sin-osc freq) (pulse freq)]
|
||||||
|
amp-env (env-gen (adsr attack decay sustain release) gate :action FREE)
|
||||||
|
f-env (env-gen (adsr fattack fdecay fsustain frelease) gate)
|
||||||
|
s1 (* osc1-level (select osc1 osc-bank-1))
|
||||||
|
s2 (* osc2-level (select osc2 osc-bank-2))
|
||||||
|
filt (moog-ff (+ s1 s2) (* cutoff f-env) 3)]
|
||||||
|
(* amp filt)))
|
||||||
|
|
||||||
|
(definst rise-fall-pad
|
||||||
|
[freq 440 t 4 amt 0.3 amp 0.8]
|
||||||
|
(let [abs-fn (partial map abs)
|
||||||
|
f-env (env-gen (perc t t) 1 1 0 1 FREE)
|
||||||
|
src (saw [freq (* freq 1.01)])
|
||||||
|
signal (rlpf (* 0.3 src)
|
||||||
|
(+ (* 0.6 freq) (* f-env 2 freq)) 0.2)
|
||||||
|
k (/ (* 2 amt) (- 1 amt))
|
||||||
|
distort (/ (* (+ 1 k) signal) (+ 1 (* k (abs-fn signal))))
|
||||||
|
gate (pulse (* 2 (+ 1 (sin-osc:kr 0.05))))
|
||||||
|
compressor (compander distort gate 0.01 1 0.5 0.01 0.01)
|
||||||
|
dampener (+ 1 (* 0.5 (sin-osc:kr 0.5)))
|
||||||
|
reverb (free-verb compressor 0.5 0.5 dampener)
|
||||||
|
echo (comb-n reverb 0.4 0.3 0.5)]
|
||||||
|
(* amp echo)))
|
||||||
|
|
||||||
|
(definst pad
|
||||||
|
[note 60 t 10 amt 0.3 amp 0.1 a 0.4 d 0.5 s 0.8 r 2]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
lfo (+ 2 (* 0.01 (sin-osc:kr 5 (rand 1.5))))
|
||||||
|
src (apply + (saw [freq (* freq lfo)]))
|
||||||
|
env (env-gen (adsr a d s r) (sin-osc:kr 0.2))
|
||||||
|
f-env (x-line:kr 0.001 4 t)
|
||||||
|
src (* env src)
|
||||||
|
signal (rlpf src (+ (* 0.3 freq) (* f-env 2 freq)) 0.5)
|
||||||
|
k (/ (* 4 amt) (- 1 amt))
|
||||||
|
dist (clip2 (/ (* (+ 1 k) signal) (+ 1 (* k (abs signal))))
|
||||||
|
0.03)
|
||||||
|
snd (* amp dist (line:kr 1 0 t))]
|
||||||
|
src))
|
||||||
|
|
||||||
|
(definst overpad
|
||||||
|
[note 60 amp 0.7 attack 0.001 release 2]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
env (env-gen (perc attack release) :action FREE)
|
||||||
|
f-env (+ freq (* 3 freq (env-gen (perc 0.012 (- release 0.1)))))
|
||||||
|
bfreq (/ freq 2)
|
||||||
|
sig (apply +
|
||||||
|
(concat (* 0.7 (sin-osc [bfreq (* 0.99 bfreq)]))
|
||||||
|
(lpf (saw [freq (* freq 1.01)]) f-env)))
|
||||||
|
audio (* amp env sig)]
|
||||||
|
audio))
|
||||||
|
|
||||||
|
;; BROKEN!
|
||||||
|
#_(definst buzz
|
||||||
|
[pitch 40 cutoff 300 dur 200]
|
||||||
|
(let [lpf-lev (* (+ 1 (lf-noise1:kr 10)) 400)
|
||||||
|
a (lpf (saw (midicps pitch)) lpf-lev)
|
||||||
|
b (sin-osc (midicps (- pitch 12)))
|
||||||
|
env (env-gen 1 1 0 1 2 (perc 0.01 (/ dur 1000)))]
|
||||||
|
(* env (+ a b))))
|
||||||
|
|
||||||
|
(definst bass
|
||||||
|
[freq 120 t 0.6 amp 0.5]
|
||||||
|
(let [env (env-gen (perc 0.08 t) :action FREE)
|
||||||
|
src (saw [freq (* 0.98 freq) (* 2.015 freq)])
|
||||||
|
src (clip2 (* 1.3 src) 0.8)
|
||||||
|
sub (sin-osc (/ freq 2))
|
||||||
|
filt (resonz (rlpf src (* 4.4 freq) 0.09) (* 2.0 freq) 2.9)]
|
||||||
|
(* env amp (fold:ar (distort (* 1.3 (+ filt sub))) 0.08))))
|
||||||
|
|
||||||
|
(definst daf-bass [freq 440 gate 1 amp 1 out-bus 0]
|
||||||
|
(let [harm [1 1.01 2 2.02 3.5 4.01 5.501]
|
||||||
|
harm (concat harm (map #(* 2 %) harm))
|
||||||
|
snd (* 2 (distort (sum (sin-osc (* freq harm)))))
|
||||||
|
snd (+ snd (repeat 2 (sum (sin-osc (/ freq [1 2])))))
|
||||||
|
env (env-gen (adsr 0.001 0.2 0.9 0.25) gate amp :action FREE)]
|
||||||
|
(* snd env)))
|
||||||
|
|
||||||
|
(definst grunge-bass
|
||||||
|
[note 48 amp 0.5 dur 0.1 a 0.01 d 0.01 s 0.4 r 0.01]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
env (env-gen (adsr a d s r) (line:kr 1 0 (+ a d dur r 0.1))
|
||||||
|
:action FREE)
|
||||||
|
src (saw [freq (* 0.98 freq) (* 2.015 freq)])
|
||||||
|
src (clip2 (* 1.3 src) 0.9)
|
||||||
|
sub (sin-osc (/ freq 2))
|
||||||
|
filt (resonz (rlpf src (* 8.4 freq) 0.29) (* 2.0 freq) 2.9)
|
||||||
|
meat (ring4 filt sub)
|
||||||
|
sliced (rlpf meat (* 2 freq) 0.1)
|
||||||
|
bounced (free-verb sliced 0.8 0.9 0.2)]
|
||||||
|
(* env bounced)))
|
||||||
|
|
||||||
|
(definst vintage-bass
|
||||||
|
[note 40 velocity 80 t 0.6 amp 1 gate 1]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
sub-freq (midicps (- note 12))
|
||||||
|
velocity (/ velocity 127.0)
|
||||||
|
sawz1 (* 0.275 (saw [freq (* 1.01 freq)]))
|
||||||
|
sawz2 (* 0.75 (saw [(- freq 2) (+ 1 freq)]))
|
||||||
|
sqz (* 0.3 (pulse [sub-freq (- sub-freq 1)]))
|
||||||
|
mixed (* 5 (+ sawz1 sawz2 sqz))
|
||||||
|
env (env-gen (adsr 0.1 3.3 0.4 0.8) gate :action FREE)
|
||||||
|
filt (* env (moog-ff mixed (* velocity env (+ freq 200)) 2.2))]
|
||||||
|
(* amp filt)))
|
||||||
|
|
||||||
|
(definst ks1
|
||||||
|
[note {:default 60 :min 10 :max 120 :step 1}
|
||||||
|
amp {:default 0.8 :min 0.01 :max 0.99 :step 0.01}
|
||||||
|
dur {:default 2 :min 0.1 :max 4 :step 0.1}
|
||||||
|
decay {:default 30 :min 1 :max 50 :step 1}
|
||||||
|
coef {:default 0.3 :min 0.01 :max 2 :step 0.01}]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
noize (* 0.8 (white-noise))
|
||||||
|
dly (/ 1.0 freq)
|
||||||
|
plk (pluck noize 1 (/ 1.0 freq) dly
|
||||||
|
decay
|
||||||
|
coef)
|
||||||
|
dist (distort plk)
|
||||||
|
filt (rlpf dist (* 12 freq) 0.6)
|
||||||
|
clp (clip2 filt 0.8)
|
||||||
|
reverb (free-verb clp 0.4 0.8 0.2)]
|
||||||
|
(* amp (env-gen (perc 0.0001 dur) :action FREE) reverb)))
|
||||||
|
|
||||||
|
(definst ks1-demo
|
||||||
|
[note 60 amp 0.8 gate 1]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
noize (* 0.8 (white-noise))
|
||||||
|
dly (/ 1.0 freq)
|
||||||
|
plk (pluck noize gate (/ 1.0 freq) dly
|
||||||
|
(mouse-x 0.1 50)
|
||||||
|
(mouse-y 0.0001 0.9999))
|
||||||
|
dist (distort plk)
|
||||||
|
filt (rlpf dist (* 12 freq) 0.6)
|
||||||
|
reverb (free-verb filt 0.4 0.8 0.2)]
|
||||||
|
(* amp (env-gen (perc 0.0001 2) :action FREE) reverb)))
|
||||||
|
|
||||||
|
;; Huh?
|
||||||
|
#_(definst ks-stringer
|
||||||
|
[freq 440 rate 6]
|
||||||
|
(let [noize (* 0.8 (white-noise))
|
||||||
|
trig (dust rate)
|
||||||
|
coef (mouse-x -0.999 0.999)
|
||||||
|
delay (/ 1.0 (* (mouse-y 0.001 0.999) freq))
|
||||||
|
plk (pluck noize trig (/ 1.0 freq) delay 10 coef)
|
||||||
|
filt (rlpf plk (* 12 freq) 0.6)]
|
||||||
|
(* 0.8 filt)))
|
||||||
|
|
||||||
|
(definst fm-mouse-demo
|
||||||
|
[note 60 amp 0.2 gate 0]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
osc-a (* (sin-osc (mouse-x 20 3000))
|
||||||
|
0.3)
|
||||||
|
osc-b (* amp (sin-osc (* (mouse-y 3000 0) osc-a)))]
|
||||||
|
osc-a))
|
||||||
|
|
||||||
|
;; Don't get this
|
||||||
|
#_(definst harmonic-swimming
|
||||||
|
[amp 0.5]
|
||||||
|
(let [freq 100
|
||||||
|
partials 20
|
||||||
|
z-init 0
|
||||||
|
offset (line:kr 0 -0.02 60)
|
||||||
|
snd (loop [z z-init
|
||||||
|
i 0]
|
||||||
|
(if (= partials i)
|
||||||
|
z
|
||||||
|
(let [f (clip:kr (mul-add
|
||||||
|
(lf-noise1:kr [(+ 6 (rand 4))
|
||||||
|
(+ 6 (rand 4))])
|
||||||
|
0.2 offset))
|
||||||
|
src (f-sin-osc (* freq (inc i)))
|
||||||
|
newz (mul-add src f z)]
|
||||||
|
(recur newz (inc i)))))]
|
||||||
|
(out 10 (pan2 (* amp snd)))))
|
||||||
|
|
||||||
|
|
||||||
|
(definst whoahaha
|
||||||
|
[freq 440 dur 5 osc 100 mul 1000]
|
||||||
|
(let [freqs [freq (* freq 1.0068) (* freq 1.0159)]
|
||||||
|
sound (resonz (saw (map #(+ % (* (sin-osc osc) mul)) freqs))
|
||||||
|
(x-line 10000 10 25)
|
||||||
|
(line 1 0.05 25))
|
||||||
|
sound (apply + sound)]
|
||||||
|
(* (lf-saw:kr (line:kr 13 17 3)) (line:kr 1 0 dur FREE) sound)))
|
||||||
|
|
||||||
|
(definst bubbles
|
||||||
|
[bass-freq 80]
|
||||||
|
(let [bub (+ bass-freq (* 3 (lf-saw:kr [8 7.23])))
|
||||||
|
glis (+ bub (* 24 (lf-saw:kr 0.4 0)))
|
||||||
|
freq (midicps glis)
|
||||||
|
src (* 0.04 (sin-osc freq))
|
||||||
|
zout (comb-n src :decay-time 4)]
|
||||||
|
zout))
|
||||||
|
|
||||||
|
(definst string [note 60 amp 1.0 dur 0.5 decay 30 coef 0.3 gate 1]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
noize (* 0.8 (white-noise))
|
||||||
|
dly (/ 1.0 freq)
|
||||||
|
plk (pluck noize gate dly dly decay coef)
|
||||||
|
dist (distort plk)
|
||||||
|
filt (rlpf dist (* 12 freq) 0.6)
|
||||||
|
clp (clip2 filt 0.8)
|
||||||
|
reverb (free-verb clp 0.4 0.8 0.2)]
|
||||||
|
(* amp (env-gen (perc 0.0001 dur) :action 0) reverb)))
|
||||||
|
|
||||||
|
(definst bowed
|
||||||
|
[note 60 velocity 80 gate 1 amp 1
|
||||||
|
bow-offset 0 bow-slope 0.5 bow-position 0.75 vib-freq 6.127 vib-gain 0.2]
|
||||||
|
(let [freq (midicps note)
|
||||||
|
velocity (/ velocity 127)
|
||||||
|
beta-ratio (+ 0.027236 (* 0.2 bow-position))
|
||||||
|
base-delay (reciprocal freq)
|
||||||
|
[fb1 fb2] (local-in 2)
|
||||||
|
vibrato (* (sin-osc vib-freq) vib-gain)
|
||||||
|
neck-delay (+ (* base-delay (- 1 beta-ratio)) (* base-delay vibrato))
|
||||||
|
neck (delay-l fb1 0.05 neck-delay)
|
||||||
|
nut-refl (neg neck)
|
||||||
|
bridge (delay-l fb2 0.025 (* base-delay beta-ratio))
|
||||||
|
string-filt (one-pole (* bridge 0.95) 0.55)
|
||||||
|
bridge-refl (neg string-filt)
|
||||||
|
adsr (* amp (env-gen (adsr 0.02 3.005 1.0 0.01) gate :action FREE))
|
||||||
|
string-vel (+ bridge-refl nut-refl)
|
||||||
|
vel-diff (- adsr string-vel)
|
||||||
|
slope (- 5.0 (* 4 bow-slope))
|
||||||
|
bow-table (clip:ar (pow (abs (+ (* (+ vel-diff bow-offset) slope) 0.75 )) -4) 0 1)
|
||||||
|
new-vel (* vel-diff bow-table)]
|
||||||
|
(local-out (+ [bridge-refl nut-refl] new-vel))
|
||||||
|
(resonz (* bridge 0.5) 500 0.85)))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(demo (ks1 40))
|
||||||
|
|
||||||
|
(doseq [i (range 10)]
|
||||||
|
(demo (at (+ (now) (* i 333)) (ks1 (+ 50 (* i 2))))))
|
||||||
|
|
||||||
|
(stop))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
|
||||||
|
(defonce tri-bus (audio-bus))
|
||||||
|
(defonce sin-bus (audio-bus))
|
||||||
|
|
||||||
|
(defsynth tri-synth [out-bus 0 freq 5]
|
||||||
|
(out:kr out-bus (lf-tri:kr freq)))
|
||||||
|
|
||||||
|
(defsynth sin-synth [out-bus 0 freq 5]
|
||||||
|
(out:kr out-bus (sin-osc:kr freq)))
|
||||||
|
|
||||||
|
(defonce main-g (group "get-on-the-bus main"))
|
||||||
|
(defonce early-g (group "early birds" :head main-g))
|
||||||
|
(defonce later-g (group "latecomers" :after early-g))
|
||||||
|
|
||||||
|
(def tri-synth-inst (tri-synth [:tail early-g] tri-bus)))
|
||||||
|
|
||||||
|
;; (def snare drum/snare)
|
||||||
|
;; (def kick drum/kick)
|
||||||
|
;; (def close-hihat drum/closed-hat)
|
||||||
|
;; (def open-hihat drum/open-hat)
|
||||||
|
|
||||||
|
(comment
|
||||||
|
|
||||||
|
(defn subdivide
|
||||||
|
"subdivide two time intervals by 4, and return the time interval
|
||||||
|
at position. this is a cheap hack to schedule 16th notes without
|
||||||
|
defining the whole pattern with the metronome firing every 16th note."
|
||||||
|
[a b position]
|
||||||
|
(+ a (* position (/ (- b a) 4) )))
|
||||||
|
|
||||||
|
(defn drums [nome]
|
||||||
|
(let [beat (nome)]
|
||||||
|
; hi-hat pattern
|
||||||
|
(at (nome beat) (close-hihat))
|
||||||
|
(at (nome (+ 1 beat)) (open-hihat))
|
||||||
|
(at (nome (+ 2 beat)) (close-hihat))
|
||||||
|
(at (nome (+ 3 beat)) (close-hihat))
|
||||||
|
(at (nome (+ 4 beat)) (close-hihat))
|
||||||
|
(at (nome (+ 5 beat)) (open-hihat))
|
||||||
|
(at (nome (+ 6 beat)) (close-hihat))
|
||||||
|
(at (nome (+ 7 beat)) (close-hihat))
|
||||||
|
|
||||||
|
; snare pattern
|
||||||
|
(at (nome (+ 2 beat)) (snare))
|
||||||
|
(at (subdivide (nome (+ 2 beat)) (nome (+ 4 beat)) 3) (snare))
|
||||||
|
(at (subdivide (nome (+ 4 beat)) (nome (+ 6 beat)) 1) (snare))
|
||||||
|
(at (nome (+ 6 beat)) (snare))
|
||||||
|
(at (subdivide (nome (+ 6 beat)) (nome (+ 8 beat)) 3) (snare))
|
||||||
|
|
||||||
|
; kick drum pattern
|
||||||
|
(at (nome beat) (kick))
|
||||||
|
(at (nome (+ 5 beat)) (kick))
|
||||||
|
(at (nome (+ 7 beat)) (kick))
|
||||||
|
(apply-by (nome (+ 8 beat)) drums nome [])))
|
||||||
|
|
||||||
|
(demo (drums (metronome 180)))
|
||||||
|
|
||||||
|
(defn bass [nome]
|
||||||
|
(let [beat (nome)]
|
||||||
|
(at (nome beat) (string 51))
|
||||||
|
(at (subdivide (nome beat) (nome (+ 2 beat)) 1) (string 51))
|
||||||
|
(at (subdivide (nome beat) (nome (+ 2 beat)) 3) (string 51))
|
||||||
|
(at (subdivide (nome (+ beat 1)) (nome (+ 3 beat)) 1) (string 51))
|
||||||
|
(at (subdivide (nome (+ beat 1)) (nome (+ 3 beat)) 3) (string 51))
|
||||||
|
(at (nome (+ 4 beat)) (string 51))
|
||||||
|
(at (subdivide (nome (+ 4 beat)) (nome (+ 6 beat)) 1) (string 49))
|
||||||
|
(at (nome (+ 5 beat)) (string 46))
|
||||||
|
(at (nome (+ 6 beat)) (string 51))
|
||||||
|
(at (subdivide (nome (+ 6 beat)) (nome (+ 8 beat)) 1) (string 49))
|
||||||
|
(at (nome (+ 7 beat)) (string 46))
|
||||||
|
(at (nome (+ 8 beat)) (string 51))
|
||||||
|
(at (nome (+ 12 beat)) (string 51))
|
||||||
|
(at (subdivide (nome (+ 12 beat)) (nome (+ 14 beat)) 1) (string 51))
|
||||||
|
(apply-by (nome (+ 16 beat)) bass nome [])))
|
||||||
|
|
||||||
|
(defn section [nome]
|
||||||
|
(drums nome)
|
||||||
|
(bass nome))
|
||||||
|
|
||||||
|
(def met (metronome (* 100 2)))
|
||||||
|
|
||||||
|
(demo 5 (section met))
|
||||||
|
|
||||||
|
(stop))
|
|
@ -0,0 +1,73 @@
|
||||||
|
(ns tunes.track
|
||||||
|
(:require [overtone.core :as o]))
|
||||||
|
|
||||||
|
(defrecord Track [metronome players playing?])
|
||||||
|
|
||||||
|
(defn- beat->bar-beat [m b]
|
||||||
|
(let [bpb (o/metro-bpb m)]
|
||||||
|
(mod b bpb)))
|
||||||
|
|
||||||
|
(defn- tick-track
|
||||||
|
([track] (tick-track track ((:metronome track))))
|
||||||
|
([track beat]
|
||||||
|
(let [m (:metronome track)]
|
||||||
|
(when (-> track :playing? deref)
|
||||||
|
(send (:players track)
|
||||||
|
(fn [players metronome beat]
|
||||||
|
(let [bar-beat (beat->bar-beat m beat)]
|
||||||
|
(doseq [[name player] players]
|
||||||
|
(try
|
||||||
|
(player metronome bar-beat)
|
||||||
|
(catch Exception e (println (str "error in player " name ": " e))))))
|
||||||
|
players)
|
||||||
|
m beat)
|
||||||
|
(o/apply-at (m (inc beat)) #'tick-track [track (inc beat)])))))
|
||||||
|
|
||||||
|
(defn make-track [bpm]
|
||||||
|
(Track. (o/metronome bpm) (agent {}) (atom false)))
|
||||||
|
|
||||||
|
(defn- partial-keyword [f & tail-args]
|
||||||
|
(fn [& args] (apply f (concat args tail-args))))
|
||||||
|
|
||||||
|
(defn add-player [track name player]
|
||||||
|
(send (:players track) conj {name player})
|
||||||
|
name)
|
||||||
|
|
||||||
|
(defn rm-player [track name]
|
||||||
|
(send (:players track) dissoc name)
|
||||||
|
name)
|
||||||
|
|
||||||
|
(defn ls-players [track]
|
||||||
|
(-> track :players deref keys))
|
||||||
|
|
||||||
|
(defn- always [val] (fn [& _] val))
|
||||||
|
|
||||||
|
(defn start [track]
|
||||||
|
(swap! (:playing? track) (always true))
|
||||||
|
(tick-track track)
|
||||||
|
track)
|
||||||
|
|
||||||
|
(defn stop [track]
|
||||||
|
(swap! (:playing? track) (always false))
|
||||||
|
track)
|
||||||
|
|
||||||
|
(defn clear [track]
|
||||||
|
(send (:players track) (always {})))
|
||||||
|
|
||||||
|
(defn print-thru [o] (println o) o)
|
||||||
|
|
||||||
|
(defn on-beat [track ugen &
|
||||||
|
{:keys [name on-beat offset]
|
||||||
|
:or {name (keyword (gensym))
|
||||||
|
on-beat (always true)
|
||||||
|
offset (always 0)}}]
|
||||||
|
(let [offset-fn (if (fn? offset) offset (fn [tick-len] (* offset tick-len)))]
|
||||||
|
(add-player track
|
||||||
|
name
|
||||||
|
(fn [metronome beat-num]
|
||||||
|
(when (on-beat beat-num)
|
||||||
|
(o/at (+ (metronome beat-num) (offset-fn (o/metro-tick metronome)))
|
||||||
|
(ugen)))))))
|
||||||
|
|
||||||
|
(defn nth-beat [n]
|
||||||
|
(fn [beat] (= n beat)))
|
Loading…
Reference in New Issue