   (fn [context at duration]
     (let [remainder (- duration attack decay sustain)
           hold (max 0.0 remainder)
-          ugen (adshr attack decay sustain hold release)]
-      (-> ugen (run-with context at duration)))))
+          node (adshr attack decay sustain hold release)]
+      (-> node (run-with context at duration)))))
 
 (defn percussive [attack decay]
   (envelope [attack 1.0] [decay 0.0]))

; Combinators

(defn connect
  [ugen1 ugen2]
  (fn [context at duration]
    (let [sink (-> ugen2 (run-with context at duration))]
      (-> ugen1 (run-with context at duration) (.connect sink))
      sink)))

(defn connect-> [& nodes]
  (reduce connect nodes))

(defn add [& ugens]
  (fn [context at duration]
    (let [sink (-> (gain 1.0) (run-with context at duration))]
      (doseq [ugen ugens]
        (-> ugen (run-with context at duration) (.connect sink)))
      sink)))



; Envelopes

(defn envelope
  "Build an envelope out of [segment-duration final-level] coordinates."
  [& corners]
  (fn [context at duration]
    (let [audio-node (.createGain context)]
      (-> audio-node .-gain (.setValueAtTime 0.0 at))
      (reduce
        (fn [x [dx y]]
          (-> audio-node .-gain (.linearRampToValueAtTime y (+ x dx)))
          (+ dx x))
        at
        corners)
      audio-node)))

(defn adshr [attack decay sustain hold release]
  (envelope [attack 1.0] [decay sustain] [hold sustain] [release 0]))
