 
 ;;UGENS - Unit generators (Sweet shop)
 
-(defsynth foo [freq 200 dur 0.5]
-  (let [src (saw [freq (* freq 1.01) (* 0.99 freq)])
-        low (sin-osc (/ freq 2))
-        filt (lpf src (line:kr (* 10 freq) freq 10))
-        env (env-gen (perc 0.1 dur) :action FREE)]
-    (out 0 (pan2 (* 0.8 low env filt)))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;Busses - Wiring synths         ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defonce tri-bus (audio-bus)) ;;Audio busses are just ids preallocated at boot.
+(defsynth ding [freq 880 dur 0.2 level 0.25 pan 0.0 out-bus 0]
+  (let [amp  (env-gen:ar (env-perc) :action FREE :time-scale dur)
+        snd (* (sin-osc:ar freq ) amp level)]
+    (out out-bus (pan2:ar snd pan))))
+
+(defsynth tick [freq 880 dur 0.1 level 0.25 pan 0.0 out-bus 0]
+  (let [amp (env-gen (env-perc) :action FREE :time-scale dur)
+        snd (lpf:ar (white-noise:ar) freq)]
+    (out out-bus (pan2:ar (* snd amp level) pan))))
+
+(defsynth woody-beep [freq 300 out-bus 0 dur 0.4]
+  (let [tri (* 0.5 (lf-tri:ar freq))
+        sin (sin-osc:ar (* 1 freq))
+        sin2 (sin-osc:ar (* 1.01 freq))
+        wood (bpf:ar (* (white-noise:ar) (line:kr 5 0 0.02)) freq 0.02)
+        src (mix [sin sin2 tri wood])
+        src (free-verb src)
+        env (env-gen:ar (env-perc :release 0.25) :action FREE :time-scale dur)]
+    (out out-bus (pan2 (* env src)))))
+
+(woody-beep :freq 400)
+
+(kill woody-beep)
+(show-graphviz-synth ding)
+
+(ding)
+(tick)
+
+;;Samples
+
+(def subby-s (freesound-sample))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;Busses - Wiring synths ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;Audio busses are just ids preallocated at boot.
+(defonce tri-bus (audio-bus))
 (defonce sin-bus (audio-bus))
 
 (println sin-bus)

(defsynth divider [div 32 in-bus 0 out-bus 0]
  (out:kr out-bus (pulse-divider (in:kr in-bus) div)))

(defonce root-count   (counter [:head timing-g] :in-bus root-trigger-bus :out-bus root-count-bus))
(defonce root-trigger (trigger [:head timing-g] :rate 100 :in-bus root-trigger-bus))
(defonce beat-trigger (divider [:after root-count] :div current-beat :in-bus root-trigger-bus :out-bus beat-trigger-bus))
(defonce beat-count   (counter [:after beat-trigger] :in-bus beat-trigger-bus :out-bus beat-count-bus))
(defsynth get-beat [] (send-trig (in:kr beat-trigger-bus) count-trigger-id (+ (in:kr beat-count-bus) 1)))

(get-beat)


(require '[overtone.inst.drum :as drum])
(on-trigger count-trigger-id (fn [x] (drum/kick)) ::beat-watch)

(ctl beat-trigger :div 60)
(ctl root-trigger :rate 100)

(comment (remove-event-handler ::beat-watch))

;; Timing and Buffers

(require '[codemash.timing :as time])


(kill mid)
(stop)

;;;;;;;;;;;;;;;;;;;;;;;
;; Timing AND Buffers;;
;;;;;;;;;;;;;;;;;;;;;;;

(def score-b         (buffer 128))
(def duration-b      (buffer 128))
(def bass-duration-b (buffer 128))
(def bass-notes-b    (buffer 128))

(def score [:F4 :F4 :F4 :F4 :F4 :F4 :F4
            :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4 :G4
            :BB4 :BB4 :BB4 :BB4 :BB4 :BB4
            :D#4 :D#4 :D#4])

(def duration     [1/7])

(def score (concat
            (map #(+ -5  (note %)) score)
            (map #(+ -5  (note %)) score)
            (map #(+ -10 (note %)) score)
            (map #(+ -5  (note %)) score)
            (map #(+ -1  (note %)) score)))

(defsynth woody-beep [duration-bus 0 beat-count-bus 0 offset-bus 0 amp 1 out-bus 0]
  (let [cnt    (in:kr beat-count-bus)
        offset (buf-rd:kr 1 offset-bus cnt)
        durs   (buf-rd:kr 1 duration-bus cnt)
        trig (t-duty:kr (dseq durs INFINITE))
        freq (demand:kr trig 0 (drand offset INFINITE))
        freq (midicps freq)

        env (env-gen:ar (env-asr :release 0.25 :sustain 0.8) trig)
        tri (* 0.5 (lf-tri:ar freq))
        sin (sin-osc:ar (* 1 freq))
        sin2 (sin-osc:ar (* 1.01 freq))
        wood (bpf:ar (* (white-noise:ar) (line:kr 5 0 0.02)) freq 0.02)
        src (mix [sin sin2 tri wood])
        src (free-verb src)]
    (out:ar out-bus (* amp env (pan2 src)))))

    (def w  (woody-beep :duration-bus duration-b :beat-count-bus beat-count-bus :offset-bus score-b :amp 4))

(defsynth deep-saw [freq 100 beat-count-bus 0 offset-bus 0 duration-bus 0 out-bus 0 amp 1 pan 0]
  (let [cnt    (in:kr beat-count-bus)
        offset (buf-rd:kr 1 offset-bus cnt)
        durs   (buf-rd:kr 1 duration-bus cnt)
        trig (t-duty:kr (dseq durs INFINITE))
        freq (demand:kr trig 0 (drand offset INFINITE))
        freq (midicps freq)

        saw1 (lf-saw:ar (* 0.5 freq))
        saw2 (lf-saw:ar (* 0.25 freq))
        sin1 (sin-osc freq)
        sin2 (sin-osc (* 1.01 freq))
        src (mix [saw1 saw2 sin1 sin2])
        env (env-gen:ar (env-asr) trig)
        src (lpf:ar src)
        src (free-verb src 0.33 1 1)]
    (out out-bus (* amp [src src]))))

(def ps (deep-saw 100 :duration-bus bass-duration-b :beat-count-bus beat-count-bus :offset-bus bass-notes-b :amp 0.9))

(ctl ps :damp 1)
(ctl ps :room 1)

(kill ps)

(buffer-write! bass-duration-b (take 32 (cycle [(/ 1 3.5)])))
(buffer-write! bass-notes-b (take 32 (cycle (map note [:F2 :F2 :G3 :G2 :G3 :BB2 :BB2 :G2 :G2]))))

(buffer-write! bass-notes-b (take 32 (cycle (map #(+ 0 (note %)) [:F2 :F2 :G3 :G2 :G3 :BB2 :BB2 :G2 :G2]))))

(buffer-write! score-b (take 128 (cycle (map note score))))
(buffer-write! duration-b (take 128 (cycle duration)))

(ctl root-trigger :rate 100)
(ctl beat-trigger :div 30)

;;Hardware (External devices)

(midi-connected-devices)

(on-event [:midi :note-on]
          (fn [m]
            (buffer-write! music-buffer (map midi->hz
                                             (map (fn [midi-note] (+ -12 midi-note))
                                                  (repeat 256 (:note m))))))
          ::phat-bass-keyboard)

(comment
  (remove-event-handler ::drumkit))
