Fix crash when removing master-bus output channels #8371

Previously when the master-bus had more outputs than inputs,
Ardour crashed when the monitor-section was set up.

Removing a master-bus output port calls
  Route::output_change_handler (master-bus)
 -> Session::reset_monitor_section
which first removes the corresponding monitor-section input,
then output port. The latter triggers
  ARDOUR::Route::output_change_handler (monitor-bus).

All with the process-lock held, so at this point in time Ardour
has removed the port-reference but the port still exists in the
backend.

Now the monitor-bus processors are re-configured and
the channel-count is updated. The port that was just removed
and triggered the ::output_change_handler() callback is
re-created.

unable to create port 'Monitor/audio_out 2': failed constructor

This fix changes the monitor-section to use strict-i/o (for plugins)
and also use master-bus output (not input) when configuring
processors.
This commit is contained in:
Robin Gareus 2020-08-19 22:26:36 +02:00
parent 481cf37052
commit aa69fe49f5
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -147,7 +147,7 @@ int
Route::init ()
{
/* default master bus to use strict i/o */
if (is_master()) {
if (is_master() || is_monitor ()) {
_strict_io = true;
}
@ -1783,11 +1783,14 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err)
* by calling _output->ensure_io()
*/
if (!is_master() && _session.master_out () && in.n_audio() > 0) {
/* ..but at least as many as there are master-inputs, if
* the delivery is dealing with audio */
// XXX this may need special-casing for mixbus (master-outputs)
// and should maybe be a preference anyway ?!
out = ChanCount::max (in, _session.master_out ()->n_inputs ());
if (!is_monitor()) {
/* ..but at least as many as there are master-inputs, if
* the delivery is dealing with audio */
out = ChanCount::max (in, _session.master_out ()->n_inputs ());
} else {
/* monitor-bus follows the master-bus' output */
out = ChanCount::max (in, _session.master_out ()->n_outputs ());
}
} else {
out = in;
}