The crashed previously because:
A VCA is-a Automatable is-a Evoral::ControlSet
After VCA's d'tor completes ~Automatable runs and emits signal to
DropReferences of all master-controls.
This in turn calls SlavableAutomationControl::master_going_away()
for slaved parameters for the given master-control
In ::master_going_away() the weak-pointer reference to the master's
AutomationControl (owned by the destroyed VCA) is still valid.
Execution is in the d'tor of Automatable which is-a ControlSet and
the ContolSet keeps a reference to the Control and hence also to the
AutomationControl which is-a Evoral::Control.
So master_going_away() locks a boost::shared_ptr<ARDOUR::AutomationControl>
which is actually the MuteControl owned by the VCA.
It calls SlavableAutomationControl::remove_master() which
in turn calls MuteControl::pre_remove_master() which uses the
MuteMaster API to retrieve the value. The MuteMaster however is the
VCA that has just been destroyed.
The solution is twofold:
1) emit "drop_references" from the VCA d'tor itself,
before the VCA is destroyed.
2) disconnect a slaved control from the master's drop_references signal
when un-assigning a master-control.
Keep Pannable::value_as_string() for now. That is another inconsistency
which needs cleaning up. GUI StereoPanner and MonoPanner print
the value as they see fit, the panner-plugin provided formatting
is not used.
Probably due to historical reasons, there are two APIs to format a
control's value. In all both variants end up calling either
ARDOUR::value_as_string() or the Controllable's formatting function
(except for panners).
TempoMap::get_grid() supplies a list of beat positions, leaving the lines
to work out any subdivision positions.
This is fine, unless a tempo section falls in between beats.
Use a BeatsFramesConverter along with a quarter note position
(in the BBTPointsList) to make this easier.
Since 478f26b2ad, transport_rolling() is only true when actually rolling.
Count-in is a no-roll process (don't move playhead, no playhead UI
position interpolation 55b8b448).
But transport isn't exactly stopped either (preparing to roll), so
during count-in transport_stopped() == transport_rolling() == false.
Previously there were large spurious spikes in the signal when
the bandwidth parameter was adjusted on a pure sine tone
for the peaking circuits. This has been *greatly* reduced if not
eliminated by fixing a typo in two of the equations.
If the parameters change too slowly the filter may never get updated. Indeed,
in spite of v_f0, v_g or v_bw being updated, set_params may never be called,
thus v_filter never updated.
Useful as temporary buffer: This allows a controllable to
get a master's automation-curve and combine it with its own
(gain, trim, send) automation buffer.