Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate audio thread blocking on GUI messages and main thread #137

Conversation

nyanpasu64
Copy link
Collaborator

@nyanpasu64 nyanpasu64 commented May 24, 2022

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 by CFamiTrackerView::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 how CMIDI::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 having CMIDI know about CFamiTrackerView::PostQueueMessage. (Perhaps timing doesn't matter if the main window is driven by the MIDI clock (not sure if always the case, see CFamiTrackerView::TranslateMidiMessage()), and if the main and MIDI threads hanging does not affect the time of MIDI events relative to the MIDI clock.)

  • In CMIDI::Event, what happens when {C, static, reinterpret} casting CView* to CFamiTrackerView*, with the latter either visible or a forward declaration?

...

  • Swap AudioMessage and GuiMessage
  • Pick a better name for QueueMessage (intended as a noun, sounds like a verb) and SpscMessage (unpronounceable)
  • Replacing AudioMessageId with enum class would make dispatch safer (no accidental audio thread blocking send PostMessage), and forwarding manageable, but the ON_MESSAGE recipient harder to use.

Fixes #134.

@nyanpasu64 nyanpasu64 force-pushed the rewrite-audio-thread branch 3 times, most recently from c2a5fde to c650486 Compare May 28, 2022 11:57
@nyanpasu64 nyanpasu64 changed the base branch from master to add-headers-to-cmake May 28, 2022 11:58
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.
@nyanpasu64 nyanpasu64 marked this pull request as ready for review May 29, 2022 10:15
@nyanpasu64 nyanpasu64 changed the base branch from add-headers-to-cmake to master May 29, 2022 12:40
@nyanpasu64 nyanpasu64 closed this May 29, 2022
@nyanpasu64 nyanpasu64 reopened this May 29, 2022
@nyanpasu64 nyanpasu64 merged commit 3bb8c25 into Dn-Programming-Core-Management:master May 29, 2022
@nyanpasu64 nyanpasu64 deleted the rewrite-audio-thread branch May 31, 2022 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix stuttering when maximizing other windows with compositing off on Windows 7
1 participant