From dfdcfe8d3ab38399496f2e40db17e1f849dd84cc Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 2 Apr 2024 18:15:39 -0600 Subject: [PATCH] most of the mechanism for livetrax signal routing via as master send --- libs/ardour/ardour/route.h | 15 ++++++--- libs/ardour/ardour/session.h | 1 + libs/ardour/internal_send.cc | 8 +++-- libs/ardour/panner_shell.cc | 1 + libs/ardour/route.cc | 48 ++++++++++++++++++++++++++--- libs/ardour/session.cc | 59 ++++++++++++++++++++++++++++++------ 6 files changed, 110 insertions(+), 22 deletions(-) diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 2b8758aa0b..e8c8a58ae2 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -196,8 +196,16 @@ public: bool can_monitor () const { return can_solo() || is_foldbackbus (); } + void enable_monitor_send (); void enable_surround_send (); + void enable_master_send (); + void remove_monitor_send (); + void remove_surround_send (); + void remove_master_send (); + + int add_aux_send (std::shared_ptr, std::shared_ptr); + int add_foldback_send (std::shared_ptr, bool post_fader); void set_denormal_protection (bool yn); bool denormal_protection() const; @@ -279,12 +287,14 @@ public: std::shared_ptr main_outs() const { return _main_outs; } std::shared_ptr internal_return() const { return _intreturn; } std::shared_ptr monitor_control() const { return _monitor_control; } + std::shared_ptr master_send() const { return _master_send; } std::shared_ptr internal_send_for (std::shared_ptr 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 add_export_point(/* Add some argument for placement later */); + void add_master_send (std::shared_ptr); /** 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. @@ -440,11 +450,6 @@ public: PBD::Signal1 SelectedChanged; - int add_aux_send (std::shared_ptr, std::shared_ptr); - int add_foldback_send (std::shared_ptr, bool post_fader); - void remove_monitor_send (); - void remove_surround_send (); - /** * return true if this route feeds the first argument directly, via * either its main outs or a send. This is checked by the actual diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 01c79aba2e..2d371122f3 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -2235,6 +2235,7 @@ 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& result); int find_all_sources_across_snapshots (std::set& result, bool exclude_this_snapshot); diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 1e1511c5fc..fc11cb857b 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -150,6 +150,8 @@ InternalSend::init_gain () int InternalSend::use_target (std::shared_ptr sendto, bool update_name) { + assert (sendto); + if (_send_to) { propagate_solo (); _send_to->remove_send_from_internal_return (this); @@ -165,9 +167,12 @@ InternalSend::use_target (std::shared_ptr sendto, bool update_name) _meter->configure_io (_send_to->internal_return ()->input_streams (), _send_to->internal_return ()->input_streams ()); _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 ()); } @@ -455,7 +460,6 @@ InternalSend::after_connect () if ((sendto = _session.route_by_id (_send_to_id)) == 0) { error << string_compose (_("%1 - cannot find any track/bus with the ID %2 to connect to"), display_name (), _send_to_id) << endmsg; - cerr << string_compose (_("%1 - cannot find any track/bus with the ID %2 to connect to"), display_name (), _send_to_id) << endl; return -1; } diff --git a/libs/ardour/panner_shell.cc b/libs/ardour/panner_shell.cc index 75d074959b..8e7d8bb10c 100644 --- a/libs/ardour/panner_shell.cc +++ b/libs/ardour/panner_shell.cc @@ -488,5 +488,6 @@ PannerShell::set_linked_to_route (bool onoff) } _session.set_dirty (); } + PannableChanged(); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 7b6720ae47..f9038fba8d 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -281,6 +281,11 @@ 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 (); @@ -316,11 +321,6 @@ Route::init () panner_shell()->select_panner_by_uri ("http://ardour.org/plugin/panner_balance"); } - if (Profile->get_livetrax() && is_track()) { - _master_send.reset (new InternalSend (_session, _pannable, _mute_master, std::dynamic_pointer_cast (shared_from_this()), std::shared_ptr(), Delivery::MasterSend, false)); - _master_send->set_display_to_user (false); - } - /* now set up processor chain and invisible processors */ { Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); @@ -3511,6 +3511,43 @@ Route::remove_monitor_send () _monitor_send.reset (); } +void +Route::enable_master_send() +{ + if (!Profile->get_livetrax()) { + return; + } + + /* Caller must hold process lock */ + assert (!AudioEngine::instance()->process_lock().trylock()); + + /* master sends 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 */ + _master_send.reset (new InternalSend (_session, pannable(), _mute_master, std::dynamic_pointer_cast (shared_from_this()), _session.master_out(), Delivery::MasterSend, false)); + _master_send->set_display_to_user (false); + _master_send->gain_control()->set_value (dB_to_coefficient (0.0), Controllable::NoGroup); + } + + /* set it up */ + configure_processors (0); +} + +void +Route::remove_master_send () +{ + /* caller needs to hold process lock */ + if (!_master_send) { + return; + } + ProcessorStreams err; + remove_processor (_master_send, &err, false); + _master_send.reset (); +} + /** Add an aux send to a route. * @param route route to send to. * @param before Processor to insert before, or 0 to insert at the end. @@ -6305,3 +6342,4 @@ Route::remove_surround_send () */ _pending_surround_send.store (1); } + diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 1af78e115b..c9b266de94 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -84,6 +84,8 @@ #include "ardour/filename_extensions.h" #include "ardour/gain_control.h" #include "ardour/graph.h" +#include "ardour/internal_return.h" +#include "ardour/internal_send.h" #include "ardour/io_plug.h" #include "ardour/luabindings.h" #include "ardour/lv2_plugin.h" @@ -1290,6 +1292,34 @@ 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 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 () @@ -3111,7 +3141,7 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r << endmsg; goto failure; } - + if (bus->output()->ensure_io (ChanCount(DataType::AUDIO, output_channels), false, this)) { error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"), @@ -3617,20 +3647,29 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool } } - if (_monitor_out && !loading()) { + if (!loading()) { Glib::Threads::Mutex::Lock lm (_engine.process_lock()); - for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) { - if ((*x)->can_monitor ()) { - (*x)->enable_monitor_send (); + if (_monitor_out) { + for (auto & r : new_routes) { + if (r->can_monitor ()) { + r->enable_monitor_send (); + } } } - } - if (_surround_master && !loading()) { - Glib::Threads::Mutex::Lock lm (_engine.process_lock()); - for (auto & r : new_routes) { - r->enable_surround_send (); + if (_surround_master) { + for (auto & r : new_routes) { + r->enable_surround_send (); + } + } + + if (Profile->get_livetrax ()) { + for (auto & r : new_routes) { + if (r->is_track()) { + r->enable_master_send (); + } + } } } }