126 lines
3.7 KiB
Racket
126 lines
3.7 KiB
Racket
#lang racket/base
|
|
|
|
(require (prefix-in fin: finalizer)
|
|
(prefix-in ffi: "libao-async-ffi.rkt")
|
|
ffi/unsafe
|
|
ffi/unsafe/custodian
|
|
data/queue
|
|
"private/utils.rkt"
|
|
)
|
|
|
|
(provide ao-open-live
|
|
ao-play
|
|
ao-close
|
|
ao-at-second
|
|
ao-music-duration
|
|
ao-bufsize-async
|
|
ao-clear-async
|
|
ao-pause
|
|
ao-valid?
|
|
)
|
|
|
|
(define device-number 1)
|
|
|
|
(define-struct ao-handle (handle-num
|
|
[bits #:auto #:mutable]
|
|
[bytes-per-sample #:auto #:mutable]
|
|
[byte-format #:auto #:mutable]
|
|
[channels #:auto #:mutable]
|
|
[rate #:auto #:mutable]
|
|
[async-player #:auto #:mutable]
|
|
[closed #:auto #:mutable]
|
|
)
|
|
#:auto-value #f
|
|
)
|
|
|
|
|
|
(define (bytes-for-bits bits)
|
|
(/ bits 8))
|
|
|
|
(define (ao-open-live bits rate channels byte-format)
|
|
(let ((handle (make-ao-handle device-number)))
|
|
|
|
(fin:register-finalizer handle
|
|
(lambda (handle)
|
|
(ao-close handle)))
|
|
|
|
(set-ao-handle-bits! handle bits)
|
|
(set-ao-handle-bytes-per-sample! handle (bytes-for-bits bits))
|
|
(set-ao-handle-byte-format! handle byte-format)
|
|
(set-ao-handle-channels! handle channels)
|
|
(set-ao-handle-rate! handle rate)
|
|
|
|
(info-sound "ao-open-live ~a ~a ~a ~a" bits rate channels byte-format)
|
|
|
|
(let ((player (ffi:ao_create_async bits rate channels byte-format)))
|
|
(set-ao-handle-async-player! handle player)
|
|
(if (eq? player #f)
|
|
(begin
|
|
(err-sound "ao-open-live - cannote create player")
|
|
(set-ao-handle-closed! handle #t)
|
|
handle)
|
|
(begin
|
|
(info-sound "ao-open-live - created player")
|
|
(set-ao-handle-closed! handle #f)
|
|
handle
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
(define (ao-close handle)
|
|
(unless (eq? (ao-handle-async-player handle) #f)
|
|
(info-sound "ao-close - closing handle")
|
|
(ffi:ao_stop_async (ao-handle-async-player handle))
|
|
(set-ao-handle-async-player! handle #f)
|
|
)
|
|
)
|
|
|
|
(define (ao-valid? handle)
|
|
(not (eq? (ao-handle-async-player handle) #f)))
|
|
|
|
(define (ao-play handle at-time-in-s music-duration-s buffer buf-len buf-type)
|
|
(let* ((bytes-per-sample (ao-handle-bytes-per-sample handle))
|
|
(bits (ao-handle-bits handle))
|
|
(rate (ao-handle-rate handle))
|
|
(channels (ao-handle-channels handle))
|
|
(endianess (ao-handle-byte-format handle))
|
|
(buf-info (ffi:make-BufferInfo_t buf-type bits rate channels endianess))
|
|
)
|
|
;(dbg-sound "ao-play ~a ~a" at-time-in-s music-duration-s)
|
|
(unless (ao-valid? handle)
|
|
(err-sound "Cannot play on an invalid ao-device")
|
|
(error "Cannot play on an invalid ao-device"))
|
|
(ffi:ao_play_async (ao-handle-async-player handle)
|
|
(exact->inexact at-time-in-s)
|
|
(exact->inexact music-duration-s)
|
|
buf-len
|
|
buffer
|
|
buf-info)
|
|
)
|
|
)
|
|
|
|
(define (ao-pause handle pause)
|
|
(dbg-sound "ao-pause ~a" pause)
|
|
(ffi:ao_pause_async (ao-handle-async-player handle) (if (eq? pause #f) 0 1))
|
|
)
|
|
|
|
(define (ao-at-second handle)
|
|
(ffi:ao_is_at_second_async (ao-handle-async-player handle))
|
|
)
|
|
|
|
(define (ao-music-duration handle)
|
|
(ffi:ao_music_duration_async (ao-handle-async-player handle))
|
|
)
|
|
|
|
(define (ao-bufsize-async handle)
|
|
(ffi:ao_bufsize_async (ao-handle-async-player handle))
|
|
)
|
|
|
|
(define (ao-clear-async handle)
|
|
(ffi:ao_clear_async (ao-handle-async-player handle))
|
|
)
|
|
|
|
|