                     n-frames start-frame 0)
     :done))
 
+(defrecord BufferOutStream [id size n-channels rate allocated-on-server path open?])
+
 (defn buffer-stream
   "Returns a buffer-stream which is similar to a regular buffer but may be used
   with the disk-out ugen to stream to a specific file on disk.

          num-samples                (* n-frames n-chans)
          rate-scale                 (/ rate (server-sample-rate))
          duration                   (/ n-frames rate)]
      (with-meta     {:size n-frames
                      :n-channels n-chans
                      :rate rate
                      :n-samples num-samples
                      :rate-scale rate-scale
                      :duration duration
                      :id id}
        {:type ::buffer-info}))))

(defn buffer
  "Synchronously allocate a new zero filled buffer for storing audio data with
  the specified size and num-channels."
  ([size] (buffer size 1))
  ([size num-channels]
     (let [id   (with-server-self-sync (fn [uid]
                                         (alloc-id :audio-buffer
                                                   1
                                                   (fn [id]
                                                     (snd "/b_alloc" id size num-channels)
                                                     (server-sync uid)))))
           info (buffer-info id)]
       (with-meta
         (merge info
                {:allocated-on-server (atom true)})
         {:type ::buffer}))))

(defn buffer-alloc-read
  "Synchronously allocates a buffer with the same number of channels as the

        {:keys [start size]} arg-map
        buf (buffer-alloc-read path start size)]
    (snd "/b_read" (:id buf) path start -1 0 1)
    (map->BufferInStream
      (assoc buf
        :path path
        :start start
        :open? (atom true)))))

(derive BufferInStream ::buffer-in-stream)
(derive ::buffer-in-stream ::file-buffer)

(defn buffer-in-stream?
