... See ultimate origin of some of the deleted lines at 4724c6a
Whatever change it is that needs loading by LoadPrefs -- do it instead right
after any possibility of changes to the relevant preferences, in the Commit()
functions of SpectrumPrefs and WaveforPrefs
... Such switches were in the TCP context menu for wave tracks,
SetTrackVisualsCommand, Nyquist (choosing the string for 'view property of
*tracks*), and the Tracks preferences panel.
This will allow easier, non-intrusive addition of other kinds of track
visualizations.
... in Wave track context menu and SetTrackVisualsCommand
Instead, discover them through a registry.
This eliminates some duplication of string constants and prepares for
non-intrusive generalization to more kinds of sub-views.
This makes the command agnostic about which subview types are known, but the
context menu still has special case treatment for Spectrogram Settings and
Wave Colors.
... To be consistent with the rearranging of sub-views, and with general UI
guidelines.
The hover cursor is an open hand, and the dragging cursor is the closed hand.
... consistently with the drop-down menu, and now the Tracks Preferences too.
Only distinguish Waveform and Spectrogram and nil.
See also commit e3d9fd9.
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().
... Regression happened at 3f1fd8ced0fb5fe617ad2dd7808cd1ae2ca2c0f3
The heights were written to file, but not read back again.
This fix was done carefully to avoid making dependency cycles. We don't want
Track to depend on TrackView or TrackControls.
It's not great that LabelTrack, NoteTrack, TimeTrack, and WaveTrack now have
those dependencies, but at least they don't make cycles.
It would be better to figure out how to attach the view and controls to the
track with ClientData, then just invoke BuildAll to repopulate the view and
controls, so that they are non-null when you reach
Track::HandleCommonXMLAttribute.