rockbox_ex_ffi (Elixir)

Copy Markdown View Source

Hex.pm Hex Docs Elixir Erlang/OTP NIF License

Elixir bindings for the Rockbox DSP, metadata, and playback engine, via an erl_nif shim over the librockbox_ffi C ABI.

Setup

The NIF links the Rust static archive (target/release/librockbox_ffi.a); mix compile builds it automatically through elixir_make (the Makefile runs cargo build --release -p rockbox-ffi first if the archive is missing).

cd bindings/elixir
mix deps.get
mix compile
mix test

Requires OTP 27+ (uses the built-in :json module — no jason dependency).

Generate the API docs locally with ExDoc:

mix docs        # -> doc/index.html

Published docs live at https://hexdocs.pm/rockbox_ex_ffi/.

Usage

# --- metadata ---
{:ok, meta} = Rockbox.Metadata.read("song.flac")
meta.artist       # "…"
meta.duration_ms  # 122324
Rockbox.Metadata.probe("track.opus")   # "Opus"

# --- DSP (interleaved stereo int16 binary) ---
d = Rockbox.Dsp.new(44_100)
Rockbox.Dsp.eq_enable(d, true)
Rockbox.Dsp.set_eq_band(d, 0, 60, 0.7, 3.0)
Rockbox.Dsp.set_replaygain(d, 0, true, 0.0)          # 0 = track (DSP-native)
Rockbox.Dsp.set_replaygain_gains(d, -6.02, nil, nil, nil)
out = Rockbox.Dsp.process(d, pcm_binary)             # int16 LE in/out

# --- playback (needs an output device) ---
p = Rockbox.Player.new(volume: 0.8, crossfade_mode: 5)   # 5 = always
Rockbox.Player.set_replaygain(p, 1, 0.0, true)           # 1 = track (player)
Rockbox.Player.set_queue(p, ["a.flac", "b.mp3"])
Rockbox.Player.play(p)
Rockbox.Player.status(p)   # %{state: "playing", index: 0, ...}

Handles (Rockbox.Dsp / Rockbox.Player) are NIF resources freed by the BEAM garbage collector — no explicit close.

Two ReplayGain encodings

The DSP and player use different mode integers (a quirk of the C ABI):

Shared NIF

c_src/rockbox_ffi_nif.c and src/rockbox_ffi_nif.erl are shared verbatim with the Gleam binding (bindings/gleam/).