# 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.rkt` and 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: ```sh 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: ```sh 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: ```text 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: ```racket (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: ```racket (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`: ```sh 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: ```text 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: ```text stdin command channel stdout reply channel stderr event channel ``` The remote worker is normally started as: ```sh 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. SSH, the remote Racket command and the remote module are configured in `racket-audio.ini`. The public `make-audio-player` API only needs the remote host and, when necessary, base path replacements. Example: ```racket (define player (make-audio-player cb-state cb-eof #:remote-host "nas" #:replace-base-paths (list (cons "/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`.