Stage 1: collect play handles and process automation
Collecting play handles
There are two major sources for play handles:
User interaction: If users trigger an play action, UI classes or MIDI event processors call AudioEngine::addPlayHandle if needed
Playing song: AudioEngine::renderNextBuffer calls Song::processNextBuffer to get play handles for the current playback position
To avoid threading issues, AudioEngine::addPlayHandle doesn't add play handles directly; it only queues play handles to process into m_newPlayHandles. Those play handles are added to the play handle list at once at this stage.
AudioEngine::removePlayHandle also work similarly when trying to remove play handles created from the mixer thread in user threads.
Processing automation
Song::processNextBuffer calls Song::processAutomations to process automation. This function calls proper override of TrackContainer::automatedValuesAt and they call TrackContainer::automatedValuesFromTracks with proper arguments.