   (q/color-mode :rgb 1.0))
 
 
-(defn draw-state [state]
+(defn draw-freq-spectrum [state]
   "state is an atom"
   (q/background 0.2)
   (let [s @state]
-;    (q/text (str (:ys s)) 100 100 300 300)
     (doseq [i (range (count (:xs s)))
             :let [x (* i 4)
                   h (+ 2 (nth (:ys s) i))]]
-      #_(q/rect x 0 4 (* 10 (/ (Math/log (* 1 h))
+      #_(q/rect x 0 4 (* 10 (/ (Math/log (* 1 h)) ;; linearly scaled scaling
                              (Math/log (+ 1.1 (- 1 (/ i 135)))))))
-      (q/rect x 0 4 h)
-      #_(q/rect x 0 4 (Math/pow h (nth (:xs s) i)))
-      #_(q/rect x 0 4 (* (+ 1 (/ (+ 1 i) 136)) h)))))
+      #_(q/rect x 0 4 h) ;; linear scaling
+      (q/rect x 0 4 (* (+ 1 (* 2 (/ (+ 1 i) 136))) h)))))
 
 
-(defn quil-plot [state]
+(defn quil-freq-spectrum [state]
   (q/sketch
    :title "plot"
    :size [(:w CONF) (:h CONF)]
    :setup quil-setup
    :update identity
-   :draw (fn [_] (draw-state state))
+   :draw (fn [_] (draw-freq-spectrum state))
    :middleware [qm/fun-mode]))
 
 
+;;; waveform
+
+(defn draw-waveform [a]
+  (q/background 1.0)
+  (defn scale [y] (-> y (* 200) (+ 200)))
+  (defn get-y [i] (-> (:input a) .-mix (.get i)))
+  (doseq [i (-> (:frame-size a) dec range)]
+    (q/line i (scale (get-y i))
+            (inc i) (scale (get-y (inc i))))))
+
+
+(defn plot-waveform [a]
+  (q/sketch
+   :size [1024 400]
+   :setup quil-setup
+   :update identity
+   :draw (fn [_] (draw-waveform a))
+   :middleware [qm/fun-mode]))
+
+
+;;; docs
 
 ;; in repl:
-;; (def a (init-stuff)) ;; a dict
+;; (def a (init-line)) ;; a dict
 ;; (def state (make-init-state)) ;; an atom
 ;; (update-state state a)
 ;; ... (quil-plot state)
-;; (swap! state assoc :stop true)
-;; (stop-stuff a)
+;; (stop-update state)
+;; (stop-line a)

                      (map #(.getAvg fft %))))))



(def A 45)
(def B 15)

(defn stop-update [state]
  (swap! state assoc :stop true))

(defn update-state [state args]
  (stop-update state)
  (Thread/sleep 400)
  (swap! state assoc :stop false)
  (let [fft (FFT. (:frame-size args) 44100.0)]
    (.logAverages fft A B)
    (a/go (while (not (:stop @state))
            (.forward fft (.-mix (:input args)))
            (swap! state update-state-once fft)
            (Thread/sleep 10)))))




#_(defn test []
  (def a (init-stuff))
  (update-state state a)
  (Thread/sleep 1000)
  (swap! state assoc :stop true)
  (stop-stuff a)
  (swap! state assoc :stop false)
  nil)


(defn minim-test [args]
  (let [fft (FFT. (:frame-size args) 44100.0)
        get-bands (fn [] (->> (range (.specSize fft))
                              (map #(.getBand fft %))))
        get-avgs (fn [] (->> (range (.avgSize fft))
                             (map #(.getAverageBandWidth fft %))))
        get-bnds get-bands]
    (.logAverages fft A B)
    (.forward fft (.-mix (:input args)))
    (Thread/sleep 50)
    (.forward fft (.-mix (:input args)))
    (def bands (get-bnds))
    (println (count bands))
                                        ;(plot bands)
    (plot1 fft)
    nil
    #_(while true
      (.forward fft (.-mix input))
      (->> (get-bands) plot)
      (Thread/sleep 2000)
      #_(.detect beat-detect (.-mix input))
      #_(cond (.isHat beat-detect) (println "HAT")
              (.isSnare beat-detect) (println "SNARE")
              (.isKick beat-detect) (println "KICK")))))



;;; quil


(def CONF
  {:w 600

(ns vijualizer.core
  (:require [clojure.core.async :as a]
            [quil.core :as q]
            [quil.middleware :as qm])
  (:import [ddf.minim Minim]
           [ddf.minim.analysis BeatDetect FFT]))


;;; Minim

;; Emulation of Processing-Environment functions

;; Defining an interface so it is possible to add types,
;; which is necessary for the class
(definterface MinimInput
  (^String sketchPath [^String filename])
  (^java.io.InputStream createInput [^String filename]))


(def MinimDummyInput
  (proxy [MinimInput] []
    (sketchPath [filename] "")
    (createInput [filename] nil)))


(defn init-line []
  "Initializes Minim and an InputLine"
  (let [frame-size 1024
        minim (Minim. MinimDummyInput)
        input (.getLineIn minim Minim/MONO, frame-size)]
    {:frame-size frame-size
     :minim minim
     :input input}))


(defn stop-line [line]
  (.close (:input line))
  (.stop (:minim line)))


;;; FFT stuff

(defn make-init-state []
  (atom {:stop false
