Service crackle fix: un-throttle the process while streaming (PerformanceMode)

The send-only service sounded hideous/crackly vs the main app, even standalone, with
clean capture (capPeak ~0.44) and clean receiver metrics (no underruns/drops/gaps) --
the fingerprint of a process being starved by the OS scheduler, not a data problem.

Cause: a headless Windows SERVICE is a background process, so Windows aggressively
downclocks it (EcoQoS), migrates its threads onto efficiency cores, and gives it a
coarse scheduler quantum -- exactly what starves the audio send loop into crackling.
The interactive app engages PerformanceMode only on the user high-priority toggle;
the service never engaged it at all, and being a service it is throttled far harder.

Fix: the service now engages PerformanceMode (EcoQoS opt-out, High priority, 1ms timer,
no deep C-states, working-set floor) whenever it is streaming, released on suspend/
dispose. Unconditional -- the service has no foreground/battery use case; it exists
solely to stream and must not be throttled.

Gate: 39/39.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-07-17 12:13:29 +01:00
co-authored by Claude Opus 4.8
parent cd9760d7d5
commit ec149ed09e
+10
View File
@@ -348,6 +348,14 @@ public sealed class ServiceSendHost : IDisposable
// blind push. Same well-known audio port and the same components the interactive app uses.
presence.Start(RemPacket.DefaultPort, endpoints);
running = true;
// Un-throttle the process while streaming. A headless Windows SERVICE is treated by the OS as a
// background process and gets aggressively downclocked (EcoQoS), migrated onto efficiency cores
// and given a coarse scheduler quantum — which starves the send loop and makes the stream
// CRACKLE even though capture and the network look clean. The interactive app only does this on
// the user's opt-in "high priority" toggle, but the service has no foreground/battery use case
// (it exists solely to stream), so it always engages while sending. Idempotent; released in
// Suspend. This is the fix for "the service sounds hideous vs the main app".
try { PerformanceMode.Apply(true, msg => log?.Invoke($"service: {msg}")); } catch { /* best-effort */ }
log?.Invoke($"service: streaming \"{profile.Title}\" — {specs.Count} source(s) to {endpoints.Count} peer(s)");
return true;
}
@@ -366,6 +374,7 @@ public sealed class ServiceSendHost : IDisposable
SwapMeterDevices(Array.Empty<CaptureSourceSpec>()); // release the endpoint-meter readers
try { sessionKick?.Dispose(); } catch { /* ignore */ }
sessionKick = null;
try { PerformanceMode.Apply(false, msg => log?.Invoke($"service: {msg}")); } catch { /* best-effort */ }
running = false;
log?.Invoke("service: suspended (interactive app present)");
}
@@ -607,6 +616,7 @@ public sealed class ServiceSendHost : IDisposable
try { deviceNotifier?.Dispose(); } catch { } deviceNotifier = null;
try { sessionKick?.Dispose(); } catch { } sessionKick = null;
SwapMeterDevices(Array.Empty<CaptureSourceSpec>());
try { PerformanceMode.Apply(false); } catch { }
try { presence.Dispose(); } catch { }
try { sender.Stop(); } catch { }
try { sender.Dispose(); } catch { }