NET Network Synchronization

Synchronize audio playback across multiple devices on your local network with sample-accurate precision. Perfect for multi-room audio, live performances, DJ setups, and synchronized installations.

✨ New in v2.5.2 Network synchronization enables multiple devices to play audio in perfect sync across your local network with <5ms accuracy on LAN and <20ms on WiFi. Zero-configuration, offline operation, and graceful degradation included.

Overview

NetworkSync provides a complete solution for multi-device audio synchronization:

Key Features

Feature Description
Local Network Only Works entirely offline, no internet required
Auto-Discovery Clients automatically find servers on LAN
Latency Compensation Automatic network delay measurement and compensation
Connection Resilience Auto-reconnect with exponential backoff
Offline Playback Clients continue playing if server disconnects
Zero-GC No heap allocations in hot path
Low Bandwidth <15 KB/s per client
Thread Isolation Network never blocks audio threads

Synchronization Accuracy

Network Type Typical Accuracy Maximum Drift
Gigabit LAN <2ms <5ms
100Mbps LAN <5ms <10ms
WiFi 5/6 (5GHz) <10ms <20ms
WiFi 4 (2.4GHz) <20ms <50ms

Quick Start

Server Setup (Control Device)

Server Mode - Basic Setup
using OwnaudioNET;

// Initialize audio system
await OwnaudioNet.InitializeAsync();
OwnaudioNet.Start();

// Start as network sync server
await OwnaudioNet.StartNetworkSyncServerAsync(
    port: 9876,
    useLocalTimeOnly: true);  // No internet required!

// Get mixer and add tracks
var mixer = OwnaudioNet.GetAudioMixer();
var track = new FileSource("song.mp3");
track.AttachToClock(mixer.MasterClock);
mixer.AddSource(track);

// All commands are automatically broadcast to clients
track.Play();   // All clients start playing
track.Pause();  // All clients pause
track.Seek(30); // All clients seek to 30 seconds

// Monitor connected clients
var status = OwnaudioNet.GetNetworkSyncStatus();
Console.WriteLine($"Connected clients: {status.ClientCount}");

Client Setup (Follower Devices)

Client Mode - Basic Setup
using OwnaudioNET;

// Initialize audio system
await OwnaudioNet.InitializeAsync();
OwnaudioNet.Start();

// Connect to server (auto-discovery or manual IP)
await OwnaudioNet.StartNetworkSyncClientAsync(
    serverAddress: "192.168.1.100",  // Or null for auto-discovery
    port: 9876,
    allowOfflinePlayback: true);     // Continue if disconnected

// Add SAME tracks as server
var mixer = OwnaudioNet.GetAudioMixer();
var track = new FileSource("song.mp3");  // Same file as server!
track.AttachToClock(mixer.MasterClock);
mixer.AddSource(track);

// Client automatically follows server commands
// No manual control needed!

// Monitor connection state
OwnaudioNet.NetworkSyncConnectionChanged += (sender, e) =>
{
    Console.WriteLine($"Connection: {e.NewState}");
    
    if (e.NewState == ConnectionState.Synced)
        Console.WriteLine("✅ Synchronized with server!");
    else if (e.NewState == ConnectionState.Disconnected)
        Console.WriteLine("⚠️ Disconnected - playing standalone");
};

Server Mode

Starting a Server

Server Configuration
// Start server with custom port
await OwnaudioNet.StartNetworkSyncServerAsync(
    port: 9876,                  // UDP port (default: 9876)
    useLocalTimeOnly: true);     // Use local time sync only

// Server is now broadcasting at 100Hz (10ms interval)

Broadcasting Commands

Transport Control
// All FileSource commands are automatically broadcast
var track = new FileSource("music.mp3");
track.AttachToClock(mixer.MasterClock);
mixer.AddSource(track);

// These commands are broadcast to all clients:
track.Play();           // Start playback
track.Pause();          // Pause playback
track.Stop();           // Stop playback
track.Seek(45.0);       // Seek to 45 seconds
track.Tempo = 1.2f;     // Set tempo to 120%

// Manual command broadcasting (advanced)
var cmd = NetworkSyncProtocol.CreatePlayCommand(
    ntpTimestamp: DateTime.UtcNow.Ticks,
    scheduledExecutionTime: DateTime.UtcNow.AddMilliseconds(100).Ticks,
    startPosition: 0.0);

OwnaudioNet.BroadcastCommand(ref cmd);

Monitoring Clients

Client Monitoring
// Get server status
var status = OwnaudioNet.GetNetworkSyncStatus();

if (status.IsServer)
{
    Console.WriteLine($"Server running");
    Console.WriteLine($"Connected clients: {status.ClientCount}");
    Console.WriteLine($"Time sync tier: {status.TimeSyncTier}");
}

// Client connection events
// (Events are raised on the server when clients connect/disconnect)
// Note: Currently implemented in NetworkSyncServer class

Client Mode

Connecting to Server

Client Connection Options
// Option 1: Auto-discovery (recommended)
await OwnaudioNet.StartNetworkSyncClientAsync(
    serverAddress: null,             // Auto-discover server
    port: 9876,
    allowOfflinePlayback: true);

// Option 2: Manual IP address
await OwnaudioNet.StartNetworkSyncClientAsync(
    serverAddress: "192.168.1.100",  // Specific server IP
    port: 9876,
    allowOfflinePlayback: true);

// Option 3: Hostname
await OwnaudioNet.StartNetworkSyncClientAsync(
    serverAddress: "audio-server.local",
    port: 9876,
    allowOfflinePlayback: true);

Connection States

State Description Local Control
Disconnected Not connected to server ✅ Allowed
Connecting Attempting to connect ❌ Blocked
Connected Connected but not synced ❌ Blocked
Synced Fully synchronized ❌ Blocked

Handling Connection Loss

Connection Resilience
// Monitor connection state changes
OwnaudioNet.NetworkSyncConnectionChanged += (sender, e) =>
{
    switch (e.NewState)
    {
        case ConnectionState.Disconnected:
            Console.WriteLine("⚠️ Disconnected from server");
            Console.WriteLine("   Continuing playback in standalone mode");
            // Client automatically continues playing
            break;
            
        case ConnectionState.Connecting:
            Console.WriteLine("🔄 Reconnecting to server...");
            break;
            
        case ConnectionState.Connected:
            Console.WriteLine("✅ Connected to server");
            break;
            
        case ConnectionState.Synced:
            Console.WriteLine("🎵 Synchronized with server!");
            var status = OwnaudioNet.GetNetworkSyncStatus();
            Console.WriteLine($"   Latency: {status.AverageLatency:F2}ms");
            break;
    }
};

// Check if local control is allowed
if (OwnaudioNet.IsNetworkSyncLocalControlAllowed())
{
    // Can control playback locally (disconnected)
    track.Play();
    track.Seek(60);
}
else
{
    // Server is controlling playback
    Console.WriteLine("Server is in control");
}
Automatic Reconnection Clients automatically attempt to reconnect if the server becomes unavailable. After 30 seconds of no server response, the client switches to standalone mode and continues playback. When the server comes back online, the client automatically reconnects and resynchronizes.

API Reference

OwnaudioNet Methods

Method Description
StartNetworkSyncServerAsync(port, useLocalTimeOnly) Start as network sync server
StartNetworkSyncClientAsync(serverAddress, port, allowOfflinePlayback) Start as network sync client
StopNetworkSync() Stop network synchronization
GetNetworkSyncStatus() Get current network sync status
IsNetworkSyncLocalControlAllowed() Check if local control is allowed
BroadcastCommand(ref command) Manually broadcast command (server only)

NetworkSyncStatus Properties

Property Type Description
IsEnabled bool Whether network sync is active
IsServer bool True if running as server
IsClient bool True if running as client
ConnectionState ConnectionState Current connection state (client only)
ClientCount int Number of connected clients (server only)
AverageLatency double Average network latency in ms (client only)
IsLocalControlAllowed bool Whether local playback control is allowed
TimeSyncTier TimeSyncTier Current time synchronization method

Real-World Use Cases

🏠 Multi-Room Audio System

Whole-Home Audio
// Living Room (Server - Main Control)
await OwnaudioNet.StartNetworkSyncServerAsync();
var livingRoomTrack = new FileSource("party-mix.mp3");
mixer.AddSource(livingRoomTrack);
livingRoomTrack.Play();

// Kitchen (Client)
await OwnaudioNet.StartNetworkSyncClientAsync();
var kitchenTrack = new FileSource("party-mix.mp3");
mixer.AddSource(kitchenTrack);
// Automatically follows living room

// Bedroom (Client)
await OwnaudioNet.StartNetworkSyncClientAsync();
var bedroomTrack = new FileSource("party-mix.mp3");
mixer.AddSource(bedroomTrack);
// Automatically follows living room

// Perfect synchronization throughout your home!

🎤 Live Performance / DJ Setup

Professional DJ System
// Main Mixer (Server)
await OwnaudioNet.StartNetworkSyncServerAsync();
var mainOutput = new FileSource("set-track-01.mp3");
mixer.AddSource(mainOutput);

// Monitor Speakers (Clients)
// Multiple monitor positions all receive the same audio
await OwnaudioNet.StartNetworkSyncClientAsync();

// Backup System (Client)
// Ready for instant failover if main system fails
await OwnaudioNet.StartNetworkSyncClientAsync(
    allowOfflinePlayback: true);  // Continues if main fails

// All systems play in perfect sync
// Backup automatically takes over if main disconnects

🎬 Installation Art / Museums

Synchronized Installation
// Central Control Room (Server)
await OwnaudioNet.StartNetworkSyncServerAsync();
var soundtrack = new FileSource("installation-audio.wav");
mixer.AddSource(soundtrack);

// Multiple Display Zones (Clients)
// Zone 1, 2, 3, 4... all synchronized
for (int zone = 1; zone <= 10; zone++)
{
    // Each zone runs on separate device
    await OwnaudioNet.StartNetworkSyncClientAsync();
    var zoneTrack = new FileSource("installation-audio.wav");
    mixer.AddSource(zoneTrack);
}

// Synchronized audio-visual experience across entire installation

🎧 Collaborative Music Production

Studio Collaboration
// Producer's Workstation (Server)
await OwnaudioNet.StartNetworkSyncServerAsync();
var projectMix = new FileSource("project-mix.wav");
mixer.AddSource(projectMix);

// Musicians' Headphones (Clients)
// Guitarist
await OwnaudioNet.StartNetworkSyncClientAsync();
var guitaristMix = new FileSource("project-mix.wav");
mixer.AddSource(guitaristMix);

// Vocalist
await OwnaudioNet.StartNetworkSyncClientAsync();
var vocalistMix = new FileSource("project-mix.wav");
mixer.AddSource(vocalistMix);

// Everyone hears exactly the same thing at the same time
// Perfect for recording sessions and rehearsals

📱 Mobile Party Mode

Synchronized Mobile Devices
// Main Phone/Tablet (Server)
await OwnaudioNet.StartNetworkSyncServerAsync();

// Other Phones/Tablets (Clients)
await OwnaudioNet.StartNetworkSyncClientAsync(
    serverAddress: null,  // Auto-discovery on WiFi
    allowOfflinePlayback: true);

// All devices play in perfect sync over WiFi
// Great for parties, outdoor events, etc.

Performance Characteristics

CPU Usage

Component CPU Usage Priority Impact
Audio MixThread 8-10% Highest UNCHANGED
FileSource Decoders 2-5% per track Normal UNCHANGED
Network Receive Thread 1-2% Normal NEW
Network Send Thread (server) 0.5-1% Normal NEW
Total Impact +2-3% - Negligible

Network Bandwidth

Memory Footprint

Zero-GC Guarantees

Operation Allocation Technique
Clock sync broadcast 0 bytes stackalloc, ArrayPool
Command serialization 0 bytes Span<byte>, BinaryPrimitives
Command deserialization 0 bytes ReadOnlySpan<byte>
State updates 0 bytes volatile fields, Interlocked
Performance Guarantee Network synchronization is designed to have ZERO impact on audio playback quality. All performance-critical paths are zero-allocation and lock-free. Audio threads are never blocked by network operations.

Troubleshooting

Common Issues

⚠️ Clients Not Discovering Server
  • Ensure all devices are on the same local network
  • Check firewall settings (UDP port 9876 must be open)
  • Try specifying server IP manually instead of auto-discovery
  • Verify router allows UDP broadcast/multicast
⚠️ Audio Drift / Desynchronization
  • Check network latency (WiFi 2.4GHz can be unstable)
  • Use wired Ethernet for best results (<5ms accuracy)
  • Ensure all devices use identical audio files
  • Verify sample rates match across all devices
⚠️ Connection Drops Frequently
  • Check WiFi signal strength on all devices
  • Reduce network congestion (pause downloads, streaming)
  • Use 5GHz WiFi instead of 2.4GHz if available
  • Consider using wired Ethernet for critical devices

Best Practices

Firewall Configuration

Required Firewall Rules
# Windows Firewall
netsh advfirewall firewall add rule name="OwnaudioSharp NetworkSync" dir=in action=allow protocol=UDP localport=9876

# Linux iptables
sudo iptables -A INPUT -p udp --dport 9876 -j ACCEPT

# macOS
# Allow in System Preferences > Security & Privacy > Firewall > Firewall Options
Need Help? For additional support, check the GitHub repository or open an issue with your specific use case.