Skip to content

Commit a83fe73

Browse files
chrisutheclaude
andcommitted
feat(startup): reduce time-to-playback from ~5s to ~300ms
Adopt the JS/CLI player's quick-start strategy: begin playback after just 2 time sync measurements instead of waiting for full Kalman filter convergence (5+ measurements). Changes: - Add HasMinimalSync property to IClockSynchronizer (true after 2 measurements) - Use HasMinimalSync instead of IsConverged for playback gating - Reduce convergence timeout from 5000ms to 1000ms as safety net The sync correction system (resampling + drop/insert) handles any initial estimation errors, making the long convergence wait unnecessary. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 364b18a commit a83fe73

3 files changed

Lines changed: 33 additions & 3 deletions

File tree

src/Sendspin.SDK/Audio/AudioPipeline.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,9 @@ private bool ShouldWaitForClockSync()
426426
return false;
427427
}
428428

429-
// If clock is already converged, proceed
430-
if (_clockSync.IsConverged)
429+
// If clock has minimal sync (2+ measurements), proceed
430+
// Full convergence happens in background, sync correction handles any estimation errors
431+
if (_clockSync.HasMinimalSync)
431432
{
432433
return false;
433434
}

src/Sendspin.SDK/Synchronization/KalmanClockSynchronizer.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public sealed class KalmanClockSynchronizer : IClockSynchronizer
4343

4444
// Convergence tracking
4545
private const int MinMeasurementsForConvergence = 5;
46+
private const int MinMeasurementsForPlayback = 2; // Quick start: 2 measurements like JS/CLI players
4647
private const double MaxOffsetUncertaintyForConvergence = 1000.0; // 1ms uncertainty threshold
4748

4849
// Drift reliability threshold - don't apply drift until uncertainty is below this
@@ -88,6 +89,7 @@ public int MeasurementCount
8889

8990
/// <summary>
9091
/// Whether the synchronizer has converged to a stable estimate.
92+
/// Requires 5+ measurements and low offset uncertainty.
9193
/// </summary>
9294
public bool IsConverged
9395
{
@@ -101,6 +103,26 @@ public bool IsConverged
101103
}
102104
}
103105

106+
/// <summary>
107+
/// Whether the synchronizer has enough measurements for playback (at least 2).
108+
/// Unlike <see cref="IsConverged"/>, this doesn't require statistical convergence.
109+
/// The sync correction system handles any estimation errors during initial playback.
110+
/// </summary>
111+
/// <remarks>
112+
/// This matches the JS/CLI player behavior which starts after 2 measurements (~300-500ms)
113+
/// rather than waiting for full Kalman filter convergence (5+ measurements, ~1-5 seconds).
114+
/// </remarks>
115+
public bool HasMinimalSync
116+
{
117+
get
118+
{
119+
lock (_lock)
120+
{
121+
return _measurementCount >= MinMeasurementsForPlayback;
122+
}
123+
}
124+
}
125+
104126
/// <summary>
105127
/// Whether the drift estimate is reliable enough to use for time conversions.
106128
/// Drift estimation requires longer time periods to be accurate, so we don't
@@ -455,9 +477,16 @@ public interface IClockSynchronizer
455477

456478
/// <summary>
457479
/// Whether the synchronizer has converged to a stable estimate.
480+
/// Requires 5+ measurements and low offset uncertainty.
458481
/// </summary>
459482
bool IsConverged { get; }
460483

484+
/// <summary>
485+
/// Whether the synchronizer has enough measurements for playback (at least 2).
486+
/// Unlike <see cref="IsConverged"/>, this doesn't require statistical convergence.
487+
/// </summary>
488+
bool HasMinimalSync { get; }
489+
461490
/// <summary>
462491
/// Resets the synchronizer state.
463492
/// </summary>

src/SendspinClient/appsettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"AdaptiveCutoff": 0.75,
2020
"MinSamplesForForgetting": 100,
2121
"WaitForConvergence": true,
22-
"ConvergenceTimeoutMs": 5000
22+
"ConvergenceTimeoutMs": 1000
2323
},
2424
"SyncCorrection": {
2525
"UseResampling": true,

0 commit comments

Comments
 (0)