Skip to content

API Reference

Chris edited this page Jan 29, 2026 · 2 revisions

API Reference

Quick reference for the most important Sendspin SDK interfaces and classes.

ISendspinClient / SendspinClientService

Main protocol client for connecting to Sendspin servers.

Properties

Property Type Description
ConnectionState ConnectionState Current connection state
ServerName string? Connected server's name
CurrentGroup GroupState? Current playback group state
CurrentPlayerState PlayerState? This player's volume/mute state
ClockSyncStatus ClockSyncStatus Clock sync statistics

Methods

// Connection
Task ConnectAsync(Uri serverUri, CancellationToken ct = default);
Task DisconnectAsync(string? reason = null);

// Commands
Task SendCommandAsync(string command, Dictionary<string, object>? parameters = null);
Task SetVolumeAsync(int volume);  // 0-100

Events

Event Payload When
ConnectionStateChanged ConnectionState Connection state changes
GroupStateChanged GroupState Playback state/metadata changes
PlayerStateChanged PlayerState Volume/mute changes (this player)
ClockSyncConverged ClockSyncStatus Clock sync stabilizes
ArtworkReceived byte[] Album artwork received

Usage

var client = new SendspinClientService(
    logger,
    connection,
    clockSync,
    capabilities,
    audioPipeline);  // Optional

await client.ConnectAsync(new Uri("ws://server:8927/sendspin"));

client.GroupStateChanged += (s, group) =>
    Console.WriteLine($"Playing: {group.Metadata?.Title}");

await client.SendCommandAsync("play");
await client.SetVolumeAsync(75);

IAudioPlayer (You Implement)

Interface for platform-specific audio output.

Properties

Property Type Description
State AudioPlayerState Current playback state
Volume float Output volume (0.0-1.0)
IsMuted bool Whether output is muted
OutputLatencyMs int Audio output buffer latency
CalibratedStartupLatencyMs int Push-model prefill time (default: 0)
OutputFormat AudioFormat? Current output format

Methods

Task InitializeAsync(AudioFormat format, CancellationToken ct = default);
void SetSampleSource(IAudioSampleSource source);
void Play();
void Pause();
void Stop();
Task SwitchDeviceAsync(string? deviceId, CancellationToken ct = default);
ValueTask DisposeAsync();

Events

Event Payload When
StateChanged AudioPlayerState Playback state changes
ErrorOccurred AudioPlayerError Error during playback

States

public enum AudioPlayerState
{
    Uninitialized,  // Not yet initialized
    Stopped,        // Initialized but not playing
    Playing,        // Actively playing audio
    Paused,         // Paused
    Error           // Error state
}

IAudioPipeline / AudioPipeline

Orchestrates audio flow from network to speakers.

Properties

Property Type Description
State AudioPipelineState Current pipeline state
IsReady bool True when ready to receive audio
CurrentFormat AudioFormat? Input audio format
OutputFormat AudioFormat? Output audio format
BufferStats AudioBufferStats Buffer statistics
DetectedOutputLatencyMs int Detected audio device latency

Methods

Task StartAsync(AudioFormat format);
Task StopAsync();
void Clear();  // Clear buffer (track change)
void ProcessAudioChunk(AudioChunk chunk);  // Called by client
void SetVolume(int volume);  // 0-100
void SetMuted(bool muted);
Task SwitchDeviceAsync(string? deviceId);

Events

Event Payload When
StateChanged AudioPipelineState Pipeline state changes
ErrorOccurred AudioPipelineError Error in pipeline

States

public enum AudioPipelineState
{
    Idle,       // Not started
    Starting,   // Initializing components
    Buffering,  // Filling buffer before playback
    Playing,    // Actively playing
    Stopping,   // Shutting down
    Error       // Error state
}

ITimedAudioBuffer / TimedAudioBuffer

Timestamped audio buffer with sync error calculation.

Properties

Property Type Description
SyncErrorMicroseconds long Raw sync error (+ = behind)
SmoothedSyncErrorMicroseconds long EMA-filtered error
BufferedMilliseconds double Current buffer depth
IsReadyForPlayback bool Buffer reached target
TargetBufferMilliseconds double Target buffer before play
OutputLatencyMicroseconds long Set from IAudioPlayer
TargetPlaybackRate double (Deprecated) For internal correction

Methods

// Write (from decoder)
void Write(ReadOnlySpan<float> samples, long serverTimestamp);

// Read (from audio thread)
int ReadRaw(Span<float> buffer, long currentTimeMicroseconds);  // Preferred
int Read(Span<float> buffer, long currentTimeMicroseconds);     // Deprecated

// Sync correction feedback
void NotifyExternalCorrection(int samplesDropped, int samplesInserted);

// Control
void Clear();  // Reset on track change
AudioBufferStats GetStats();

IClockSynchronizer / KalmanClockSynchronizer

Server-to-local time synchronization using Kalman filter.

Properties

Property Type Description
IsConverged bool 5+ stable measurements
HasMinimalSync bool 2+ measurements (quick start)
StaticDelayMs double Manual sync offset

Methods

// Process NTP-style measurement
void ProcessMeasurement(long t1, long t2, long t3, long t4);

// Time conversion
long ServerToClientTime(long serverTimestamp);
long ClientToServerTime(long clientTimestamp);

// Status
ClockSyncStatus GetStatus();
void Reset();

ClockSyncStatus

public record ClockSyncStatus
{
    public double OffsetMicroseconds { get; init; }          // Server-to-client offset
    public double DriftMicrosecondsPerSecond { get; init; }  // Clock drift rate
    public int MeasurementCount { get; init; }               // Total measurements
    public bool IsConverged { get; init; }
    public bool HasMinimalSync { get; init; }
}

IServerDiscovery / MdnsServerDiscovery

mDNS-based server discovery.

Properties

Property Type Description
Servers IReadOnlyCollection<DiscoveredServer> Found servers
IsRunning bool Discovery active

Methods

Task StartAsync();   // Start continuous discovery
Task StopAsync();    // Stop discovery
Task<IEnumerable<DiscoveredServer>> ScanAsync(TimeSpan timeout);  // One-time scan

Events

Event Payload When
ServerFound DiscoveredServer New server found
ServerLost DiscoveredServer Server disappeared
ServerUpdated DiscoveredServer Server info changed

DiscoveredServer

public record DiscoveredServer(
    string Id,
    string Name,
    Uri Uri,
    string? Version);

ClientCapabilities

Identifies your player to servers.

public class ClientCapabilities
{
    public string ClientId { get; set; }           // Unique ID (auto-generated if null)
    public string ClientName { get; set; }         // Display name
    public string? ProductName { get; set; }       // Product model
    public string? Manufacturer { get; set; }      // Brand/company
    public string? SoftwareVersion { get; set; }   // App version
    public List<string> Roles { get; set; }        // Feature support
    public List<AudioFormat> AudioFormats { get; set; }  // Supported codecs
    public int BufferCapacity { get; set; }        // Max buffer (bytes)
    public List<string> ArtworkFormats { get; set; }     // jpeg, png
    public int ArtworkMaxSize { get; set; }        // Max artwork px
    public int InitialVolume { get; set; }         // 0-100
    public bool InitialMuted { get; set; }
}

SyncCorrectionCalculator

Calculates sync correction strategy based on error.

Properties

Property Type Description
CurrentMode SyncCorrectionMode Current correction mode
TargetPlaybackRate double Playback rate (1.0 = normal)
DropEveryNFrames int Drop interval (0 = disabled)
InsertEveryNFrames int Insert interval (0 = disabled)

Methods

void UpdateFromSyncError(long rawError, long smoothedError);
void Reset();

Events

Event Payload When
CorrectionChanged ISyncCorrectionProvider Correction strategy changes

Modes

public enum SyncCorrectionMode
{
    None,       // Within deadband
    Resampling, // Rate adjustment (1-15ms)
    Dropping,   // Drop frames (>15ms behind)
    Inserting   // Insert frames (>15ms ahead)
}

SyncCorrectionOptions

Configuration for sync correction behavior.

public class SyncCorrectionOptions
{
    public double MaxSpeedCorrection { get; set; }            // Default: 0.02 (2%)
    public double CorrectionTargetSeconds { get; set; }       // Default: 3.0
    public long ResamplingThresholdMicroseconds { get; set; } // Default: 15,000 (15ms)
    public long ReanchorThresholdMicroseconds { get; set; }   // Default: 500,000 (500ms)
    public long StartupGracePeriodMicroseconds { get; set; }  // Default: 500,000

    // Presets
    public static SyncCorrectionOptions Default { get; }      // Conservative (Windows)
    public static SyncCorrectionOptions CliDefaults { get; }  // Aggressive (CLI)
}

AudioFormat

Describes audio codec and format.

public class AudioFormat
{
    public string Codec { get; set; }        // "opus", "flac", "pcm"
    public int SampleRate { get; set; }      // 48000, 44100, etc.
    public int Channels { get; set; }        // 1, 2
    public int? BitDepth { get; set; }       // 16, 24, 32 (PCM)
    public int? Bitrate { get; set; }        // kbps (lossy)
    public string? CodecHeader { get; set; } // Base64 codec data
}

GroupState

Playback group state and metadata.

public class GroupState
{
    public string GroupId { get; set; }
    public string? Name { get; set; }
    public PlaybackState PlaybackState { get; set; }  // Playing, Paused, Stopped
    public int Volume { get; set; }                   // Group average (0-100)
    public bool Muted { get; set; }
    public TrackMetadata? Metadata { get; set; }
    public bool Shuffle { get; set; }
    public string? Repeat { get; set; }               // "off", "one", "all"
}

TrackMetadata

Current track information.

public class TrackMetadata
{
    public string? Title { get; set; }
    public string? Artist { get; set; }
    public string? AlbumArtist { get; set; }
    public string? Album { get; set; }
    public string? ArtworkUrl { get; set; }
    public int? Year { get; set; }
    public int? Track { get; set; }
    public PlaybackProgress? Progress { get; set; }
    public double? Duration { get; set; }   // Computed
    public double? Position { get; set; }   // Computed
}

See Also