Remove the FIFO thread
Removes the FIFO thread, which was a thread used in the audio engine that wrote chunks of rendered audio buffers to a circular buffer, while the audio callback thread would read from that. Instead, the audio callback is the one rendering the buffers directly and doing any chunking as necessary.
The functionality this thread brought allowed for buffers to be "written ahead" of the audio callback, meaning that the FIFO thread would be rendering buffers as fast it can, stopping when it can't write any more buffers, while the audio callback would be reading them at a fixed interval. However:
- Since the priority of this thread was the same as every other thread running on the system (i.e., not high priority), while the audio callback is commonly thought to run on high priority, it is more likely that the FIFO thread wouldn't have gotten much time to do its task of rendering (i.e., a high priority task). Moving that work into the audio callback is better in this case.
- Even if the FIFO thread had high priority, it would have to compete with the audio callback's high priority as well. If we assume that the FIFO thread had high priority, but just a little bit less than the audio callback, then for buffers like 64, 32, etc, the audio callback thread will be running so frequently that we run the risk of not being able to render any buffers at all since the FIFO thread may not have a large enough time slice.
- The latency wasn't completely determined by the buffer size, but also by how long it took to get this thread running since it was the one rendering the buffers.
- Very strange deadlocks happened because of this thread. For example, simplifying the thread communication in this case fixes #7320.
This PR also greatly simplifies the transmission of buffers between the engine and the audio device. AudioDevice::nextBuffer is a new function that handles and correctly processes the chunks of audio returned by the audio engine, and also manages both interleaved and non-interleaved outputs. This removes a lot of repetitive code in each audio device that originally was handling their configuration on their own.
This PR also makes ALSA use floating-point audio instead of int16.
Changed the PR to still remove the FIFO thread but keep the chunking of the buffer size (to avoid problems with non sample accurate automation but to also fix the problems this thread has caused).
This shoulda had higher priority. @LMMS/testers
Wait the tester role is only for peki?
@LMMS/testers
Reporting!
I'm busy with managing #7477, #7444 and #7366.
Is this making the code more readable without reducing performance? Or is it a performance boosting PR? In any case, great stuff, I'll look at it when I'm done with these three PRs!
This is supposed to solve the performance degradation on master compared to 1.2 and the rare case with deadlocks making a mess, along with the buffer size and automation performance, among other stuff. @sakertooth correct me if I'm wrong. If what i guess is right, this PR has the potential to straighten up a lot of the performance bugs.
Wait the tester role is only for peki?
For the time being, yeah. I think I get rights to review PRs and whatnot, so it's probably not wise to give it away to anyone wanting to test, but I'm not entirely sure about if that's how it behaves, just speculation.
This is supposed to solve the performance degradation on master compared to 1.2 and the rare case with deadlocks making a mess, along with the buffer size and automation performance, among other stuff. @sakertooth correct me if I'm wrong. If what i guess is right, this PR has the potential to straighten up a lot of the performance bugs.
It's mostly to fix deadlock bugs involving this thread waiting forever to close. It's less of a performance benefit (though that could be possible) but more so to simplify the thread communication within the audio pipeline.
So I tested this PR. Exporting works fine, no hearable differences. Playback is still pretty much the same as on master, I made it play the performance intensive part of a song, my phone is still in pain, no noticeable gain or loss there. I had two random crashes but I expect this to be a me problem because well, it's a phone and this mmpz is uhh... a bit tough sometimes. Still on the "me problem" side, usually Equalizer takes a minute to load for the first time, in this PR it takes 30 seconds so it's better, not gonna complain. Now back on playback, the playhead will desync itself from the actual sound after a huge lag spike, but that's a general performance problem, it doesn't have much to do with this PR I think.
Final feedback is this seems good, did Peki test that too ? There could be differences with a computer that can handle heavy workload.
Final feedback is this seems good, did Peki test that too ? There could be differences with a computer that can handle heavy workload.
I don't think Peki has tested this yet, but they're probably busy with other PRs so it's fine. Thank you for testing this for me :+1:
Also, don't understand what is now happening with the chunking mechanism. Is the audio thread processing in chunks of 256 and then outputting to the playback/export at the user defined buffer size? Or is there something I missed.
Sorry, just realized that I didn't answer this question @Rossmaxx. What happens is that the user selects their desired buffer size and audio device to use, and then when LMMS starts, the audio device thread starts, which periodically calls renderNextBuffer, which either returns the latest rendered chunk (256 sample frames per chunk), or calls the overloaded variant for renderNextBuffer to render any buffer size wanted (e.g. 1024 frames). All of the audio devices call the overloaded variant for renderNextBuffer to be able to render any desired buffer size for real-time playback.
There is one thread requesting data periodically. That's it. There are other worker threads that do the actual processing, but this is the only thread requesting data (if not that thread then the export thread). To compare this to before, there was an additional thread, but this was removed, as it was mostly unnecessary and causing issues.
I could test this, if it's ready to be tested, or needs WIP testing. @sakertooth ?
I could test this, if it's ready to be tested, or needs WIP testing. @sakertooth ?
There were merge conflicts, so I'm still working on this. I'll let you know if its ready :+1:
Should be ready @bratpeki.
Please request a review so I see it on the GitHub UI :)
Okay, so, how do I test this?
Okay, so, how do I test this?
See if there's any funny business going on when playing demos/exporting on various audio devices. There shouldn't be any audio glitches, crashes, deadlocks, things of that nature (except for soundio which I believe was already broken in master).
Alright, I'll use it for some time as if it were the real deal, make a few songs, and report anything I see!
PR is currently broken, will be fixed when I make this PR ready for review again.
Applied the fixes, this PR should be good now.
Tested with commit 29a6829, seems to be just fine. I even noticed a performance boost! I believe Rossmaxx mentioned something about fewer deadlocks.
Testing the latest commit.
One of latest commits completly messed up playback on SDL backend on Windows. Only left channel can be heard and right channel is completly silent.
One of latest commits completly messed up playback on SDL backend on Windows. Only left channel can be heard and right channel is completly silent.
Thanks for the heads up. It should be fixed now.
I got a "Bus error (Core dumped)" and can't reliably recreate it. This only happened the first time I tried exporting a project made at a "later" LMMS (MIDI slicing, etc). So it could be tied to that. I'd rebase this to upstream or, because this is a HUGE improvement, just merge and we can make a follow-up PR.
@regulus79 @Rossmaxx please have a look and if all is well, merge
@regulus79 @Rossmaxx please have a look and if all is well, merge
I'm not sure I'm done with this yet.
What do you feel needs to be done? More than happy to wait on it.
Wait never mind I guess it's fine, we can merge but I still might be playing around with the code.
Follow-up PR if needed, then!
I have been thinking of getting back to this, but I'm in the middle of exams. Will take some time.
No objections, and it drives great. Please do final checks and merge! :grin:
EDIT: Spoke too soon, there seems to be an issue with the msvc-x64 check.