            hold        100
            rms-window  100
            trigger     default-trigger}}]
-  (let [node   (.createScriptProcessor ctx buffer-size 1 1)
-        config {:ctx        ctx
+  (let [config {:ctx        ctx
                 :threshold  threshold
                 :look-ahead look-ahead
                 :hold       hold
                 :rms-window rms-window
-                :trigger    trigger}
-        gate   (map->Gate {:config      config
-                           :node        node
-                           :rms-buffers (aatom [])})]
-    (set! (.-onaudioprocess node)
-          #(.process-audio gate %))
-    gate))
+                :trigger    trigger}]
+    (map->Gate {:config      config
+                :next        (atom nil)
+                :rms-buffers (aatom [])})))

  (:require [audio-utils.ring-buffer :as rb]
            [audio-utils.rms-buffer :as rms]
            [audio-utils.util :refer [aatom aderef areset! aswap!
                                      db->amplitude time->samples]]))

(defprotocol IGate
  (connect-source [this source])
  (connect-destination [this destination])
  (disconnect [this]))

;;sample-rate        (.-sampleRate ctx)
;;threshold'         (db->amplitude threshold)

;;look-ahead-samples (max 1 (time->samples look-ahead sample-rate))
;;look-ahead-buffer  (rb/ring-buffer look-ahead-samples)

;;(let [sample-rate (.-sampleRate (:ctx config))
;;      rms-window  (:rms-window config)
;;      rms-samples (max 1 (time->samples rms-window sample-rate))]
;;  (areset! rms-buffers
;;           (into [] (repeat (.-channelCount source)
;;                            (rms/rms-buffer rms-samples)))))

(defprotocol IGate
  (generate-output-sample [this channel input-sample]))

(defrecord Gate [config next rms-buffers]
  w/IWorkerAudioNode
  (connect [this destination]
    (reset! next destination))

  (disconnect [this]
    (reset! next nil))

  (process-audio [this data]
    (let [n-samples  (count (first data))
          n-channels (count data)
          output     (volatile! (into [] (repeat n-channels [])))]
      (dotimes [n n-samples]
        (dotimes [channel n-channels]
          (let [input-sample  ((data channel) n)
                output-sample (generate-output-sample this channel
                                                      input-sample)]
            (vswap! output update channel conj output-sample))))
      (some-> @next (w/process-audio @output))))

  IGate
  (generate-output-sample [this channel input-sample]
    (if (>= (Math/abs input-sample)
            (db->amplitude (:threshold config)))
      input-sample
      0.0)))

(defn default-trigger
  [gate state])
