211 lines
6.4 KiB
Racket
211 lines
6.4 KiB
Racket
#lang scribble/manual
|
|
|
|
@(require racket/base
|
|
(for-label racket/base
|
|
"../libao.rkt"))
|
|
|
|
@title{libao}
|
|
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
|
|
|
|
@defmodule["libao.rkt"]
|
|
|
|
This module provides a small high-level interface to an asynchronous
|
|
audio output backend. It opens a live output device, queues audio
|
|
buffers for playback, reports playback position, supports pause and
|
|
buffer clearing, and exposes a small set of validation predicates.
|
|
|
|
The central value is an @racket[ao-handle], created by
|
|
@racket[ao-open-live]. An @racket[ao-handle] stores the playback
|
|
configuration together with a native asynchronous player handle.
|
|
|
|
@section{Audio handles}
|
|
|
|
@defproc[(ao-handle? [v any/c]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[v] is an @racket[ao-handle] value, and
|
|
@racket[#f] otherwise.
|
|
}
|
|
|
|
@defproc[(ao-valid? [handle ao-handle?]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[handle] still has a native asynchronous
|
|
player, and @racket[#f] otherwise.
|
|
|
|
A handle becomes invalid after @racket[ao-close], or when
|
|
@racket[ao-open-live] failed to create the native player.
|
|
}
|
|
|
|
@section{Validation predicates}
|
|
|
|
@defproc[(ao-valid-bits? [bits any/c]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[bits] is one of @racket[8],
|
|
@racket[16], @racket[24], or @racket[32], and @racket[#f] otherwise.
|
|
}
|
|
|
|
@defproc[(ao-valid-rate? [rate any/c]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[rate] is one of the sample rates
|
|
accepted by this module, and @racket[#f] otherwise.
|
|
|
|
The accepted rates are:
|
|
|
|
@itemlist[#:style 'compact
|
|
@item{@racket[8000], @racket[11025], @racket[16000], @racket[22050],}
|
|
@item{@racket[44100], @racket[48000], @racket[88200], @racket[96000],}
|
|
@item{@racket[176400], @racket[192000], @racket[352800], and}
|
|
@item{@racket[384000].}]
|
|
}
|
|
|
|
@defproc[(ao-valid-channels? [channels any/c]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[channels] is an integer greater than or
|
|
equal to @racket[1], and @racket[#f] otherwise.
|
|
}
|
|
|
|
@defproc[(ao-valid-format? [format any/c]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[format] is one of
|
|
@racket['little-endian], @racket['big-endian], or
|
|
@racket['native-endian], and @racket[#f] otherwise.
|
|
}
|
|
|
|
@defproc[(ao-supported-music-format? [format any/c]) boolean?]{
|
|
|
|
Returns @racket[#t] if @racket[format] is one of @racket['flac],
|
|
@racket['mp3], or @racket['ao], and @racket[#f] otherwise.
|
|
|
|
This value is used by @racket[ao-play] to describe the format of the
|
|
buffer being queued.
|
|
}
|
|
|
|
@section{Opening and closing}
|
|
|
|
@defproc[(ao-open-live [bits ao-valid-bits?]
|
|
[rate ao-valid-rate?]
|
|
[channels ao-valid-channels?]
|
|
[byte-format ao-valid-format?])
|
|
ao-handle?]{
|
|
|
|
Creates an audio output handle for live playback.
|
|
|
|
The handle stores the given sample size, sample rate, channel count,
|
|
and byte format. It then tries to create a native asynchronous player.
|
|
|
|
If the native player is created successfully, the returned handle is
|
|
valid. If player creation fails, the function still returns an
|
|
@racket[ao-handle], but that handle is marked closed and is not valid
|
|
for playback.
|
|
|
|
A finalizer is registered for the handle and calls @racket[ao-close]
|
|
when the handle is reclaimed.
|
|
}
|
|
|
|
@defproc[(ao-close [handle ao-handle?]) void?]{
|
|
|
|
Stops playback for @racket[handle] and releases the native player
|
|
reference stored in the handle.
|
|
|
|
If the handle already has no native player, this procedure has no
|
|
effect.
|
|
}
|
|
|
|
@section{Playback}
|
|
|
|
@defproc[(ao-play [handle ao-handle?]
|
|
[music-id integer?]
|
|
[at-time-in-s number?]
|
|
[music-duration-s number?]
|
|
[buffer any/c]
|
|
[buf-len integer?]
|
|
[buf-type ao-supported-music-format?])
|
|
void?]{
|
|
|
|
Queues audio data for asynchronous playback.
|
|
|
|
The @racket[music-id] argument identifies the music stream associated
|
|
with the buffer. The arguments @racket[at-time-in-s] and
|
|
@racket[music-duration-s] describe the position and duration, in
|
|
seconds, associated with the buffer. The arguments @racket[buffer] and
|
|
@racket[buf-len] provide the audio data and its length. The
|
|
@racket[buf-type] argument specifies the buffer format.
|
|
|
|
The buffer description passed to the native layer is completed with the
|
|
sample size, sample rate, channel count, and byte format stored in
|
|
@racket[handle].
|
|
|
|
If @racket[handle] is not valid, this procedure raises an exception.
|
|
}
|
|
|
|
@defproc[(ao-pause [handle ao-handle?]
|
|
[pause boolean?])
|
|
void?]{
|
|
|
|
Pauses or resumes asynchronous playback for @racket[handle].
|
|
|
|
A true value pauses playback. @racket[#f] resumes playback.
|
|
}
|
|
|
|
@defproc[(ao-clear-async [handle ao-handle?]) void?]{
|
|
|
|
Clears buffered asynchronous playback data for @racket[handle].
|
|
}
|
|
|
|
@section{Playback state}
|
|
|
|
@defproc[(ao-at-second [handle ao-handle?]) number?]{
|
|
|
|
Returns the current playback position, in seconds, as reported by the
|
|
native asynchronous player.
|
|
}
|
|
|
|
@defproc[(ao-at-music-id [handle ao-handle?]) integer?]{
|
|
|
|
Returns the music identifier currently reported by the native
|
|
asynchronous player.
|
|
}
|
|
|
|
@defproc[(ao-music-duration [handle ao-handle?]) number?]{
|
|
|
|
Returns the duration of the current music stream, in seconds, as
|
|
reported by the native asynchronous player.
|
|
}
|
|
|
|
@defproc[(ao-bufsize-async [handle ao-handle?]) integer?]{
|
|
|
|
Returns the current buffered size in bytes for the asynchronous player.
|
|
}
|
|
|
|
@section{Volume control}
|
|
|
|
@defproc[(ao-set-volume! [handle ao-handle?]
|
|
[percentage number?])
|
|
void?]{
|
|
|
|
Sets the playback volume for @racket[handle].
|
|
|
|
If @racket[percentage] is an exact integer, it is converted to an
|
|
inexact number before it is passed to the native layer.
|
|
}
|
|
|
|
@defproc[(ao-volume [handle ao-handle?]) number?]{
|
|
|
|
Returns the current playback volume as reported by the native
|
|
asynchronous player.
|
|
}
|
|
|
|
@section{Notes}
|
|
|
|
This module is a higher-level wrapper around the asynchronous FFI layer.
|
|
It stores the playback configuration in the handle, and reuses that
|
|
configuration for each call to @racket[ao-play].
|
|
|
|
The module does not expose the handle fields directly. The public API
|
|
is intentionally small: create a handle, queue buffers, inspect
|
|
position and buffer state, pause or clear playback, adjust volume, and
|
|
close the handle.
|
|
|
|
A typical usage pattern is to open one live handle for a given stream
|
|
format, queue decoded buffers with @racket[ao-play], and query the
|
|
playback position with @racket[ao-at-second] while playback proceeds
|
|
asynchronously. |