main.rkt
#lang racket/base

(require 
 (prefix-in ao: "ffi.rkt")
 (prefix-in sf: "sample-format-struct.rkt")
 srfi/8)

(ao:initialize)
(define driver (make-parameter (ao:default-driver-id)))

(define (with-driver-p name proc)
  (parameterize
      ((driver (ao:driver-id name)))
    (when (< driver 0)
      (error "Not a driver name, see http://xiph.org/ao/doc/drivers.html"))
    (proc)))

(define-syntax-rule (with-driver name body ...)
  (with-driver-p name (λ () body ...)))

(define (build-options in-options)
  (let loop ((options #f) (in-options in-options))
    (if (null? in-options)
        options
        (receive (result options) (apply ao:append-option options in-options)
          (loop options (cdr in-options))))))

(define monaural #"M")

(define default-sample-format (sf:make #x10 8000 1 ao:big-endian monaural))

(define filename (make-parameter "out.au"))

(define (open #:type (type 'live) #:options (options null) #:format (format default-sample-format))
  (let ((format (ao:build-sample-format format))
        (options (build-options options)))
    (display format)(newline)
    (if (eq? type 'live)
       (ao:open-live (driver) format options)
       (ao:open-file (driver) (filename) #t format options))))

(define (play device samples)
  (when (not (ao:play device samples))
    (error "ao-play failedd")))

(define close ao:close)

(provide open play close driver filename
         monaural
         (rename-out
          (ao:big-endian big-endian)
          (ao:little-endian little-endian)
          (ao:native-endian native-endian)))