 
 (defn bus?
   [b]
-  (and (associative? b)
-       (or (isa? (type b) ::bus))))
+  (or (number? b)
+      (and (associative? b)
+       (or (isa? (type b) ::bus)))))
+
+(defn- bus-id
+  [b]
+  (if (number? b)
+    b
+    (:id b)))
 
 ; TODO: In order to allocate multi-channel busses we actually need to
 ; allocate multiple, adjacent busses, which the current bitset based

(ns overtone.sc.bus
  (:use [overtone.sc.machinery defaults allocator]
        [overtone.sc server]))

;; ## Busses

;(on-sync-event :reset reset-busses ::reset-busses)

(defn bus-set!
  "Takes a list of control bus indices and values and sets the buses to those values.
  Modifies bus(ses) in place on the server.

  (bus-set! my-bus 3) ;=> Sets my-bus to the value 3"
  [bus val]
  (assert (bus? bus))
  (snd "/c_set" (bus-id bus) (double val)))

(defn bus-get
  "Get the current value of a control bus."
  [bus]
  (assert (bus? bus))
  (let [p (server-recv "/c_set")]
    (snd "/c_get" (bus-id bus))
    (try
      (second (:args (deref! p)))
      (catch TimeoutException t
        :timeout))))

(defn bus-set-range!
  "Set a range of consecutive control busses to the supplied values."
  [bus start len vals]
  (assert (bus? bus))
  (apply snd "/c_setn" (bus-id bus) start len (floatify vals)))

(defn bus-get-range
  "Get a range of consecutive control bus values."
  [bus len]
  (assert (bus? bus))
  (let [p (server-recv "/c_setn")]
    (snd "/c_getn" (bus-id bus) len)
    (try
      (drop 2 (:args (deref! p)))
      (catch TimeoutException t
        :timeout))))
