13
0

livetrax signal flow redesign

Rather than a send to the master outs, and the _main_outs delivery to physical outputs,
we now use a send to the physical outs and _main_outs to Master (as in mainline ardour)
This commit is contained in:
Paul Davis 2024-05-14 12:27:52 -06:00
parent b3a2745227
commit c8797bdd5c
14 changed files with 100 additions and 203 deletions

View File

@ -57,11 +57,11 @@ public:
Aux = 0x10,
/* foldback - internal send used only to deliver to a personal monitor bus */
Foldback = 0x20,
/* master send - used only with LiveTrax, delivers to master bus */
MasterSend = 0x40
/* direct outs - used only with LiveTrax, delivers to master bus */
DirectOuts = 0x40
};
static bool role_requires_output_ports (Role r) { return r == Main || r == Send || r == Insert; }
static bool role_requires_output_ports (Role r) { return r == Main || r == Send || r == Insert || r == DirectOuts; }
bool does_routing() const { return true; }

View File

@ -46,8 +46,7 @@ public:
PostFader = 0x2, ///< mute all post-fader sends
Listen = 0x4, ///< mute listen out
Main = 0x8, ///< mute main out
SurroundSend = 0x10, ///< mute surround send (if any)
MasterSend = 0x20 ///< mute master send (LiveTrax only)
SurroundSend = 0x10 ///< mute surround send (if any)
};
static const MutePoint AllPoints;

View File

@ -129,7 +129,6 @@ CONFIG_VARIABLE (bool, mute_affects_post_fader, "mute-affects-post-fader", true)
CONFIG_VARIABLE (bool, mute_affects_control_outs, "mute-affects-control-outs", true)
CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
CONFIG_VARIABLE (bool, mute_affects_surround_sends, "mute-affects-surround-sends", true)
CONFIG_VARIABLE (bool, mute_affects_master_sends, "mute-affects-master-sends", true)
CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
CONFIG_VARIABLE (ListenPosition, listen_position, "listen-position", AfterFaderListen)
CONFIG_VARIABLE (PFLPosition, pfl_position, "pfl-position", PFLFromAfterProcessors)

View File

@ -199,10 +199,10 @@ public:
void enable_monitor_send ();
void enable_surround_send ();
void enable_master_send ();
void enable_direct_outs ();
void remove_monitor_send ();
void remove_surround_send ();
void remove_master_send ();
void remove_direct_outs ();
int add_aux_send (std::shared_ptr<Route>, std::shared_ptr<Processor>);
int add_foldback_send (std::shared_ptr<Route>, bool post_fader);
@ -287,14 +287,14 @@ public:
std::shared_ptr<Delivery> main_outs() const { return _main_outs; }
std::shared_ptr<InternalReturn> internal_return() const { return _intreturn; }
std::shared_ptr<MonitorProcessor> monitor_control() const { return _monitor_control; }
std::shared_ptr<InternalSend> master_send() const { return _master_send; }
std::shared_ptr<Send> direct_outs() const { return _direct_outs; }
std::shared_ptr<Send> internal_send_for (std::shared_ptr<const Route> target) const;
void add_internal_return ();
void add_send_to_internal_return (InternalSend *);
void remove_send_from_internal_return (InternalSend *);
void listen_position_changed ();
std::shared_ptr<CapturingProcessor> add_export_point(/* Add some argument for placement later */);
void add_master_send (std::shared_ptr<Route>);
void add_direct_outs (std::shared_ptr<Route>);
/** A record of the stream configuration at some point in the processor list.
* Used to return where and why an processor list configuration request failed.
@ -701,9 +701,9 @@ protected:
std::shared_ptr<PeakMeter> _meter;
std::shared_ptr<PolarityProcessor> _polarity;
std::shared_ptr<TriggerBox> _triggerbox;
std::shared_ptr<InternalSend> _master_send;
std::shared_ptr<Send> _direct_outs;
void create_master_send ();
void create_direct_outs ();
bool _volume_applies_to_output;

View File

@ -2260,7 +2260,6 @@ private:
void setup_route_monitor_sends (bool enable, bool need_process_lock);
void setup_route_surround_sends (bool enable, bool need_process_lock);
void setup_route_master_sends (bool enable, bool need_process_lock);
int find_all_sources (std::string path, std::set<std::string>& result);
int find_all_sources_across_snapshots (std::set<std::string>& result, bool exclude_this_snapshot);

View File

@ -57,7 +57,8 @@ bool Delivery::panners_legal = false;
Delivery::Delivery (Session& s, std::shared_ptr<IO> io, std::shared_ptr<Pannable> pannable,
std::shared_ptr<MuteMaster> mm, const string& name, Role r)
: IOProcessor(s, std::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : std::shared_ptr<IO>()), name, Temporal::TimeDomainProvider (Temporal::AudioTime), (r == Send || r == Aux || r == Foldback))
: IOProcessor(s, std::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : std::shared_ptr<IO>()), name, Temporal::TimeDomainProvider (Temporal::AudioTime),
(r == Send || r == Aux || r == Foldback || r == DirectOuts))
, _role (r)
, _output_buffers (new BufferSet())
, _current_gain (GAIN_COEFF_ZERO)
@ -67,7 +68,7 @@ Delivery::Delivery (Session& s, std::shared_ptr<IO> io, std::shared_ptr<Pannable
{
if (pannable) {
bool is_send = false;
if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback|Delivery::MasterSend)) {
if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback|Delivery::DirectOuts)) {
is_send = true;
}
_panshell = std::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, *this, is_send));
@ -83,7 +84,7 @@ Delivery::Delivery (Session& s, std::shared_ptr<IO> io, std::shared_ptr<Pannable
/* deliver to a new IO object */
Delivery::Delivery (Session& s, std::shared_ptr<Pannable> pannable, std::shared_ptr<MuteMaster> mm, const string& name, Role r)
: IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name, "", DataType::AUDIO, (r == Send || r == Aux || r == Foldback))
: IOProcessor(s, false, (role_requires_output_ports (r) ? true : false), name, "", DataType::AUDIO, (r == Send || r == Aux || r == Foldback || r == DirectOuts))
, _role (r)
, _output_buffers (new BufferSet())
, _current_gain (GAIN_COEFF_ZERO)
@ -93,7 +94,7 @@ Delivery::Delivery (Session& s, std::shared_ptr<Pannable> pannable, std::shared_
{
if (pannable) {
bool is_send = false;
if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback|Delivery::MasterSend)) {
if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback|Delivery::DirectOuts)) {
is_send = true;
}
_panshell = std::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, *this, is_send));
@ -132,6 +133,8 @@ Delivery::display_name () const
case Listen:
return _("listen");
break;
case DirectOuts:
return _("direct");
case Send:
case Insert:
default:
@ -218,7 +221,7 @@ Delivery::configure_io (ChanCount in, ChanCount out)
see ::can_support_io_configuration() for comments
*/
if (_role == Main) {
if (_role == Main || _role == DirectOuts) {
if (_output) {
if (_output->n_ports() != out) {
@ -291,7 +294,6 @@ Delivery::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample
if (tgain != _current_gain) {
/* target gain has changed */
_current_gain = Amp::apply_gain (bufs, _session.nominal_sample_rate(), nframes, _current_gain, tgain);
} else if (fabsf (tgain) < GAIN_COEFF_SMALL) {
@ -323,7 +325,7 @@ Delivery::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample
if (_amp) {
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_sample, end_sample, nframes);
_amp->run (bufs, start_sample, end_sample, speed, nframes, true);
// _amp->run (bufs, start_sample, end_sample, speed, nframes, true);
}
// Panning
@ -601,9 +603,7 @@ Delivery::target_gain ()
case Listen:
mp = MuteMaster::Listen;
break;
case MasterSend:
mp = MuteMaster::MasterSend;
break;
case DirectOuts:
case Send:
case Insert:
case Aux:
@ -628,6 +628,22 @@ Delivery::target_gain ()
desired_gain = GAIN_COEFF_ZERO;
}
#ifdef LIVETRAX
if (_role == DirectOuts) {
if (_session.virtual_soundcheck()) {
/* leave desired_gain alone */
} else {
desired_gain = GAIN_COEFF_ZERO;
}
} else if (_role == Main) {
if (!_session.virtual_soundcheck()) {
/* leave desired_gain alone */
} else {
desired_gain = GAIN_COEFF_ZERO;
}
}
#endif
if (_polarity_control && _polarity_control->get_value () > 0) {
desired_gain *= -1;
}

View File

@ -732,7 +732,7 @@ setup_enum_writer ()
REGISTER_CLASS_ENUM (Delivery, Main);
REGISTER_CLASS_ENUM (Delivery, Aux);
REGISTER_CLASS_ENUM (Delivery, Foldback);
REGISTER_CLASS_ENUM (Delivery, MasterSend);
REGISTER_CLASS_ENUM (Delivery, DirectOuts);
REGISTER_BITS (_Delivery_Role);
REGISTER_CLASS_ENUM (MuteMaster, PreFader);
@ -740,7 +740,6 @@ setup_enum_writer ()
REGISTER_CLASS_ENUM (MuteMaster, Listen);
REGISTER_CLASS_ENUM (MuteMaster, Main);
REGISTER_CLASS_ENUM (MuteMaster, SurroundSend);
REGISTER_CLASS_ENUM (MuteMaster, MasterSend);
REGISTER_BITS (_MuteMaster_MutePoint);
REGISTER_CLASS_ENUM (IO, Input);

View File

@ -141,12 +141,6 @@ InternalSend::init_gain ()
if (_role == Listen) {
/* send to monitor bus is always at unity */
gain_control ()->set_value (GAIN_COEFF_UNITY, PBD::Controllable::NoGroup);
} else if (_role == MasterSend) {
if (_session.virtual_soundcheck()) {
gain_control ()->set_value (GAIN_COEFF_ZERO, PBD::Controllable::NoGroup);
} else {
gain_control ()->set_value (GAIN_COEFF_UNITY, PBD::Controllable::NoGroup);
}
} else {
/* aux sends start at -inf dB */
gain_control ()->set_value (GAIN_COEFF_ZERO, PBD::Controllable::NoGroup);
@ -175,10 +169,6 @@ InternalSend::use_target (std::shared_ptr<Route> sendto, bool update_name)
_send_delay->configure_io (_send_to->internal_return ()->input_streams (), _send_to->internal_return ()->input_streams ());
reset_panner ();
if (_role == MasterSend) {
_panshell->set_linked_to_route (false);
}
if (update_name) {
set_name (sendto->name ());
}

View File

@ -521,7 +521,6 @@ IO::ensure_io (ChanCount count, bool clear, void* src)
#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
#endif
return ensure_ports (count, clear, src);
}

View File

@ -39,7 +39,7 @@ using namespace std;
const string MuteMaster::xml_node_name (X_("MuteMaster"));
const MuteMaster::MutePoint MuteMaster::AllPoints = MuteMaster::MutePoint(
PreFader|PostFader|Listen|Main|SurroundSend|MasterSend);
PreFader|PostFader|Listen|Main|SurroundSend);
MuteMaster::MuteMaster (Session& s, Muteable& m, const std::string&)
: SessionHandleRef (s)
@ -70,10 +70,6 @@ MuteMaster::MuteMaster (Session& s, Muteable& m, const std::string&)
if (Config->get_mute_affects_surround_sends ()) {
_mute_point = MutePoint (_mute_point | SurroundSend);
}
if (Config->get_mute_affects_master_sends ()) {
_mute_point = MutePoint (_mute_point | MasterSend);
}
}
void

View File

@ -281,27 +281,10 @@ Route::init ()
_volume.reset (new Amp (_session, X_("LAN Amp"), _volume_control, false));
_volume->set_display_to_user (false);
_volume->deactivate ();
if (Profile->get_livetrax()) {
_intreturn.reset (new InternalReturn (_session, tdp));
_intreturn->activate ();
}
}
_main_outs->activate ();
if (Profile->get_livetrax() && is_track()) {
/* We need a separate gain control the main outs, because we
* will use that when switching between stereo outs and direct
* outs for virtual soundcheck
*/
_volume_control.reset (new GainControl (_session, MainOutVolume));
_volume_control->set_flag (Controllable::NotAutomatable);
_main_outs->set_gain_control (_volume_control);
_volume_control->set_value (_session.virtual_soundcheck() ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO, PBD::Controllable::NoGroup);
}
if (is_monitor()) {
/* where we listen to tracks */
_intreturn.reset (new MonitorReturn (_session, tdp));
@ -583,6 +566,8 @@ Route::process_output_buffers (BufferSet& bufs,
}
}
// std::cerr << name() << " before " << (*i)->display_name() << " silent data: " << bufs.silent_data() << std::endl;
if (speed < 0) {
(*i)->run (bufs, start_sample + latency, end_sample + latency, pspeed, nframes, *i != _processors.back());
} else {
@ -591,6 +576,8 @@ Route::process_output_buffers (BufferSet& bufs,
bufs.set_count ((*i)->output_streams());
// std::cerr << name() << " after " << (*i)->display_name() << " silent data: " << bufs.silent_data() << std::endl;
if (re_inject_oob_data) {
write_out_of_band_data (bufs, nframes);
}
@ -1480,7 +1467,7 @@ Route::is_internal_processor (std::shared_ptr<Processor> p) const
(_triggerbox && p == _triggerbox) ||
(_surround_return && p == _surround_return) ||
(_surround_send && p == _surround_send) ||
(_master_send && p == _master_send) ||
(_direct_outs && p == _direct_outs) ||
(is_master() && p == _intreturn)) {
return true;
}
@ -3339,11 +3326,11 @@ Route::set_processor_state (XMLNode const& node, int version, XMLProperty const*
if (prop->value() == "intsend") {
XMLProperty const * role_prop = node.property (X_("role"));
if (role_prop && role_prop->value() == "MasterSend") {
if (role_prop && role_prop->value() == "DirectOuts") {
if (Profile->get_livetrax()) {
create_master_send ();
assert (_master_send);
processor = _master_send;
create_direct_outs ();
assert (_direct_outs);
processor = _direct_outs;
}
} else {
processor.reset (new InternalSend (_session, _pannable, _mute_master, std::dynamic_pointer_cast<ARDOUR::Route>(shared_from_this()), std::shared_ptr<Route>(), Delivery::Aux, true));
@ -3540,14 +3527,7 @@ Route::remove_monitor_send ()
}
void
Route::create_master_send ()
{
_master_send.reset (new InternalSend (_session, pannable(), _mute_master, std::dynamic_pointer_cast<Route> (shared_from_this()), _session.master_out(), Delivery::MasterSend, false));
_master_send->set_display_to_user (false);
}
void
Route::enable_master_send()
Route::enable_direct_outs ()
{
if (!Profile->get_livetrax()) {
return;
@ -3556,13 +3536,13 @@ Route::enable_master_send()
/* Caller must hold process lock */
assert (!AudioEngine::instance()->process_lock().trylock());
/* master sends are for tracks only */
/* direct outs are for tracks only */
assert (is_track());
/* make sure we have one */
if (!_master_send) {
/* An internal send with its own panner to deliver to the master bus */
create_master_send ();
if (!_direct_outs) {
/* An external send to deliver to physical outputs */
create_direct_outs ();
}
/* set it up */
@ -3570,15 +3550,20 @@ Route::enable_master_send()
}
void
Route::remove_master_send ()
Route::create_direct_outs ()
{
/* caller needs to hold process lock */
if (!_master_send) {
return;
/* caller must hold process lock */
_direct_outs.reset (new Send (_session, pannable(), mute_master(), Delivery::DirectOuts, false));
_direct_outs->set_display_to_user (false);
_direct_outs->activate ();
try {
_direct_outs->output()->ensure_io (ChanCount (DataType::AUDIO, input()->ports().num_ports(DataType::AUDIO)), false, this);
} catch (AudioEngine::PortRegistrationFailure& err) {
error << string_compose (_("Cannot set up direct outs: %1"), err.what()) << endmsg;
_direct_outs.reset ();
}
ProcessorStreams err;
remove_processor (_master_send, &err, false);
_master_send.reset ();
}
/** Add an aux send to a route.
@ -4935,10 +4920,6 @@ Route::panner() const
{
/* may return null ! */
if (Profile->get_livetrax() && _master_send) {
return _master_send->panner_shell()->panner();
}
return _main_outs->panner_shell()->panner();
}
@ -4947,10 +4928,6 @@ Route::panner_shell() const
{
/* may return null ! */
if (Profile->get_livetrax() && _master_send) {
return _master_send->panner_shell();
}
return _main_outs->panner_shell();
}
@ -5375,6 +5352,12 @@ Route::setup_invisible_processors ()
new_processors.insert (amp, _meter);
}
/* For livetrax, pre-fader direct outs */
if (Profile->get_livetrax() && _direct_outs) {
new_processors.insert (amp, _direct_outs);
}
/* SURROUND SEND */
if (_surround_send) {
new_processors.push_back (_surround_send);

View File

@ -189,11 +189,8 @@ RouteGroup::add (std::shared_ptr<Route> r)
_solo_group->add_control (r->solo_control());
_mute_group->add_control (r->mute_control());
if (ARDOUR::Profile->get_livetrax()) {
_gain_group->add_control (r->master_send()->gain_control());
} else {
_gain_group->add_control (r->gain_control());
}
_gain_group->add_control (r->gain_control());
std::shared_ptr<Track> trk = std::dynamic_pointer_cast<Track> (r);
if (trk) {
_rec_enable_group->add_control (trk->rec_enable_control());
@ -264,11 +261,8 @@ RouteGroup::remove (std::shared_ptr<Route> r)
_solo_group->remove_control (r->solo_control());
_mute_group->remove_control (r->mute_control());
if (Profile->get_livetrax()) {
_gain_group->remove_control (r->master_send()->gain_control());
} else {
_gain_group->remove_control (r->gain_control());
}
_gain_group->remove_control (r->gain_control());
std::shared_ptr<Track> trk = std::dynamic_pointer_cast<Track> (r);
if (trk) {
_rec_enable_group->remove_control (trk->rec_enable_control());

View File

@ -73,9 +73,6 @@ Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot, bool ignore_b
return string ();
}
switch (r) {
case Delivery::Aux:
if (Profile->get_livetrax()) {
@ -91,8 +88,8 @@ Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot, bool ignore_b
return string_compose (_("send %1"), (bitslot = s.next_send_id ()));
case Delivery::Foldback:
return string_compose (_("foldback %1"), (bitslot = s.next_aux_send_id ()));
case Delivery::MasterSend:
return string_compose (_("master %1"), (bitslot = s.next_aux_send_id ()));
case Delivery::DirectOuts:
return string_compose (_("directs %1"), (bitslot = s.next_aux_send_id ()));
default:
fatal << string_compose (_("programming error: send created using role %1"), enum_2_string (r)) << endmsg;
abort(); /*NOTREACHED*/
@ -108,14 +105,8 @@ Send::Send (Session& s, std::shared_ptr<Pannable> p, std::shared_ptr<MuteMaster>
{
//boost_debug_shared_ptr_mark_interesting (this, "send");
if (role() == MasterSend) {
std::shared_ptr<AutomationList> gl (new AutomationList (Evoral::Parameter (GainAutomation), *this));
set_gain_control (std::shared_ptr<GainControl> (new GainControl (_session, Evoral::Parameter (GainAutomation), gl)));
} else {
std::shared_ptr<AutomationList> gl (new AutomationList (Evoral::Parameter (BusSendLevel), *this));
set_gain_control (std::shared_ptr<GainControl> (new GainControl (_session, Evoral::Parameter (BusSendLevel), gl)));
}
std::shared_ptr<AutomationList> gl (new AutomationList (Evoral::Parameter (BusSendLevel), *this));
set_gain_control (std::shared_ptr<GainControl> (new GainControl (_session, Evoral::Parameter (BusSendLevel), gl)));
gain_control ()->set_flag (Controllable::InlineControl);
add_control (gain_control ());
@ -256,6 +247,7 @@ Send::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, do
}
if (!check_active()) {
std::cerr << "send " << display_name() << " not active\n";
_meter->reset ();
_output->silence (nframes);
return;
@ -405,16 +397,16 @@ Send::set_state (const XMLNode& node, int version)
*/
if ((prop = node.property ("bitslot")) == 0) {
if (_role == Delivery::Aux || _role == Delivery::Foldback || _role == Delivery::MasterSend) {
if (_role == Delivery::Aux || _role == Delivery::Foldback || _role == Delivery::DirectOuts) {
_bitslot = _session.next_aux_send_id ();
} else if (_role == Delivery::Send) {
} else if (_role == Delivery::Send || _role == Delivery::DirectOuts) {
_bitslot = _session.next_send_id ();
} else {
// bitslot doesn't matter but make it zero anyway
_bitslot = 0;
}
} else {
if (_role == Delivery::Aux || _role == Delivery::Foldback || _role == Delivery::MasterSend) {
if (_role == Delivery::Aux || _role == Delivery::Foldback) {
_session.unmark_aux_send_id (_bitslot);
_bitslot = string_to<uint32_t>(prop->value());
_session.mark_aux_send_id (_bitslot);
@ -567,7 +559,7 @@ Send::set_name (const string& new_name)
bool
Send::display_to_user () const
{
if (_role == MasterSend && Profile->get_livetrax()) {
if (_role == Delivery::DirectOuts && Profile->get_livetrax()) {
return false;
}

View File

@ -1298,35 +1298,6 @@ Session::setup_route_monitor_sends (bool enable, bool need_process_lock)
}
}
void
Session::setup_route_master_sends (bool enable, bool need_process_lock)
{
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock (), Glib::Threads::NOT_LOCK);
if (need_process_lock) {
/* Hold process lock while doing this so that we don't hear bits and
* pieces of audio as we work on each route.
*/
lx.acquire();
}
std::shared_ptr<RouteList const> rl = routes.reader ();
ProcessorChangeBlocker pcb (this, false /* XXX */);
for (auto const& x : *rl) {
if (x->is_track()) {
if (enable) {
x->enable_master_send ();
} else {
x->remove_master_send ();
}
}
}
if (auditioner) {
auditioner->connect ();
}
}
void
Session::reset_monitor_section ()
{
@ -3679,9 +3650,6 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
}
ensure_stripable_sort_order ();
if (Profile->get_livetrax()) {
reassign_track_numbers ();
}
}
if (!loading()) {
@ -3701,12 +3669,13 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
}
}
if (Profile->get_livetrax ()) {
if (Profile->get_livetrax()) {
for (auto & r : new_routes) {
if (r->is_track()) {
r->enable_master_send ();
r->enable_direct_outs ();
}
}
reassign_track_numbers ();
}
}
}
@ -7912,6 +7881,13 @@ Session::livetrax_auto_connect ()
for (auto & r : *rl) {
if (!r->is_auditioner()) {
if ((t = std::dynamic_pointer_cast<Track> (r))) {
/* skip this if 1 or more tracks do not have
* direct outs set up yet.
*/
if (!t->direct_outs()) {
std::cerr << "skip LAC, direct outs missing\n";
return;
}
tracks.push_back (t);
}
}
@ -7924,7 +7900,6 @@ Session::livetrax_auto_connect ()
for (auto & t : tracks) {
t->input()->disconnect (this);
t->output()->disconnect (this);
uint32_t n;
@ -7933,9 +7908,9 @@ Session::livetrax_auto_connect ()
t->input()->connect (t->input()->ports().port (DataType::AUDIO, c), *ip, this);
++ip;
}
n = t->output()->n_ports().n_audio();
n = t->direct_outs()->output()->n_ports().n_audio();
for (uint32_t c = 0; c < n && op != physoutputs.end(); ++c) {
t->output()->connect (t->output()->ports().port (DataType::AUDIO, c), *op, this);
t->direct_outs()->output()->ports().port (DataType::AUDIO, c)->connect (*op);
++op;
}
}
@ -7948,10 +7923,12 @@ Session::auto_connect (const AutoConnectRequest& ar)
if (!route) {
if (Profile->get_livetrax() && ar.all) {
/* This being LiveTrax, we will connect all tracks at once */
/* This being LiveTrax, we will connect all tracks'
* direct outs at once
*/
livetrax_auto_connect ();
return;
}
return;
}
if (loading()) {
@ -8392,53 +8369,7 @@ Session::set_virtual_soundcheck (bool yn)
return;
}
std::shared_ptr<RouteList const> rl = routes.reader ();
std::shared_ptr<AutomationControlList> master_sends (new AutomationControlList);
std::shared_ptr<AutomationControlList> main_outs (new AutomationControlList);
std::vector<double> values;
for (auto & route : *rl) {
if (!route->is_track()) {
continue;
}
master_sends->push_back (route->master_send()->gain_control());
main_outs->push_back (route->main_outs()->gain_control());
if (yn) {
/* Save current values for master send gain before we turn it off */
double g = route->master_send()->gain_control()->get_value();
auto result = livetrax_vs_msend_values.insert (std::make_pair (route->id(), g));
if (!result.second) {
result.first->second = g;
}
} else {
/* Lookup master send gain values from before we turned them off */
std::map<PBD::ID,double>::iterator v = livetrax_vs_msend_values.find (route->id());
if (v == livetrax_vs_msend_values.end()) {
/* not found - use a default */
values.push_back (1.0);
} else {
values.push_back (v->second);
}
}
}
if (!master_sends->empty()) {
if (yn) {
set_controls (master_sends, 0., PBD::Controllable::NoGroup);
set_controls (main_outs, 1., PBD::Controllable::NoGroup);
} else {
assert (master_sends->size() == values.size());
set_controls_with_values (master_sends, values, PBD::Controllable::NoGroup);
set_controls (main_outs, 0., PBD::Controllable::NoGroup);
}
}
_virtual_soundcheck = yn;
VirtualSoundCheckChanged (yn); /* EMIT SIGNAL */
}