Fix audio clock drift and adaptive jitter buffering
This commit is contained in:
@@ -34,7 +34,7 @@ public sealed class WasapiAudioBackend : IAudioDeviceBackend
|
||||
private sealed class Playback : IAudioPlayback
|
||||
{
|
||||
private readonly string? deviceId;
|
||||
private readonly PcmRing pcm = new(32768);
|
||||
private readonly AdaptivePcmBuffer pcm = new(2);
|
||||
private readonly ManualResetEventSlim initialized = new(false);
|
||||
private readonly Thread thread;
|
||||
private volatile bool running = true;
|
||||
@@ -47,6 +47,7 @@ public sealed class WasapiAudioBackend : IAudioDeviceBackend
|
||||
thread.Start();
|
||||
if (!initialized.Wait(5000) || !ready) { Dispose(); throw new InvalidOperationException("WASAPI playback could not start."); }
|
||||
}
|
||||
public int BufferMilliseconds { get => pcm.BufferMilliseconds; set => pcm.BufferMilliseconds = value; }
|
||||
public void Write(ReadOnlySpan<short> stereoPcm) => pcm.TryWrite(stereoPcm);
|
||||
private unsafe void Work()
|
||||
{
|
||||
@@ -68,7 +69,6 @@ public sealed class WasapiAudioBackend : IAudioDeviceBackend
|
||||
render = (IAudioRenderClient)output;
|
||||
if (client.Start() < 0) return;
|
||||
ready = true; initialized.Set();
|
||||
Span<short> discard = stackalloc short[1920];
|
||||
while (running)
|
||||
{
|
||||
bufferReady.WaitOne(20); // Scheduling wait is outside the buffer-fill cycle.
|
||||
@@ -77,8 +77,6 @@ public sealed class WasapiAudioBackend : IAudioDeviceBackend
|
||||
if (frames == 0) continue;
|
||||
if (render.GetBuffer(frames, out nint buffer) < 0) break;
|
||||
var destination = new Span<short>((void*)buffer, checked((int)frames * 2));
|
||||
// Keep queued playback bounded to ~120 ms, then fill underflow with silence.
|
||||
while (pcm.Count > 11520) pcm.Read(discard);
|
||||
int count = pcm.Read(destination); destination[count..].Clear();
|
||||
if (render.ReleaseBuffer(frames, 0) < 0) break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user