              (concat named [(first names) (first args)]))
       named)))
 
-(defn synth-player [sname arg-names]
+(defn synth-player 
+  "Returns a player function for a named synth.  Used by (synth ...) internally, but can be
+  used to generate a player for a pre-compiled synth.  The function generated will accept two
+  optional arguments that must come first, the :target and :position (see the node function docs).
+
+  (foo)
+  (foo :target 0 :position :tail)
+
+  or if foo has two arguments:
+  (foo 440 0.3)
+  (foo :target 0 :position :tail 440 0.3)
+  at the head of group 2:
+  (foo :target 2 :position :head 440 0.3)
+
+  These can also be abbreviated:
+  (foo :tgt 2 :pos :head)
+  "
+  [sname arg-names]
   (fn [& args]
-    (let [[args sgroup] (if (= :target (first args))
+    (let [[args sgroup] (if (or (= :target (first args))
+                                (= :tgt    (first args)))
                           [(drop 2 args) (second args)]
                           [args (get @synths* sname)])
-          controller (partial node-control sgroup)
-          player (partial node sname :target sgroup)
+          [args pos]    (if (or (= :position (first args))
+                                (= :pos      (first args)))
+                          [(drop 2 args) (second args)]
+                          [args :tail])
+          controller    (partial node-control sgroup)
+          player        (partial node sname :target sgroup :position pos)
           [tgt-fn args] (if (= :ctl (first args))
                           [controller (rest args)]
                           [player args])

(defn buffer? [buf]
  (= (type buf) ::buffer))

(defn buffer-free
  "Free an audio buffer and the memory it was consuming."
  [buf]
  (assert (buffer? buf))
  (free-id :audio-buffer (:id buf))
  (snd "/b_free" (:id buf)))


(defonce server*        (ref nil))
(defonce status*        (ref :no-audio))
(defonce synths*        (ref nil))
(defonce sc-world*      (ref nil))

; Server limits
(defonce MAX-NODES 1024)
