Re-think playback caching of track events
Reading the live data used by the UI leads to threading problems (reading notes while notes are edited, etc.). Before, we used to stop the engine on each edit which causes bad UX like #4180 . Maybe have the audio threads use a cached structure of the data to play back and have a background caching thread (`ProcessorCacheGenService`? that accepts work requests like these) that just swaps the DSP pointer when the new cache is ready. The cache should be extremely dumb, machine-friendly and not know about the project counter-parts (e.g., maybe use pure MIDI sequence for MIDI regions). Or maybe make cache-setting possible on a more fundamental level (in GraphNode) so the whole processing graph doesn't need to know about actual project structures at all and can be completely independent? Maybe even add callbacks on GraphNode for fetching what to play.
task