mirror of
https://github.com/libretro/parallel-gx2.git
synced 2026-11-07 12:37:54 -10:00
Pace AX with a clock that moves, on Windows too
NNshi's Windows core produced about a fifth of the audio it should, which is silence on WASAPI and a 90% underrun on XAudio and ASIO. The ratio is the tell: AXOut_update gates on 3 ms and queues one 3 ms frame per pass, and 15.6 ms divided by 3 ms is 5.2. 15.6 ms is the Windows system timer period, and that is the resolution of std::chrono::high_resolution_clock on a MinGW build - libstdc++ makes it an alias of system_clock, which reads the system time rather than QPC. now_cached() hands MinGW exactly that, because its fast path is written in MSVC STL internals and everything else falls through to the standard clock. Upstream never meets this: its Windows build is MSVC, where now_cached is QPC by hand, and on Linux and macOS the standard clock is fine. So the pacing uses tick_cached() instead, which is QPC on every compiler and monotonic besides - which is what a delta wanted in the first place. The same fallback is in VPADController for its input tick. Left alone: nothing has been reported there and a coarse clock costs less in input sampling than it does in an audio gate, so that is a change to make with evidence rather than by analogy.
This commit is contained in:
1 parent
71418964e4
commit
29b06ff0fa
1 file changed
+12
-3
@@ -557,10 +557,19 @@ namespace snd_core
|
||||
// s_last_check is always set to the timestamp at the time of firing
|
||||
// it's used to enforce the minimum wait delay (we want to avoid calling AX update in quick succession because other threads may need to do work first)
|
||||
|
||||
static auto s_ax_interval_timer = now_cached() - kWaitDuration;
|
||||
static auto s_last_check = now_cached();
|
||||
// tick_cached, not now_cached: these are deltas, so what they want is a
|
||||
// monotonic clock - and on a MinGW build now_cached falls back to
|
||||
// std::chrono::high_resolution_clock, which is libstdc++'s system_clock
|
||||
// and on Windows ticks with the system timer, not with QPC. A clock that
|
||||
// only moves every ~15.6 ms never opens this 3 ms gate on time: AX then
|
||||
// queues one 3 ms frame per tick instead of five, which is audio at a
|
||||
// fifth of real time - silence on WASAPI, underruns everywhere else.
|
||||
// Upstream never meets this because its Windows build is MSVC, where
|
||||
// now_cached is QPC by hand. tick_cached is QPC on every compiler.
|
||||
static auto s_ax_interval_timer = tick_cached() - kWaitDuration;
|
||||
static auto s_last_check = tick_cached();
|
||||
|
||||
const auto now = now_cached();
|
||||
const auto now = tick_cached();
|
||||
const auto diff = (now - s_ax_interval_timer);
|
||||
|
||||
if (diff < wait_duration)
|
||||
|
||||
Reference in new issue
Block a user