Eliminate audio thread blocking on GUI messages and main thread #137
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This replaces all message queues between the audio and GUI thread with wait-free
rigtorp/SPSCQueue
s. The queue from audio to GUI is read by a worker thread owned byCFamiTrackerView::m_ReceiveThread
, which then blocking-sends window messages to the main thread's event loop.This eliminates the last known causes of audio stuttering (un/minimizing windows on Windows <=7 with compositing off, and enabling register view and switching windows on Wine kwin_x11), outside of Mac Wine. For the first time in this program's history, Dn-FamiTracker can run at a stable 20-22 ms of latency (eg. by setting the slider to 1ms), entirely immune to the inescapable audio glitching that has plagued it for years. (Technically the audio thread still competes with the main thread for mutexes, but this does not contend in practice.)
As an added bonus, this replaces the queue between the MIDI thread and the main thread with a
SPSCQueue
(eliminating janky custom code), though I didn't bother rewriting the "new event arrived" signaling system (WM_USER_MIDI_EVENT
) with a SPSCQueue. This is no worse than before, but I wonder howCMIDI::m_iTimingCounter
and row transitions interact, whether there are off-by-1-row bugs in this code or not, and if we can get more reliable timing by havingCMIDI
know aboutCFamiTrackerView::PostQueueMessage
. (Perhaps timing doesn't matter if the main window is driven by the MIDI clock (not sure if always the case, seeCFamiTrackerView::TranslateMidiMessage()
), and if the main and MIDI threads hanging does not affect the time of MIDI events relative to the MIDI clock.)CMIDI::Event
, what happens when {C, static, reinterpret} castingCView*
toCFamiTrackerView*
, with the latter either visible or a forward declaration?...
AudioMessageId
withenum class
would make dispatch safer (no accidental audio thread blocking sendPostMessage
), and forwarding manageable, but theON_MESSAGE
recipient harder to use.Fixes #134.