This one took me by surprise. When in Song mode and Looping disable playback did not reach the very end of the song but stopped one "lookahead" before. Since this is a conceptional flaw predating the rewriting of the AudioEngine this might have always been the case. But I have not checked. In any case only the last note on a very fine resolution is affected.
The problem was as follows. In the AudioEngine there are two distinct position: a playback position (used by everything outside the audio engine) and a queuing one. The job of the latter is ahead of the transport position and checks for upcoming notes and patches their starting position (as we allow them to lead/lag). These two position also existed (more or less) before the rewrite of the engine. They were just mixed up and dirty most of the time. Now, traditionally the end of the song was determined in AudioEngine::updateNoteQueue. But this function acts on the queuing position. This means whenever the end of the song was reported, transport/playback was not finished yet but had to stop too. If there were still notes waiting in the note queue ahead of the playback position, they were not handed to the Sampler and MIDI output.
Now, AudioEngine::updateNoteQueue will just stop enqueuing notes (but still update the queuing position) whenever the end of the song is reached. Stopping playback is done at the end of AudioEngine::audioEngine_process in case the transport/playback position reached the end. And it is done after all audio processing etc. All notes are now played back.
This one took me by surprise. When in Song mode and Looping disable playback did not reach the very end of the song but stopped one "lookahead" before. Since this is a conceptional flaw predating the rewriting of the AudioEngine this might have always been the case. But I have not checked. In any case only the last note on a very fine resolution is affected.
The problem was as follows. In the
AudioEngine
there are two distinct position: a playback position (used by everything outside the audio engine) and a queuing one. The job of the latter is ahead of the transport position and checks for upcoming notes and patches their starting position (as we allow them to lead/lag). These two position also existed (more or less) before the rewrite of the engine. They were just mixed up and dirty most of the time. Now, traditionally the end of the song was determined inAudioEngine::updateNoteQueue
. But this function acts on the queuing position. This means whenever the end of the song was reported, transport/playback was not finished yet but had to stop too. If there were still notes waiting in the note queue ahead of the playback position, they were not handed to the Sampler and MIDI output.Now,
AudioEngine::updateNoteQueue
will just stop enqueuing notes (but still update the queuing position) whenever the end of the song is reached. Stopping playback is done at the end ofAudioEngine::audioEngine_process
in case the transport/playback position reached the end. And it is done after all audio processing etc. All notes are now played back.Addresses #1859