initial checkin

This commit is contained in:
Niten 2022-12-22 09:48:48 -08:00
commit 1b001e49ee
7 changed files with 2074 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
.DS_Store
.idea
*.log
tmp/
.cpcache/
.nrepl-port
target/
result
.clj-kondo
native/

7
deps.edn Normal file
View File

@ -0,0 +1,7 @@
{
:paths ["src"]
:deps {
org.clojure/clojure {:mvn/version "1.11.0"}
overtone/overtone {:mvn/version "0.10.6"}
}
}

1138
deps.nix Normal file

File diff suppressed because it is too large Load Diff

337
src/tunes/core.clj Normal file
View File

@ -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)))

4
src/tunes/live.clj Normal file
View File

@ -0,0 +1,4 @@
(ns tunes.live
(:use overtone.core)
(:require [overtone.inst.drum :as drum]
[tunes.track :as track]))

504
src/tunes/sounds.clj Normal file
View File

@ -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))

73
src/tunes/track.clj Normal file
View File

@ -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)))