... when there really is at least one new sample block committed to the table,
which is typically only once in about every six seconds, with the default rate
and sample format.
Also renamed a callback function more aptly, since blocks are not files any
more.
!!! THERE WILL NO DOUBT BE BUGS !!!
This is a big one and there's still several things to
complete. Just want to get this in the wild to start
receiving feedback.
One big thing right now is that it will NOT load pre-aup3
files. An importer is on the way for that.
I got an error when compiling with wxWidgets 3.0.4, because wxPowerResource is undefined.
It seems to me that wxPowerResource has been introduced with wxWidgets 3.1.x branch:
51d715e46d (diff-93a9bace734a8065b203ebd2f670cbe8)
so, it would be worth to check if the feature is supported at compile time.
I don't know how this hasn't been seen before, but Cliff found that
opening Audacity via Commander One would, more often than not, cause
the pause button to enable when you started monitoring.
Seems it was picking up uninitialized memory values, but near as I can
tell, this has been this way for a very long time (like forever). So,
it's possible that I've not completely identified the culprit.
Even so, this should be initialized anyway and Cliff reports that it
does resolve the problem for him.
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).
If one of the keyboard scrubbing keys is being held down, and the other keyboard scrubbing key is pressed:
1. With current behaviour, scrubbing in the other direction only starts when the original key is released - scrubbing stops and then starts in the other direction.
2. With the new behaviour, scrubbing immediately changes direction, and does not stop when the original key is released - scrubbing does not stop and then start again.
New behaviour:
If one of the keyboard scrubbing keys is being held down,
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().
Instead of only when recording (it broke monitoring), now Audacity
will prevent the system from sleeping while any audio I/O is active.
This might be a little strong-handed though and maybe should be a
preference option.
... though in a small cycle with each other, by moving RealtimeEffectManager to
new files, which remain in the big component.
Net loss of 1, the big component now has 27 files
... 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.
... as a preparation for splitting up class AudacityProject.
Use ProjectWindow as an alias for AudacityProject, and fetch it from the
project with a static member function, where certain of its services are used;
pretending they are not the same class.
Use global accessor functions to get wxFrame from the project where only
wxFrame's member functions are needed, so there will be less dependency on
ProjectWindow when it becomes a distinct class.
... Rename it as SetStatus; make it part of AudacityProject not
TrackPanelListener; and use a roundabout event signalling to cause the timer
restart.
Because SetStatus will be one of very few things left in AudacityProject, but
the timer handling will be part of another class decoupled from it.
And TrackPanelListener won't really be needed: TrackPanel will not need to
pretend it doesn't know what an AudacityProject is.