decibri 4.1.0

Cross-platform audio capture, playback, and voice activity detection for Rust
Documentation

Decibri (Rust)

Cross-platform audio capture, playback, and voice activity detection for Rust applications.

crates.io docs.rs License

This is the Rust core of decibri. The same core powers decibri's Python and Node.js packages; see the main README for cross-language context.

Add to Cargo.toml

cargo add decibri

Or directly:

[dependencies]
decibri = "4"

The default feature set (capture, playback, vad, ort-load-dynamic) covers most use cases. See Feature flags below for opt-in or trimmed configurations.

Quick start

The two primary types are Microphone for input and Speaker for output. Each follows the same shape: build a config, construct the object, then start() it to open the device and get a stream.

Capture and detect speech

use std::time::Duration;
use decibri::{Microphone, MicrophoneConfig, SileroVad, VadConfig, DecibriError};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let microphone = Microphone::new(MicrophoneConfig::default())?;
    let stream = microphone.start()?;
    let mut vad = SileroVad::new(VadConfig::default())?;

    loop {
        match stream.next_chunk(Some(Duration::from_millis(100))) {
            Ok(Some(chunk)) => {
                let result = vad.process(&chunk.data)?;
                if result.is_speech {
                    println!("speech @ p={:.2}", result.probability);
                }
            }
            Ok(None) => continue,
            Err(DecibriError::MicrophoneStreamClosed) => break,
            Err(e) => return Err(e.into()),
        }
    }
    Ok(())
}

MicrophoneStream::next_chunk returns a three-state Result: Ok(Some(chunk)) with data, Ok(None) on a timeout while the stream is still open, and Err(DecibriError::MicrophoneStreamClosed) once the stream ends.

Speaker output

use decibri::{Speaker, SpeakerConfig};

let speaker = Speaker::new(SpeakerConfig::default())?;
let stream = speaker.start()?;

// f32 samples in [-1.0, 1.0]; here, one second of silence at 16 kHz mono.
let samples: Vec<f32> = vec![0.0; 16_000];
stream.send(samples)?;
stream.drain(); // block until everything queued has played
stream.stop();  // immediate; discards anything remaining

SpeakerStream::send takes a Vec<f32> of samples in the range [-1.0, 1.0]. drain blocks until the device has finished playing the queue; stop is immediate and discards what remains.

List devices

use decibri::Microphone;

for device in Microphone::devices()? {
    println!("[{}] {}", device.index, device.name);
}

Speaker::devices() is the playback equivalent. The free functions decibri::input_devices() and decibri::output_devices() return the same lists.

Without ONNX Runtime

If you do not need Silero VAD, disable the vad feature to drop the ONNX Runtime dependency entirely.

Feature flags

Flag Default Purpose
capture on Microphone input stream support
playback on Speaker output stream support
vad on Silero voice-activity detection (pulls in ONNX Runtime)
ort-load-dynamic on ONNX Runtime loaded at runtime from a path you control
ort-download-binaries off ONNX Runtime downloaded at build time and embedded

ort-load-dynamic and ort-download-binaries are mutually exclusive; selecting both is a compile error.

Execution-provider passthrough features (off by default; opt in for GPU acceleration on specific platforms): coreml, cuda, directml, rocm. See docs/features.md for the full reference.

Common configurations

Zero-config builds (ONNX Runtime downloaded at cargo build, embedded):

decibri = { version = "4", features = ["ort-download-binaries"], default-features = false }

Add back the other features you want (capture, playback, vad).

Production deployments with a bundled runtime (default; ONNX Runtime loaded at runtime from a path you control):

decibri = "4"

Then either set ORT_DYLIB_PATH=/path/to/libonnxruntime.{so,dylib,dll} before first use, or call ort::init_from(path).commit() at startup. ONNX Runtime initializes exactly once per process; the first successful path wins and later constructions silently reuse it.

Capture and playback without VAD (no ONNX Runtime dependency at all):

decibri = { version = "4", features = ["capture", "playback"], default-features = false }

ONNX Runtime configuration

Under ort-load-dynamic (default), the ONNX Runtime shared library is located at runtime via a VadConfig::ort_library_path, the ORT_DYLIB_PATH environment variable, or a process-wide ort::init_from(...).commit() call. decibri performs a filesystem-level path check before handing the path off, so a missing or wrong-arch library surfaces as DecibriError::OrtPathInvalid rather than hanging on dynamic load.

See the ONNX Runtime linking docs for the full runtime-loading reference.

Fork safety (Linux)

ONNX Runtime initialized in a parent process does not survive fork() cleanly: internal threads, memory pools, and device handles belonging to the parent may misbehave in the child. Python consumers should use multiprocessing.set_start_method('spawn', force=True) before importing decibri. Node.js consumers using child_process or worker_threads are unaffected.

Public API surface

The stable 4.x surface includes:

The common types are re-exported at the crate root, so use decibri::Microphone; works directly. Full API reference: docs.rs/decibri.

Thread safety

All public types are Send and suitable for cross-thread handoff. MicrophoneStream and SpeakerStream are !Sync because they hold a live platform audio stream internally; wrap them in a mutex or move them into a dedicated thread for shared access.

Platform support

Platform Architecture Audio Backend
Windows x64 WASAPI
macOS arm64 (Apple Silicon) CoreAudio
Linux x64 (gnu) ALSA
Linux arm64 (gnu) ALSA

Source builds work on additional targets (Intel macOS, Windows arm64, musl Linux) but are not part of the npm and PyPI binary release matrix. The crate itself has no per-target restriction beyond what the platform audio host supports.

Cross-references

License

Apache-2.0 (c) 2026 Decibri.