28
Nov 12

Hoover sound in Overtone

I’ve recently managed to write my first serious instrument in Overtone. It is a straightforward translation from the existing SuperCollider code. Good analysis of this synth can be found here.

It sounds like this:

The resulting code looks rather imperative. Here’s the synth:

(defsynth hoooover [freq 220 amp 10 lgu 0.1 lgd 1 gate 1]
     (let [pwm (lin-lin (sin-osc:kr (vec (repeatedly 3 #(ranged-rand 2 4)))) -1 1 0.125 0.875)
           freq (lag-ud freq lgu lgd)
           freq (*
                  freq
                  (lin-exp (sin-osc:kr 
                                 (vec (repeatedly 3 #(ranged-rand 2.9 3.1)))
                                 (vec (repeatedly 3 #(ranged-rand 0 (* 2 Math/PI))))
                                 ) -1 1 0.995 1.005)) 
           mix (*
                 0.1
                 (apply + 
                        (*
                          (lin-lin (lf-saw (* [0.25 0.5 1] freq) 1) -1 1 0 1)
                          (- 1 (lf-pulse:ar (* freq [0.5 1 2]) 0 pwm)))))
           ;bass
           mix (+ mix (lf-par (* 0.25 freq) 0))
           mix (mul-add mix 0.1 0)
           ;eq
           mix (b-peak-eq mix 6000 1 3)
           mix (b-peak-eq mix 3500 1 6)
           ;chorus
           mix (+ mix 
                 (* 0.5 (comb-c mix 1/200 
                             (lin-lin (sin-osc:kr 3 [(* 0.5 Math/PI) (* 1.5 Math/PI)]) -1 1 1/300 1/200)
                             0)))
           env (env-gen (asr) gate)]
       (out 0 (* mix env amp))))

Important:

  • Overtone doesn’t implement the ‘range’ method yet and lin-lin had to be used instead (lin-exp for exprange)
  • Some UGens default to ar and some to kr if not explicitly specified – might cause some pain when you don’t realize this

After creating the synth I wanted to make a use of my MIDI keyboard. The following code listens for key pressed event. If the key is pressed the synth frequency is altered. If all the keys are released the synth is muted.

(def ^:dynamic mysynth (hoooover))
(def cnt (atom 0))

(on-event [:midi :note-on]
          (fn [e]
            (let [note (:note e)
                  vel  (:velocity e)]
              (ctl (var-get #'mysynth) :gate 1 :freq (midi->hz note))
              (swap! cnt inc)))
          ::keyboard-pressed)

(on-event [:midi :note-off]
          (fn [e]
            (let [note (:note e)
                  vel  (:velocity e)]
              (swap! cnt dec)
              (if (zero? @cnt) (ctl (var-get #'mysynth) :gate 0))))
          ::keyboard-up)

Leave a Reply

Your email address will not be published.