overtone/overtone — pull request #47 by neatonk (2011-12-20 01:40:12+00:00)
Title: Re-implement #'metronome using deftype and protocols.

In response to this [discussion] (http://groups.google.com/group/overtone/browse_thread/thread/1ff4171a0ab38e86/85e4bd6b75f4779a?show_docid=5e387c602b2fd1ec), I've a Implemented a new protocol `IMetronome` and a new tecord/class `Metronome` which implements `IMetronome` and `clojure.lang.IFn`. I've modified `#'metronone` to return an instance of this this class. Use like this...

```clj
(def m (metronome 120))
(type m) ;=> overtone.music.rhythm.Metronome

;; IMetronome
(start m) ;=> 1
(start m 10) ;=> 11
(tick m) ;=> 500.0
(beat m) ;=> 14
(beat m 200) ;=> 1.3243412651295E12
(bpm m) ;=> 120
(bpm m 128) ;=> [:bpm 128]
```

Since `Metronome` implements the `clojure.lang.IFn` the old way still works!

```clj
;; clojure.lang.IFn
(m) ;=> 24
(m 200) ;=> 1.32434126506625E12
(m :bpm) ;=> 128
(m :bpm 140) ;=> [:bpm 140]
```

Now `Metronome` can be extended...

```clj
(defprotocol Playable
(play [this]))

(extend-type overtone.music.rhythm.Metronome
Playable
(play [this] (start this)))

(play m) ;=> 1
```