Skip to content

Instantly share code, notes, and snippets.

@micahrj
Created December 16, 2013 09:39
Show Gist options
  • Save micahrj/7984505 to your computer and use it in GitHub Desktop.
Save micahrj/7984505 to your computer and use it in GitHub Desktop.
(ns paint.core
(:use [seesaw core graphics color]
clojure.math.numeric-tower)
(:require [seesaw.mouse :as m]
[seesaw.bind :as b]
[overtone.live :as o]))
(def canvas-width 50)
(def canvas-height 50)
(def cell-width 8)
(def cell-height 8)
(def song (atom (vec (repeat canvas-height (vec (repeat canvas-width 0))))))
(defn -main [& args]
(o/definst tone [freq 440 amp 1] (* amp (o/sin-osc freq)))
(def tones (for [y (range canvas-height)]
;(tone (* 50 (- canvas-height y)))))
(tone (* 220 (expt (expt 2 (/ 1 12)) (- canvas-height y 1))) 0)))
(def play (button :text "play"))
(def stop (button :text "stop"))
(def reset (button :text "reset"))
(def song-canvas (canvas :id :canvas :background "#000000"))
(def content (border-panel :hgap 5 :vgap 5 :border 5
:north (horizontal-panel :items [play stop reset])
:center song-canvas))
(defn click-handler [e]
(let [[x y] (m/location e)]
(swap! song (fn [s] (update-in s [(quot y cell-height) (quot x cell-width)]
(fn [x] (case (m/button e)
:left (min 255 (+ x 50))
:right (max 0 (- x 50))))))))
(repaint! song-canvas))
(defn paint-canvas [c g]
(doseq [x (range canvas-width)
y (range canvas-height)]
(let [brightness (nth (nth @song y) x)]
(draw g (rect (* x cell-width) (* y cell-height) cell-width cell-height)
(style :background (color brightness brightness brightness 255))))))
(config! song-canvas :paint paint-canvas)
(def tick (atom nil))
(listen play :action (fn [e]
(let [t @tick] (if (not (nil? t)) (.stop @tick)))
(swap! tick (fn [_] (timer (fn [x]
(doseq [y (range canvas-height)]
(o/ctl (nth tones y) :amp (/ (get-in @song [y x]) 255)))
(+ 1 x))
:initial-value 0 :delay 125 :start? true :repeats? true)))))
(listen stop :action (fn [e]
(doseq [t tones] (o/ctl t :amp 0))
(let [t @tick] (if (not (nil? t)) (.stop @tick)))))
(listen reset :action (fn [e]
(swap! song (fn [s] (vec (repeat canvas-height (vec (repeat canvas-width 0))))))
(repaint! song-canvas)))
(listen song-canvas :mouse-pressed click-handler)
(invoke-later
(-> (frame :title "hi" :width 640 :height 480 :content content :on-close :exit)
show!)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment