Other engines & native
The C ABI and Rust crate behind every SDK — for custom engines, engine mods and extensions, dedicated-server bots and tooling.
What you get#
aurix-client is the native client the Unreal, Unity (desktop/mobile) and Godot SDKs sit on. It exposes a C ABI (aurix_client.h, a C++ header on top) and a Rust crate; it speaks the AURX media protocol over UDP and QUIC to the node with a TLS tunnel fallback, does Opus encode/decode, jitter buffering, VAD, echo cancellation / noise suppression / AGC and 3D mixing, and hands you PCM in and out.
Prebuilt libraries for Windows (MSVC x64), Linux x86_64 / arm64, macOS (x86_64 / arm64) and Android are in every release (aurix-client-1.13.0-<target>) together with the header.
Minimal C integration#
#include "aurix_client.h"
struct AurixClientConfig cfg;
aurix_client_config_default(&cfg);
cfg.ws_url = endpoint_ws_url; // endpoint.ws_url from your backend's /v1/tokens call
cfg.token = token;
struct AurixClient *c = aurix_client_create(&cfg);
aurix_client_connect(c); // asynchronous: wait for AURIX_EVENT_SESSION_READY
struct AurixUuid channel; aurix_uuid_parse(channel_id_text, &channel);
uint64_t req; aurix_client_join_channel(c, &channel, NULL, &req);
// main loop
for (struct AurixEvent *ev; (ev = aurix_client_poll_event(c)); aurix_event_free(ev)) { /* join/leave/speaking/errors */ }
// audio thread (48 kHz float): microphone in, mixed output out
aurix_client_push_capture_f32(c, pcm_in, frames, 48000, 1);
aurix_client_mix_output_f32(c, pcm_out, frames, 2);
// positional channels: your own and (for the server-side mixer) other players' positions
aurix_client_update_positions(c, &channel, positions, count); // struct AurixPosition { user_id, x,y,z, forward, up }
aurix_client_destroy(c);Audio functions may be called from a real-time thread concurrently with control calls; events are freed with aurix_event_free. For engine-side spatialisation pull each talker separately with aurix_client_pull_participant_f32 instead of mix_output. Two complete samples (C and C++) live in crates/aurix-client/examples and are built and run by the engine's test suite.
Rust#
The crate is not on crates.io; depend on the repository tag:
[dependencies]
aurix-client = { git = "https://github.com/aurix-voice/aurix", tag = "v1.13.0" }use aurix_client::{Client, ClientConfig, Event};
use std::time::Duration;
let client = Client::new(ClientConfig::new(ws_url, token))?;
client.connect()?;
loop {
match client.wait_event(Duration::from_millis(100)) {
Some(Event::SessionReady(_)) => { client.join_channel(channel_id, None)?; }
Some(Event::ChannelJoined { participants, .. }) => println!("{} others", participants.len()),
Some(Event::Disconnected { .. }) => break,
_ => {}
}
// audio thread: client.push_capture_f32(mic_pcm, rate, channels);
// client.mix_output_f32(speaker_pcm, 2);
}Bots and headless clients#
The same crate drives server-side bots (announcers, music, recording consumers). The rooms example in the engine repository runs a native bot that streams audio files into a channel — a good template for a radio station or a test signal generator.
Scripting languages#
For languages without a native bridge (Lua in game servers, Python tooling) talk to the cell's REST API directly — tokens, channels, moderation and analytics are plain HTTPS, and typed server SDKs exist for Node, Python, Go and C#. Voice itself always needs a native or browser client.
Channel patterns#
| Pattern | Channels per player | Notes |
|---|---|---|
| Co-op / squad | one team | mute = PTT off; nothing positional |
| Shooter with proximity | positional (shard) + team (squad) | transmit on the team channel by default, hold a key to speak locally |
| Open world | positional (shard), optional whisper for direct calls | roster_radius keeps the participant list small |
| Event / stage | audience-shaped channel, hosts with priority | thousands of listeners, a few speakers |
The transmit channel is a client-side choice: join several, send to one, hear all with receive. Positional audio needs positions roughly 10 times a second; between updates the node interpolates.
Latency and quality#
Expect 30–60 ms mouth-to-ear on the same continent over UDP/QUIC, more over TURN. Opus runs at 32 kbps with DTX by default; the spending ladder may lower it to 16 kbps when your forecast exceeds the limit. Server-side noise suppression is on by default and costs nothing on the client.
Testing without a full build#
- Two players: the rooms demo in a browser plus your build — they share a cell, so a token from your backend joins the same channel by name.
- Mic path: an
echochannel plays your own voice back through the real pipeline. - Network: block UDP on one machine and watch the client fall back to the TLS tunnel (
MEDIA_PATH_CHANGEDevent).
Troubleshooting#
| Symptom | Check |
|---|---|
| connected, no audio | capture pushed? channel grant speak/receive? OS microphone permission? |
| audio but no spatialisation | positions sent on the positional channel id, not the team channel |
QUOTA_EXCEEDED on connect | plan concurrency cap or spending ladder step 4 — see Spending limit |