From d752b3124583c829c5bcb9571c54eff6721c349c Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 6 Apr 2024 21:46:32 -0600 Subject: [PATCH] some basic but incomplete logic for track autoconnect in livetrax --- libs/ardour/ardour/audio_backend.h | 4 +- libs/ardour/audio_backend.cc | 3 + libs/ardour/audioengine.cc | 4 +- libs/ardour/session.cc | 94 ++++++++++++++++++++++++++++-- 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h index 100832275a..276f120782 100644 --- a/libs/ardour/ardour/audio_backend.h +++ b/libs/ardour/ardour/audio_backend.h @@ -858,14 +858,14 @@ public: PBD::TimingStats dsp_stats[NTT]; + void setup_channel_masks (size_t in, size_t out); + protected: AudioBackendInfo& _info; AudioEngine& engine; virtual int _start (bool for_latency_measurement) = 0; - void setup_channel_masks (size_t in, size_t out); - ChannelMask _input_channel_mask; ChannelMask _output_channel_mask; }; diff --git a/libs/ardour/audio_backend.cc b/libs/ardour/audio_backend.cc index 1f485891d6..286ecf78ca 100644 --- a/libs/ardour/audio_backend.cc +++ b/libs/ardour/audio_backend.cc @@ -116,6 +116,9 @@ AudioBackend::setup_channel_masks (size_t in, size_t out) { _input_channel_mask.assign (in, true); _output_channel_mask.assign (out, true); + + _input_channel_mask[2] = false; + _output_channel_mask[3] = false; } } // namespace ARDOUR diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index fc052ef749..11ba09508c 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -1075,13 +1075,15 @@ AudioEngine::start (bool for_latency) } if (!for_latency) { + /* Do this here so we do not have to add it to every backend */ + _backend->setup_channel_masks (_backend->input_channels(), _backend->output_channels()); + /* Call the library-wide ::init_post_engine() before emitting * running to ensure that its tasks are complete before any * signal handlers execute. PBD::Signal does not ensure * ordering of signal handlers so even if ::init_post_engine() * is connected first, it may not run first. */ - ARDOUR::init_post_engine (_start_cnt); Running (_start_cnt); /* EMIT SIGNAL */ diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 93190f1dac..c4322a5d6e 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3551,7 +3551,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool * we will resort when done. */ - if (!_monitor_out && !loading() && !input_auto_connect && !output_auto_connect) { + if (!_monitor_out && !loading() && !input_auto_connect && !output_auto_connect && !Profile->get_livetrax()) { resort_routes_using (r); } } @@ -7809,17 +7809,99 @@ Session::livetrax_auto_connect (std::shared_ptr route) get_physical_ports (physinputs, physoutputs, DataType::AUDIO); - const vector::size_type n = route->track_number() - 1; + AudioBackend::ChannelMask const & input_channel_mask ( _engine.current_backend()->input_channel_mask()); + AudioBackend::ChannelMask const & output_channel_mask ( _engine.current_backend()->output_channel_mask()); route->input()->disconnect (this); route->output()->disconnect (this); - route->input()->connect (route->input()->ports().port (DataType::AUDIO, 0), physinputs[n % physinputs.size()], this); - route->output()->connect (route->output()->ports().port (DataType::AUDIO, 0), physoutputs[n % physoutputs.size()], this); + vector::size_type n; + vector::size_type ichn; + vector::size_type ochn; + vector::size_type i; + vector::size_type start_from; + vector::size_type enabled; + + n = route->track_number() - 1; + + /* move to the nth enabled input channel */ + + i = 0; + start_from = 0; + enabled = 0; + while (enabled <= n && i < input_channel_mask.size()) { + if (input_channel_mask[i]) { + start_from = i; + enabled++; + } + ++i; + } + + n = start_from; + size_t attempts = 0; + size_t limit = physinputs.size(); + + while (attempts < limit) { + + ichn = n % physinputs.size(); + + if (input_channel_mask[ichn]) { + route->input()->connect (route->input()->ports().port (DataType::AUDIO, 0), physinputs[ichn], this); + break; + } else { + /* reduce limit because we found a channel that can't be used */ + --limit; + } + + ++attempts; + ++n; + + if (n >= physinputs.size()) { + n = 0; + } + } + + + n = route->track_number() - 1; + + i = 0; + start_from = 0; + enabled = 0; + while (enabled <= n && i < output_channel_mask.size()) { + if (output_channel_mask[i]) { + start_from = i; + enabled++; + } + ++i; + } + + n = start_from; + attempts = 0; + limit = physoutputs.size(); + + while (attempts < limit) { + + ochn = n % physoutputs.size(); + + if (output_channel_mask[ochn]) { + route->output()->connect (route->output()->ports().port (DataType::AUDIO, 0), physoutputs[ochn], this); + break; + } else { + /* reduce limit because we found a channel that can't be used */ + --limit; + } + + ++attempts; + ++n; + + if (n >= physinputs.size()) { + n = 0; + } + } DEBUG_TRACE (DEBUG::PortConnectAuto, string_compose ("livetrax auto connect %1 [%2] to %3 and %4\n", route->name(), route->track_number(), - physinputs[n % physinputs.size()], - physoutputs[n % physoutputs.size()])); + physinputs[ichn], + physoutputs[ochn])); } void