Eliminate audio thread blocking on GUI messages and main thread#137
Merged
nyanpasu64 merged 9 commits intoDn-Programming-Core-Management:masterfrom May 29, 2022
Merged
Conversation
c2a5fde to
c650486
Compare
c650486 to
d1b04f6
Compare
Stuttering still occurs because the audio thread sends data to the GUI thread using CFamiTrackerView::PostMessage, which can block.
`new CSoundGen` would call the regular allocator, but `delete CSoundGen` would call the line-number _aligned deallocator, which pops up an error dialog.
This fixes audio thread hangs caused by PostMessage blocking.
d1b04f6 to
4ab664c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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/SPSCQueues. 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_iTimingCounterand 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 havingCMIDIknow 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?...
AudioMessageIdwithenum classwould make dispatch safer (no accidental audio thread blocking sendPostMessage), and forwarding manageable, but theON_MESSAGErecipient harder to use.Fixes #134.