 
 (defmethod live/play-note :default [{:keys [pitch pan]}]
   (when pitch (horn :freq pitch :pan (or pan 0))))
-
-(defn rand-variations [variations]
-  (let [variation (rand-nth variations)]
-    (concat
-      variation
-      (lazy-seq
-        (->> (rand-variations variations)
-             (after (duration variation) ))))))
-
-(defn part [model & variations]
-  ((apply juxt identity variations) model))
-
-(def tete
-  (let [model (phrase [8/4 3/4 5/4] (repeat 0))
-        a (split 0 1/4)
-        b (comp (split 1/4 1/4) a)
-        c (comp (accent 2/4) (split 2/4 1/4) b)
-        d (comp (omit 0/4) c)]
-    (part model a b c d)))
-
-(def ta
-  (let [model (->> (phrase [5/4 3/4 4/4] (repeat 1)) (after 4/4))
-        a (split 9/4 1/4)
-        b (comp (split 10/4 1/4) a)
-        c (comp (accent 11/4) (split 11/4 1/8) b) ; 17
-        d (split 4/4 1/4)
-        e (comp (omit 10/4) c)] ; 8
-    (part model a b c d e)))
-
-(def ha
-  (let [model (->> (phrase [12/4 2/4] (repeat 2)) (after 2/4))
-        a (comp (split 2/4 1/4) (split 0 1/4))
-        b (comp (split 6/4 1/4))
-        c (comp (split 0 1/4) b)
-        d (comp a b)]
-    (part model a b c d)))
-
-(def tulule
-  (let [model (phrase [8/4 8/4] (repeat 3))
-        a (comp (split 8/4 2/4) (split 0 2/4)) ; 28
-        b (comp (split 0 1/4) (split 2/4 1/4) a) ; 6
-        c (comp (accent 7/8) (split 3/4 1/8) b)] ; 5
-    (part model a b c)))
-
-(def bongo
-  (let [model (->> (phrase [3/4 7/4] (repeat 4)) (after 6/4)) ; 5
-        a (split 9/4 5/4) ; 6
-        b (comp (split 6/4 1/4) a) ; 9
-        c (comp (split 14/4 1/4) b) ; 8
-        d (comp (accent 10/4) (split 9/4 1/4) b)] ; 19
-    (part model a b c d)))
-
-(defn big [notes]
-  (->> notes
-       (map (partial where :pitch #(+ % 5)))))
-
-(defn pan [{:keys [pitch] :as note}]
-  (if pitch
-    (let [p (-> note :pitch (/ 18) dec)]
-      (if (odd? pitch)
-        (assoc note :pan (- p))
-        (assoc note :pan p)))
-    note))
-
-(def ndereje-balendoro ; p 343
-  (->> [tete ta ha tulule bongo
-        (big tete) (big ta) (big ha) (big tulule) (big bongo)
-        (big (big tete)) (big (big ta)) (big (big ha)) (big (big tulule)) (big (big bongo))
-        (big (big (big tete))) (big (big (big ta))) (big (big (big ha)))]
-       ;(map (comp list first))
-       (map rand-variations)
-       (map after (range 0 (* 4 18) 4))
-       (reduce with)
-       (map pan)))
-
-(comment
-  (->>
-    ndereje-balendoro
-    (where :pitch (comp temperament/equal A car))
-    (tempo (bpm 120))
-    (live/play)))
-
-(def first-drum
-  (let [model (->> (rhythm [2/5 3/5 1/5 1/5 3/5]) (all :part :clap1))
-        a (split 6/5 1/10)
-        b (split 5/5 1/10)
-        c (comp (split 17/15 2/15) (split 5/5 2/15) (omit 6/5))
-        d (comp (omit 7/5) (omit 6/5))]
-    (part model a b c d)))
-
-(def second-drum
-  (let [model (->> (rhythm [2/5 2/5 4/5 1/5 1/5]) (all :part :clap2))
-        a (omit 9/5)
-        b (omit 0)
-        c (comp a b)
-        d #(then % (->> (rhythm (repeat 5 2/5)) (all :part :clap2)))]
-    (part model a b c d)))
-
-(def third-drum
-  (let [model (->> (rhythm [2/5 1/5 2/5]) (all :part :clap3))
-        a (omit 2/5)
-        b (omit 3/5)
-        c (comp (split 0 1/5) a)
-        d (split 3/5 1/5)
-        e (comp (split 3/5 1/10) d)
-        f (split 0 1/5)
-        g (comp (split 0 1/10) f)]
-    (part model a b c d e f g)))
-
-(def aga-terumo ; p299
-  (let [drums [first-drum second-drum third-drum]]
-    (->> drums
-         ;(map (comp list first))
-         (map rand-variations)
-         (map after (range 0 (* 4 3) 4))
-         (reduce with))))
-
-(comment
-  (->>
-    aga-terumo
-    (tempo (bpm 90))
-    (live/play)))


(defmethod live/play-note :clap3 [_]
  (drum 75 :pan 0))

(defn vary [t f]
  (fn [notes]
    (let [before? #(-> % :time (< t))
          before (->> notes (take-while before?))
          [note & after] (->> notes (drop-while before?))]
      (concat before (f note) after))))

(defn split [t fraction]
  (letfn [(f [note]
            [(-> note
                 (assoc :duration fraction))
             (-> note
                 (update-in [:duration] - fraction)
                 (update-in [:time] + fraction))])]
    (vary t f)))

(defn accent [t]
  (letfn [(f [note] [(-> note (update-in [:pitch] dec))])]
    (vary t f)))

(defn omit [t]
  (vary t (constantly [])))

(definst horn [freq 440 vol 0.5 pan 0]
  (-> (sin-osc freq)

  (->> (clapping-music)
       live/play))

(defn vary [t f]
  (fn [notes]
    (let [before? #(-> % :time (< t))
          before (->> notes (take-while before?))
          [note & after] (->> notes (drop-while before?))]
      (concat before (f note) after))))

(defn split [t fraction]
  (letfn [(f [note]
            [(-> note
                 (assoc :duration fraction))
             (-> note
                 (update-in [:duration] - fraction)
                 (update-in [:time] + fraction))])]
    (vary t f)))

(defn accent [t]
  (letfn [(f [note] [(-> note (update-in [:pitch] dec))])]
    (vary t f)))

(defn omit [t]
  (vary t (constantly [])))

(defn rand-variations [variations]
  (let [variation (rand-nth variations)]
    (concat
      variation
      (lazy-seq
        (->> (rand-variations variations)
             (after (duration variation) ))))))

(defn part [model & variations]
  ((apply juxt identity variations) model))

(def tete
  (let [model (phrase [8/4 3/4 5/4] (repeat 0))
        a (split 0 1/4)
        b (comp (split 1/4 1/4) a)
        c (comp (accent 2/4) (split 2/4 1/4) b)
        d (comp (omit 0/4) c)]
    (part model a b c d)))

(def ta
  (let [model (->> (phrase [5/4 3/4 4/4] (repeat 1)) (after 4/4))
        a (split 9/4 1/4)
        b (comp (split 10/4 1/4) a)
        c (comp (accent 11/4) (split 11/4 1/8) b) ; 17
        d (split 4/4 1/4)
        e (comp (omit 10/4) c)] ; 8
    (part model a b c d e)))

(def ha
  (let [model (->> (phrase [12/4 2/4] (repeat 2)) (after 2/4))
        a (comp (split 2/4 1/4) (split 0 1/4))
        b (comp (split 6/4 1/4))
        c (comp (split 0 1/4) b)
        d (comp a b)]
    (part model a b c d)))

(def tulule
  (let [model (phrase [8/4 8/4] (repeat 3))
        a (comp (split 8/4 2/4) (split 0 2/4)) ; 28
        b (comp (split 0 1/4) (split 2/4 1/4) a) ; 6
        c (comp (accent 7/8) (split 3/4 1/8) b)] ; 5
    (part model a b c)))

(def bongo
  (let [model (->> (phrase [3/4 7/4] (repeat 4)) (after 6/4)) ; 5
        a (split 9/4 5/4) ; 6
        b (comp (split 6/4 1/4) a) ; 9
        c (comp (split 14/4 1/4) b) ; 8
        d (comp (accent 10/4) (split 9/4 1/4) b)] ; 19
    (part model a b c d)))

(defn big [notes]
  (->> notes
       (map (partial where :pitch #(+ % 5)))))

(defn pan [{:keys [pitch] :as note}]
  (if pitch
    (let [p (-> note :pitch (/ 18) dec)]
      (if (odd? pitch)
        (assoc note :pan (- p))
        (assoc note :pan p)))
    note))

(def ndereje-balendoro ; p 343
  (->> [tete ta ha tulule bongo
        (big tete) (big ta) (big ha) (big tulule) (big bongo)
        (big (big tete)) (big (big ta)) (big (big ha)) (big (big tulule)) (big (big bongo))
        (big (big (big tete))) (big (big (big ta))) (big (big (big ha)))]
       ;(map (comp list first))
       (map rand-variations)
       (map after (range 0 (* 4 18) 4))
       (reduce with)
       (map pan)))

(comment
  (->>
    ndereje-balendoro
    (where :pitch (comp temperament/equal A car))
    (tempo (bpm 120))
    (live/play)))

(def first-drum
  (let [model (->> (rhythm [2/5 3/5 1/5 1/5 3/5]) (all :part :clap1))
        a (split 6/5 1/10)
        b (split 5/5 1/10)
        c (comp (split 17/15 2/15) (split 5/5 2/15) (omit 6/5))
        d (comp (omit 7/5) (omit 6/5))]
    (part model a b c d)))

(def second-drum
  (let [model (->> (rhythm [2/5 2/5 4/5 1/5 1/5]) (all :part :clap2))
        a (omit 9/5)
        b (omit 0)
        c (comp a b)
        d #(then % (->> (rhythm (repeat 5 2/5)) (all :part :clap2)))]
    (part model a b c d)))

(def third-drum
  (let [model (->> (rhythm [2/5 1/5 2/5]) (all :part :clap3))
        a (omit 2/5)
        b (omit 3/5)
        c (comp (split 0 1/5) a)
        d (split 3/5 1/5)
        e (comp (split 3/5 1/10) d)
        f (split 0 1/5)
        g (comp (split 0 1/10) f)]
    (part model a b c d e f g)))

(def aga-terumo ; p299
  (let [drums [first-drum second-drum third-drum]]
    (->> drums
         ;(map (comp list first))
         (map rand-variations)
         (map after (range 0 (* 4 3) 4))
         (reduce with))))

(comment
  (->>
    aga-terumo
    (tempo (bpm 90))
    (live/play)))

; Instruments
(definst drum [freq 440 vol 0.5 pan 0]
  (-> (* 2/3 (brown-noise))
      (+ (* 1/2 (sin-osc (* 3 freq))))
