anchor.diff:  (defvar *sink-cvar* (mezzano.supervisor:make-condition-variable "Sound output sink cvar"))
   
   (defvar *master-volume* 1.0)
  +
  +(defun master-volume ()
  +  *master-volume*)
  +
  +(defun (setf master-volume) (value)
  +  (check-type value single-float)
  +  (setf *master-volume* value))
   
   (defun mix (dest source volume &key (start1 0) end1 (start2 0) end2)
     (unless end1 (setf end1 (length dest)))
  
positive.code:   (push device *cards*)
    (mezzano.supervisor:make-thread
     (lambda () (sound-worker device))
     :name (format nil "Sound worker for ~S" device)))
  
  (defun make-sound-output-sink (&key (buffer-duration 0.1) (volume 1.0))
    (make-instance 'sound-output-sink
                   :volume volume
                   ;; 100ms at 44.1khz, 2 channels.
                   :buffer (make-array (* (truncate (* 44100 buffer-duration)) 2)
                                       :element-type 'single-float)
                   :buffer-empty t
  
negative.code: (defun copy-into-sink (sink samples start end)
    (let* ((buffer (buffer sink))
           (buffer-size (length buffer))
           (total-copied 0)
           (elements-consumed 0))
      (when (and (not (buffer-empty sink))
                 (eql (buffer-head sink) (buffer-tail sink)))
        ;; Buffer is full.
        (return-from copy-into-sink 0))
      (when (>= (buffer-tail sink) (buffer-head sink))
        ;; Head behind tail, copy to end of sink buffer.
        (let ((n-to-copy (min (/ (- end start) (elements-per-sample (sink-format sink)))
                              (- buffer-size (buffer-tail sink)))))
          (unless (eql n-to-copy 0)
            (multiple-value-bind (n-samples-sourced
                                  n-elements-consumed)
                (transcode (sink-format sink)
                           buffer samples
                           :start1 (buffer-tail sink)
                           :end1 (+ (buffer-tail sink) n-to-copy)
                           :start2 start)
              (incf start n-elements-consumed)
              (incf total-copied n-samples-sourced)
              (incf elements-consumed n-elements-consumed)
              (setf (buffer-tail sink) (rem (+ (buffer-tail sink) n-samples-sourced)
                                            buffer-size))
              (unless (eql n-samples-sourced 0)
                (setf (buffer-empty sink) nil))))))
      (when (< (buffer-tail sink) (buffer-head sink))
        ;; Tail behind head, copy to head.
        (let ((n-to-copy (min (/ (- end start) (elements-per-sample (sink-format sink)))
                              (- (buffer-head sink) (buffer-tail sink)))))
          (unless (eql n-to-copy 0)
            (multiple-value-bind (n-samples-sourced
                                  n-elements-consumed)
                (transcode (sink-format sink)
                           buffer samples
                           :start1 (buffer-tail sink)
                           :end1 (+ (buffer-tail sink) n-to-copy)
                           :start2 start)
              (incf start n-elements-consumed)
              (incf total-copied n-samples-sourced)
              (incf elements-consumed n-elements-consumed)
              (setf (buffer-tail sink) (rem (+ (buffer-tail sink) n-samples-sourced)
                                            buffer-size))
              (unless (eql n-samples-sourced 0)
                (setf (buffer-empty sink) nil))))))
      (values total-copied
              elements-consumed)))
  
  (defun output-sound (samples sink &key (start 0) end)
    (check-type sink sound-output-sink)
    (check-type samples (array * (*)))
    (setf end (or end (length samples)))
    (assert (<= 0 start end (length samples)))
    (when (eql (- end start) 0)
      (return-from output-sound))
    (mezzano.supervisor:with-mutex (*sink-lock*)
      (let ((offset start))
        (loop
           (when (buffer-empty sink)
             ;; Buffer is currently empty, sink is not live.
             (assert (not (member sink *sinks*)))
             (push sink *sinks*))
           ;; Fill the buffer as much as possible.
           (multiple-value-bind (total-samples-copied
                                 total-elements-consumed)
               (copy-into-sink sink samples offset end)
             (incf offset total-elements-consumed)
             (when (not (eql total-samples-copied 0))
               (mezzano.supervisor:condition-notify *sink-cvar* t))
             (when (>= offset end)
               (return))
             ;; Buffer must be full now.
             (assert (eql (buffer-tail sink) (buffer-head sink)))
             ;; Wait for the buffer to be consumed.
             (mezzano.supervisor:condition-wait *sink-cvar* *sink-lock*))))))
  
  (defun flush-sink (sink)
    "Drop all samples in SINK's internal buffer, returning the number of samples dropped."
    (check-type sink sound-output-sink)
    (mezzano.supervisor:with-mutex (*sink-lock*)
      (if (buffer-empty sink)
          0
          (let* ((head (buffer-head sink))
                 (tail (buffer-tail sink))
                 (size (length (buffer sink)))
                 (n-samples (if (>= head tail)
                                (+ (- size head) tail)
                                (- tail head))))
            (setf (buffer-head sink) 0
                  (buffer-tail sink) 0
                  (buffer-empty sink) t)
            n-samples))))
  