... This makes it impossible to forget to include the EXPERIMENTAL definitions
(such as when cutting and pasting code) and so get unintended quiet changes of
behavior.
The EXPERIMENTAL flags are now specified instead in new file Experimental.cmake
Currently AudioIoCallback::ScrubState::Get(), inserts a period of silence the first time it's called because at this time Scrubber::ContinueScrubbingPoll() has not been called, and so message.end has not been set to an appropriate value.
In the case of keyboard scrubbing and play-at-speed, the initial speed is already known, so message.end can be set to this value, removing the need for an initial silence.
The start of keyboard scrubbing and play-at-speed are now faster (the latter very much faster).
Problem:
On Windows, after 50ms, there is a short period of roughly zero introduced into the output. On Linux, there is also a spike which sounds like a crackle.
In AudioIO::FillBuffers(), Mixer::SetTimesAndSpeed() is called, which sets mT0 and mT1 to a small interval.
In Mixer::MixVariableRates(), all the samples in the interval are used, which means the Resample::Process() is called with last equal to true.
So when Mixer::MixVariableRates() is called again, the resampler is being reused after a call to Process() in which last is true.
It is not stated in the soxr documentation if the resampler will produce valid results in this case, and it's only the scrubbing code which does this.
I think this is the problem, and so the partial fix below avoids this happening.
Partial fix for play-at-speed and keyboard scrubbing:
For these, there is no need to reset the values of mT0 and mT1. (There is no need to allow for the sample position being used to potentially jump around.)
So for these cases, Mixer::SetSpeed() is called, rather than Mixer::SetTimesAndSpeed().
... so that DeviceManager, DeviceToolbar, and PrefsDialog do not depend directly
on AudioIO.
But no function in the base class for starting streams, which would require
mention of Track types, which we want to avoid.
... New files, but (almost) empty; don't use the global variable gAudioIO,
but use one of two accessor function names (which are the same function for
now).
AudioIOBase will have fewer dependencies than AudioIO -- in particular, no
dependency on tracks.
It won't include StartStream. It will contain functions to query the
present state of streams, and device capabilities.