rockbox_ffi_nif is the common native layer for every binding that runs on
the BEAM. The Elixir (rockbox_ex_ffi) and
Gleam (rockbox_ffi) packages both depend on it instead of
vendoring their own copy of the C shim and loader — the ergonomic wrappers live
in those packages.
Requires OTP 27+ (JSON is decoded with the built-in json module). The Hex
package ships only a checksum manifest; the loader’s -on_load hook downloads
the matching prebuilt .so for your platform on first use (see
NIF delivery).
Every function is a raw NIF: strings and paths are UTF-8 binaries,
*_json
functions return raw JSON binaries (decode with OTP 27’s json module), and
handles (RbDecoder, RbPlayer, RbDsp) are opaque reference()s freed by
the GC — there is no explicit close.
Read metadata
Decode a file to PCM
decoder_next_chunk/1 hands back interleaved-stereo little-endian int16 PCM
until it returns nil at end of track.
Run PCM through the DSP pipeline
Play a queue
A player owns a live audio device and a background engine thread; dropping the last reference to the handle stops playback.player_set_eq_band/5, player_set_tone/5, player_set_crossfade/7,
player_set_replaygain/4, player_set_balance/2 / player_balance/1, and more
(see the module docs).
API
- Handles (
RbDecoder,RbDsp,RbPlayer) are NIF resources freed by the BEAM garbage collector — no explicit close. - PCM crosses the boundary as an int16 LE binary.
- Rich values (
*_json) come back as raw JSON binaries — decode with OTP 27’s built-injsonmodule. - The DSP chain mirrors Rockbox’s own; see the official Rockbox sound-settings manual for what each control does.
NIF delivery
The compiled NIF statically links the Rustlibrockbox_ffi.a, making it a
multi-megabyte shared object — too large to bundle in a Hex tarball. So the Hex
package ships only the checksum manifest, and rockbox_ffi_nif.erl’s -on_load
hook downloads the matching rockbox_ffi_nif-<triple>.so from the named GitHub
release into the user cache on first use, verifying it against the manifest
sha256. Both the Elixir and Gleam bindings get their native code the same way.
Prebuilt targets: aarch64-apple-darwin, x86_64-apple-darwin,
aarch64-linux-gnu, x86_64-linux-gnu, x86_64-unknown-freebsd,
x86_64-unknown-netbsd. Other platforms build from source.
Local development
Inside a full monorepo checkout (needs the Cargo workspace +include/ header):
.so via a path
dependency on ../erlang — the loader prefers a local priv/*.so over any
cached download.
Docs
Read the published module docs at hexdocs.pm/rockbox_ffi_nif, or generate them locally withrebar3 ex_doc.