From 9b63e298d315cb2ad4ab5467655fa2245c58f0df Mon Sep 17 00:00:00 2001 From: Assistant builder Date: Fri, 12 Jun 2026 12:06:48 +0000 Subject: [PATCH] Beep cleanup: start before Task.Run + Wait timeout to avoid orphaned task --- tests/02-wakeword-cs/Program.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/02-wakeword-cs/Program.cs b/tests/02-wakeword-cs/Program.cs index a269080..b44e52e 100644 --- a/tests/02-wakeword-cs/Program.cs +++ b/tests/02-wakeword-cs/Program.cs @@ -165,7 +165,6 @@ static void FireAndForgetBeep(int device, short[] beepBuffer) { int remaining = beepBuffer.Length - offset; int take = (int)Math.Min(frameCount, (uint)remaining); - int silence = (int)frameCount - take; unsafe { short* dst = (short*)output.ToPointer(); @@ -187,15 +186,27 @@ static void FireAndForgetBeep(int device, short[] beepBuffer) var stream = new Stream( null, outParams, WakewordModel.SampleRate, 1024, StreamFlags.NoFlag, playCb, IntPtr.Zero); + try + { + stream.Start(); + } + catch + { + stream.Dispose(); + done.Dispose(); + throw; + } Task.Run(() => { - done.Wait(); + // 2 s timeout so a failed callback (which PortAudio silently swallows + // and would leave 'done' unset) eventually releases the stream + handle + // instead of leaking them for the process lifetime. + done.Wait(TimeSpan.FromSeconds(2)); Thread.Sleep(200); stream.Stop(); stream.Dispose(); done.Dispose(); }); - stream.Start(); } static class Libc