From aa69fe49f51df821b8b9d072ca69c0db73edfde0 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 19 Aug 2020 22:26:36 +0200 Subject: [PATCH] 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. --- libs/ardour/route.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index fe24a5a120..cadee321de 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -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; }