#lang racket/base (require (for-syntax "make-sample-format.rkt") (prefix-in sf: "sample-format.rkt") ffi/unsafe (for-syntax racket/base)) (define lib (ffi-lib "libao" "4")) (define-syntax (define-ao form) (syntax-case form () ((_ name type) (let* ((datum (syntax-e form)) (name (cadr datum)) (name-datum (syntax->datum name)) (type (caddr datum))) (when (not (symbol? name-datum)) (error "The name must be a symbol, got " name-datum)) (let ((c-name (string-append "ao_" (regexp-replace* #rx"-" (symbol->string name-datum) "_")))) (datum->syntax form `(begin (define ,name (get-ffi-obj ,c-name lib ,type)) (provide ,name)) form)))))) (define-ao initialize (_fun -> _void)) (define-ao shutdown (_fun -> _void)) (define-ao default-driver-id (_fun -> _int)) (define-ao driver-id (_fun _string -> _int)) (define-cpointer-type _options) (define-cpointer-type _device) (define _sample_format _gcpointer) (define-ao append-option (_fun (options key value) :: (options : (_ptr io _options/null) = options) (key : _string) (value : _string) -> (result : _int) -> (values (= result 1) options))) (define-ao open-live (_fun _int _sample_format _options/null -> _device)) (define-ao open-file (_fun (id filename overwrite format options) :: (id : _int) (filename : _string) (_int = (if overwrite 1 0)) (format : _sample_format) (options : _options/null) -> _device)) (define-ao play (_fun (device samples) :: (device : _device) (samples : _bytes) (_uint32 = (bytes-length samples)) -> (result : _int) -> (not (= result 0)))) (define-ao close (_fun _device -> (result : _int) -> (= result 1))) (provide (rename-out (sf:build build-sample-format) (sf:little-endian little-endian) (sf:big-endian big-endian) (sf:native-endian native-endian)))