racket-audio
Integration of common audio libraries in Racket.
The package contains decoder, player and encoder bindings. Playback uses the
existing audio player modules. Encoding is provided by audio-encoder.rkt with
Opus and FLAC backends.
Native dependencies
For playback and decoding, install the native libraries used by the selected backends:
- libao
- libFLAC
- mpg123
- FFmpeg libraries, including libavutil, libavcodec and libavformat
For encoding, also install:
- libopusenc
- libopus
- libogg
- TagLib with the C binding, usually provided as
taglib/taglib_c - libsoxr, used by
resampler.rktand encoder-side PCM sample-rate conversion
The Opus encoder backend uses libopusenc directly. The FLAC encoder backend
uses libFLAC directly. FLAC sample-rate conversion uses resampler.rkt, backed by libsoxr. Metadata and cover-art copying use the TagLib wrapper; the
public taglib.rkt API also supports read-write tag editing.
Debian / Ubuntu
On Debian-like systems, install the runtime and development packages for the selected backends. A typical full setup is:
sudo apt install \
libao-dev \
libflac-dev \
libmpg123-dev \
ffmpeg \
libavutil-dev libavcodec-dev libavformat-dev libswresample-dev \
libogg-dev libopus-dev libopusenc-dev libopusfile-dev \
libsoxr-dev libtag1-dev
For Opus encoding, libopusenc-dev is required. For Opus decoding through
opusfile-decoder.rkt, install libopusfile-dev as well.
macOS
Using Homebrew, install the native libraries before using the package:
brew install libao
brew install flac
brew install mpg123
brew install ffmpeg
brew install opus
brew install libopusenc
brew install libsoxr
brew install taglib
Some Homebrew installations provide FFmpeg as ffmpeg; older local setups may
use ffmpeg-full.
Windows
On Windows, the package downloader fetches the native DLL bundle from the
Codeberg racket-sound-lib release area. The current bundle URL pattern is:
https://codeberg.org/hnmdijkema/racket-sound-lib/releases/download/1-1-2/windows-x86_64.zip
The archive is installed below Racket's addon directory by
download-soundlibs.
Encoder examples
Encode to Opus:
(require "audio-encoder.rkt")
(audio-encode "input.flac"
"output.opus"
(hash 'bitrate 224000
'vbr? #t
'complexity 10)
#:encoder 'opus)
Encode 96 kHz FLAC to 48 kHz FLAC:
(audio-encode "input-96k.flac"
"output-48k.flac"
(hash 'sample-rate 48000
'bits-per-sample 24
'compression-level 8)
#:encoder 'flac)
A small test wrapper is available in encoder-test.rkt:
racket encoder-test.rkt --encoder opus --input input.flac --output output.opus --bitrate-kbps 224
racket encoder-test.rkt --encoder flac --input input-96k.flac --output output-48k.flac --sample-rate 48000
Placed player stdio mode
The placed player can also run as a standard-port worker. In that mode the three existing logical channels are mapped to standard streams:
stdin command channel
stdout reply channel
stderr event channel
Because stdout and stderr are protocol streams in this mode, ordinary display
and log output is redirected. By default, placed-player/stdio appends such
output to a log file below Racket's standard cache directory, for example
~/.cache/racket/racket-audio/placed-audio-player-stdio.log on many Unix-like
systems. Pass #:log-file #f to discard ordinary output, or pass a path to
choose a different log file.
Remote placed player over SSH
The placed player can also be started as a remote subprocess over SSH. In this mode the existing three logical player channels are kept separate:
stdin command channel
stdout reply channel
stderr event channel
The remote worker is normally started as:
racket -l racket-audio/audio-placed-player -- --stdio
The worker redirects ordinary logging to a cache log file so that stdout and
stderr remain serialized protocol streams. On Unix-like systems the SSH
launcher defaults to ssh -T -q. On Windows it prefers PuTTY plink.exe or
plink with -batch -T, and falls back to OpenSSH ssh.exe/ssh when PuTTY
is not present. These defaults can be overridden with the #:ssh-program,
#:ssh-options, #:remote-racket, #:remote-module, and #:remote-command
arguments to make-audio-player.
Example:
(define player
(make-audio-player cb-state cb-eof
#:remote-host "nas"
#:remote-path-map
(list (list "/muziek" "/volume1/music"))))
(audio-play! player "/muziek/klassiek/track.flac")
The remote host must be able to read the translated path. In the example above,
the remote worker receives /volume1/music/klassiek/track.flac.