       (assoc buf
         :path path
         :open? (atom true))
-      {:type ::buffer-stream})))
-
-(derive ::buffer-stream ::buffer)
-
-(defn buffer-stream?
+      {:type ::buffer-out-stream})))
+
+(derive ::buffer-out-stream ::file-buffer)
+
+(defn buffer-out-stream?
   [bs]
-  (isa? (type bs) ::buffer-stream))
+  (isa? (type bs) ::buffer-out-stream))
 
 (defn buffer-stream-close
   "Close a buffer stream created with #'buffer-stream. Also frees the internal
   buffer. Returns the path of the newly created file."
   [buf-stream]
-  (assert (buffer-stream? buf-stream))
+  (assert (file-buffer? buf-stream))
   (when-not @(:open? buf-stream)
     (throw (Exception. "buffer-stream already closed.")))
 

  ([buf-cue]
     (buffer-cue-pos buf-cue 0))
  ([buf-cue pos]
     (assert (buffer-cue? buf-cue))
     (when-not @(:open? buf-cue)
       (throw (Exception. "buffer-cue is closed.")))
     (let [{:keys [id path]} buf-cue]
       (snd "/b_close" id)
       (snd "/b_read" id path pos -1 0 1))
     buf-cue))

(defn buffer-cue-close
  "Close a buffer stream created with #'buffer-cue. Also frees the internal
  buffer. Returns the path of the streaming file."
  [buf-cue]
  (assert (buffer-cue? buf-cue))
  (when-not @(:open? buf-cue)
    (throw (Exception. "buffer-cue already closed.")))

  (snd "/b_close" (:id buf-cue))
  (buffer-free buf-cue)
  (reset! (:open? buf-cue) false)
  (:path buf-cue))

(defmulti buffer-id type)
(defmethod buffer-id java.lang.Integer [id] id)

  [buf]
  (isa? (type buf) ::buffer))

(defn file-buffer?
  [buf]
  (isa? (type buf) ::file-buffer))

(defn buffer-free
  "Synchronously free an audio buffer and the memory it was consuming."
  [buf]
