Skip to content

Commit 6452cf3

Browse files
eizclaude
andcommitted
SarAsio: don't broadcast format changes on Windows 10 and later
Whenever any audio endpoint became active, SarAsio had the driver send KSEVENT_PINCAPS_FORMATCHANGE to every SAR filter on its next tick, and the audio engine invalidated every stream open on a SAR endpoint. The comment says new and non-SAR endpoints are filtered out, but the property check passes for any endpoint, so starting a host invalidated its own fresh streams, and so did each endpoint Windows rebuilt or any other device appearing. The event exists so the audio engine re-reads the format of an endpoint re-created with a different sample rate. On Windows 10 and later the driver puts the channel count, sample rate and sample size into the endpoint's KS reference string, so such an endpoint is a new endpoint to Windows and the event is never needed there. Skip it on those versions. On the test VM (16 endpoint pairs, three start/stop iterations), the loopback run saw 34 to 116 stream invalidations per run with the broadcast (3 runs) and none without it (8 runs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 990828a commit 6452cf3

1 file changed

Lines changed: 21 additions & 1 deletion

File tree

‎SarAsio/sarclient.cpp‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,26 @@ void SarClient::mux(
580580
}
581581
}
582582

583+
// On Windows 10 and later the driver puts each endpoint's channel count,
584+
// sample rate and sample size into its KS reference string (see
585+
// SarCreateEndpoint), so an endpoint whose format changed is a new endpoint
586+
// to Windows and no format change event is needed.
587+
static bool endpointIdIncludesFormat()
588+
{
589+
typedef LONG (WINAPI *RtlGetVersionFn)(PRTL_OSVERSIONINFOW);
590+
static const bool result = [] {
591+
RTL_OSVERSIONINFOW info = {};
592+
auto rtlGetVersion = (RtlGetVersionFn)GetProcAddress(
593+
GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion");
594+
595+
info.dwOSVersionInfoSize = sizeof(info);
596+
return rtlGetVersion && rtlGetVersion(&info) == 0 &&
597+
info.dwMajorVersion >= 10;
598+
}();
599+
600+
return result;
601+
}
602+
583603
HRESULT STDMETHODCALLTYPE SarClient::NotificationClient::OnDeviceStateChanged(
584604
_In_ LPCWSTR pwstrDeviceId,
585605
_In_ DWORD dwNewState)
@@ -591,7 +611,7 @@ HRESULT STDMETHODCALLTYPE SarClient::NotificationClient::OnDeviceStateChanged(
591611
// KSEVENT_PINCAPS_FORMATCHANGE event, which causes the audio engine to
592612
// re-query the pin capabilities. This isn't needed for newly added
593613
// endpoints or non-SAR endpoints, so we filter out those events.
594-
if (dwNewState != DEVICE_STATE_ACTIVE) {
614+
if (dwNewState != DEVICE_STATE_ACTIVE || endpointIdIncludesFormat()) {
595615
return S_OK;
596616
}
597617

0 commit comments

Comments
 (0)