Skip to main content

Overview

This is the core client API implemented in Rust and exported to native C libraries. These libraries are the low-level building blocks for our high-level SDKs like Unity SDK or Unreal SDK.

Please check out our public Github repository for source code and a CLI application example.

Usage​

Quick Start​

The Core SDK now uses a Connection Pool to manage connections efficiently. The following example demonstrates how to initialize the SDK, create a connection pool, and join a room.

#include <stdio.h>
#include "odin.h"

int main(int argc, const char *argv[])
{
// 1. Initialize the SDK
odin_initialize(ODIN_VERSION);

// 2. Configure the Connection Pool
// 'on_rpc' is the callback for receiving events from the server
OdinConnectionPoolSettings settings = {
.on_datagram = NULL,
.on_rpc = NULL,
.user_data = NULL
};

OdinConnectionPool *pool;
odin_connection_pool_create(settings, &pool);

// 3. Create a room and join
OdinRoom *room;
odin_room_create(pool, "<SERVER_URL>", "<TOKEN>", &room);

// ... Main loop or application logic ...
getchar();

// 4. Cleanup
odin_room_free(room);
odin_connection_pool_free(pool);
odin_shutdown();

return 0;
}

Authentication​

To enter a room, an authentication token is required. ODIN uses signed JSON Web Tokens (JWT). Use the OdinTokenGenerator to create these tokens locally for testing, or generate them on your backend.

OdinTokenGenerator *generator;
odin_token_generator_create("<ACCESS_KEY>", &generator);

char token[512];
// Payload usually contains "rid" (room ID) and "uid" (user ID)
const char *payload = "{\"rid\": \"my-room\", \"uid\": \"user-1\"}";
odin_token_generator_sign(generator, payload, token, sizeof(token));

odin_token_generator_free(generator);
Security Note

Your Access Key is a sensitive credential. Do not embed it in your client-side code in production. Use a backend service to issue tokens.

Event Handling (RPC)​

The ODIN Core SDK uses an event-driven architecture based on RPC (Remote Procedure Calls). Events such as users joining, media starting, or messages received are delivered as MessagePack encoded data to the on_rpc callback defined in your connection pool settings.

To handle these events, you must:

  1. Register an on_rpc callback in OdinConnectionPoolSettings.
  2. Deserialize the bytes payload using a MessagePack library (and/or JSON parser).
  3. Process the event based on its structure.

See Event Structures for a detailed reference of the available event schemas.

void on_rpc(uint64_t room_ref, const uint8_t *bytes, uint32_t bytes_length, void *user_data) {
// 1. Deserialize MessagePack to JSON
// 2. Inspect 'kind' or event type
// 3. Handle logic (e.g., UI updates, stream setup)
}

Audio Talk-Status Events​

For performance-critical talk-status specific updates (Voice Activity Detection), you can register direct callbacks on encoders and decoders using odin_encoder_set_event_callback and odin_decoder_set_event_callback.

void on_decoder_event(OdinDecoder* decoder, OdinAudioEvents events, void* user_data) {
if (events & ODIN_AUDIO_EVENTS_IS_SILENT_CHANGED) {
bool silent = odin_decoder_is_silent(decoder);
printf("Peer %s speaking\n", silent ? "stopped" : "started");
}
}

Media Streams​

ODIN uses an explicit signaling mechanism to manage media streams. You must send RPC commands to the server to Start, Stop, Pause, or Resume media.

Starting Media​

To transmit audio, you must first create an audio stream (likely initializing your microphone) and then signal the room that you are starting media.

// Example: Sending a "StartMedia" RPC
// Payload: { "media_id": <id>, "properties": { "kind": "audio" } }
// Wraps in command structure as defined in your application protocol
// Then send via odin_room_send_rpc

For a complete implementation of audio capture and media signaling, refer to the Minimal Client Sample.

Audio Processing​

The Audio Processing Module (APM) handles echo cancellation, noise suppression, and gain control. You can configure it by applying an OdinApmConfig to your audio pipeline.

OdinApmConfig apm_config = {
.voice_activity_detection = true,
.voice_activity_detection_attack_probability = 0.9,
.voice_activity_detection_release_probability = 0.8,
.echo_canceller = true,
.noise_suppression_level = OdinNoiseSuppressionLevel_Moderate,
.gain_controller = true,
.gain_controller_version = ODIN_GAIN_CONTROLLER_VERSION_V2 // Use V2 for improved quality
};

// Apply to your pipeline (implementation depends on your encoder setup)

User Data & Messages​

Arbitrary data updates (User Data) and Messages are also handled via RPC commands (UpdatePeer, SendMessage). Sending a message to all peers involves sending a SendMessage RPC command with your binary payload.

See Event Structures for the MessageReceived event format.