From b8d0fa5a65599e35cfd3f2cf78b5bc6d50cea68f Mon Sep 17 00:00:00 2001 From: Ednunp <29843396+Ednunp@users.noreply.github.com> Date: Fri, 17 Jul 2026 14:48:30 +0100 Subject: [PATCH] Service: start capturing immediately at boot (catch the Windows startup sound) The boot log showed a 2.6s gap between the service OnStart and its first capture -- that is the resume-settle delay (2000ms), which exists to stop rapid app open/close from thrashing the engine. But at boot the interactive app has NEVER been present, so waiting it out is pure dead time in which the Windows startup tune plays uncaptured (NVDA, which keeps talking, was caught once capture finally came up; the one-shot tune was missed). Fix: the settle now applies only AFTER the app has actually been present (a real yield). The first-ever stint at boot starts capture immediately, ~2.6s sooner, giving the startup sound a chance to be captured. Later app->absent transitions keep the anti-thrash settle. Gate: 40/40. Co-Authored-By: Claude Opus 4.8 --- src/RemSound.App/ServiceSendHost.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/RemSound.App/ServiceSendHost.cs b/src/RemSound.App/ServiceSendHost.cs index f781945..26ec9a4 100644 --- a/src/RemSound.App/ServiceSendHost.cs +++ b/src/RemSound.App/ServiceSendHost.cs @@ -462,11 +462,13 @@ public sealed class ServiceSendHost : IDisposable var appWasPresent = true; // force an initial evaluation var absentSince = Environment.TickCount64; var triedThisAbsence = false; + var haveSeenApp = false; // the settle delay only matters AFTER a real app yield while (!ct.IsCancellationRequested) { var appPresent = isAppPresent(); if (appPresent) { + haveSeenApp = true; wantSending = false; if (IsSending) Suspend(); absentSince = long.MaxValue; @@ -475,7 +477,11 @@ public sealed class ServiceSendHost : IDisposable else { if (appWasPresent) { absentSince = Environment.TickCount64; triedThisAbsence = false; } // app just left - if (Environment.TickCount64 - absentSince >= resumeSettleMs) + // The resume-settle delay exists to stop rapid app open/close from thrashing the engine — + // but ONLY once the app has actually been present. At BOOT the app has never run, so waiting + // it out is pure dead time in which the Windows startup sound plays uncaptured. Start + // immediately on the first-ever stint; apply the settle only on later app→absent transitions. + if (!haveSeenApp || Environment.TickCount64 - absentSince >= resumeSettleMs) { wantSending = true; // One start attempt per absence. If capture isn't ready yet (audio stack still coming