This lets us get a more explicit handle on time conversions, and is the main
step towards using actual beat:tick time and getting away from floating point
precision problems.
Fix initial read of discrete MIDI controllers.
Fix spurious note offs when starting to play in the middle of a note.
Faster search for initial event when cached iterator is invalid.
So much for dropping the cached iterator. The iterator is responsible for
handling note offs, so that doesn't work. This design means we have some stuck
note issues at the source read level, but they should be taken care of by the
state tracker anyway.
This should probably hijack the same modifier as the guard points and work the
same on all automation tracks, but I did it this way to not change behaviour of
track automation where a default is much more reasonable.
This cleans up a lot of false-positives in static analysis
and also helps compilers to optimize code paths in general.
(tagging the fatal stingstream operator as ‘noreturn’ is
far less trivial)
Serialization of Session::save_state() will already protect against most of this, but there is really no
good reason why Evoral::SMF's API should require single-threaded/explicit serialization.
Also some work towards tolerating automation controls with no automation list,
towards actually doing something for these cases, though not required just to
fix this crash (MidiTrack::set_parameter_automation_state() avoids those
paths).
It'd be nice if we could use 'ARDOUR::config_dir_name' for this purpose (or perhaps 'PROGRAM_VERSION'). However, neither is implemented widely enough at present to make this practical. Keep an eye on them though, as possible future strategies.
TODO: needs undo. only works in top quarter of automation lane. selection model feels weird sometimes. needs to show gain curve when you are using Range tool
Constrain control points to one per tick (1/1920 beats).
Prior to this it was possible to set two values to the
same time (interpolation and iteration failed).