From 0669bb455b72bb5333534941787a889d828ea443 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 11 Jan 2014 23:29:36 +0100 Subject: VBAP GUI depends on signal-position (not parameter changes) --- libs/ardour/ardour/panner.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libs/ardour/ardour') diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 0c025b0ca2..18e3e8045a 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -87,6 +87,9 @@ public: virtual void reset () = 0; + /* azimut, width or elevation updated -> recalc signal_position -> emit Changed */ + PBD::Signal0 SignalPositionChanged; + void set_automation_state (AutoState); AutoState automation_state() const; void set_automation_style (AutoStyle); -- cgit v1.2.3 From 0c384b7c219872322a4462f62e5e67b4119caa6d Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 13 Jan 2014 10:48:23 +0100 Subject: update internal-send port-count when target port-count changes --- libs/ardour/ardour/internal_send.h | 1 + libs/ardour/delivery.cc | 2 +- libs/ardour/internal_send.cc | 12 +++++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'libs/ardour/ardour') diff --git a/libs/ardour/ardour/internal_send.h b/libs/ardour/ardour/internal_send.h index a7f0f73e6e..09b26d57d5 100644 --- a/libs/ardour/ardour/internal_send.h +++ b/libs/ardour/ardour/internal_send.h @@ -70,6 +70,7 @@ class InternalSend : public Send int connect_when_legal (); void init_gain (); int use_target (boost::shared_ptr); + void target_io_changed (); }; } // namespace ARDOUR diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 79c44ce94a..575d26acdd 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -388,7 +388,7 @@ Delivery::reset_panner () if (_panshell) { _panshell->configure_io (ChanCount (DataType::AUDIO, pans_required()), ChanCount (DataType::AUDIO, pan_outs())); - if (_role == Main) { + if (_role == Main || _role == Aux) { _panshell->pannable()->set_panner (_panshell->panner()); } } diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 9716cf002c..dac1839a5e 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -95,11 +95,21 @@ InternalSend::use_target (boost::shared_ptr sendto) target_connections.drop_connections (); _send_to->DropReferences.connect_same_thread (target_connections, boost::bind (&InternalSend::send_to_going_away, this)); - _send_to->PropertyChanged.connect_same_thread (target_connections, boost::bind (&InternalSend::send_to_property_changed, this, _1));; + _send_to->PropertyChanged.connect_same_thread (target_connections, boost::bind (&InternalSend::send_to_property_changed, this, _1)); + _send_to->io_changed.connect_same_thread (target_connections, boost::bind (&InternalSend::target_io_changed, this)); return 0; } +void +InternalSend::target_io_changed () +{ + assert (_send_to); + mixbufs.ensure_buffers (_send_to->internal_return()->input_streams(), _session.get_block_size()); + mixbufs.set_count (_send_to->internal_return()->input_streams()); + reset_panner(); +} + void InternalSend::send_to_going_away () { -- cgit v1.2.3 From d9cf6880b6d65665a55aed212503de0820db6f40 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 13 Jan 2014 10:50:22 +0100 Subject: fix output metering for Sends (Aux and External) --- libs/ardour/ardour/send.h | 1 + libs/ardour/send.cc | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'libs/ardour/ardour') diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 1a21d1d050..118110f05a 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -77,6 +77,7 @@ class Send : public Delivery private: /* disallow copy construction */ Send (const Send&); + void panshell_changed (); int set_state_2X (XMLNode const &, int); diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index e74fd7f8ce..2c3d8f23ae 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -29,6 +29,7 @@ #include "ardour/buffer_set.h" #include "ardour/meter.h" #include "ardour/io.h" +#include "ardour/panner_shell.h" #include "i18n.h" @@ -86,6 +87,10 @@ Send::Send (Session& s, boost::shared_ptr p, boost::shared_ptrgain_control ()); + + if (panner_shell()) { + panner_shell()->Changed.connect_same_thread (*this, boost::bind (&Send::panshell_changed, this)); + } } Send::~Send () @@ -284,7 +289,7 @@ Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) bool Send::configure_io (ChanCount in, ChanCount out) { - if (!_amp->configure_io (in, out) || !_meter->configure_io (in, out)) { + if (!_amp->configure_io (in, out)) { return false; } @@ -292,11 +297,21 @@ Send::configure_io (ChanCount in, ChanCount out) return false; } + if (!_meter->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs()))) { + return false; + } + reset_panner (); return true; } +void +Send::panshell_changed () +{ + _meter->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs())); +} + bool Send::set_name (const string& new_name) { -- cgit v1.2.3 From 291618fe7116424448da5f7029e567d655526521 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 13 Jan 2014 15:13:37 +0100 Subject: allow to custom select panner-type for each delivery. --- gtk2_ardour/mixer_strip.cc | 29 ++++++++--------------------- gtk2_ardour/panner_ui.cc | 9 +++------ gtk2_ardour/panner_ui.h | 4 ++-- gtk2_ardour/send_ui.cc | 12 ++++++++++++ libs/ardour/ardour/panner_manager.h | 5 ++++- libs/ardour/ardour/panner_shell.h | 3 +++ libs/ardour/delivery.cc | 1 + libs/ardour/panner_manager.cc | 26 ++++++++++++++++++++++++-- libs/ardour/panner_shell.cc | 20 ++++++++++++++++++++ libs/ardour/route.cc | 5 +++++ 10 files changed, 82 insertions(+), 32 deletions(-) (limited to 'libs/ardour/ardour') diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 780e8078c6..830d2bf161 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -1041,29 +1041,13 @@ MixerStrip::update_panner_choices () ENSURE_GUI_THREAD (*this, &MixerStrip::update_panner_choices) if (!_route->panner_shell()) { return; } - int in = _route->output()->n_ports().n_audio(); - int out = in; - + uint32_t in = _route->output()->n_ports().n_audio(); + uint32_t out = in; if (_route->panner()) { in = _route->panner()->in().n_audio(); } - if (out < 2 || in == 0) { - panners.set_available_panners(_route, std::map()); - return; - } - - std::map panner_list; - std::list panner_info = PannerManager::instance().panner_info; - /* get available panners for current configuration. */ - for (list::iterator p = panner_info.begin(); p != panner_info.end(); ++p) { - PanPluginDescriptor* d = &(*p)->descriptor; - if (d->in != -1 && d->in != in) continue; - if (d->out != -1 && d->out != out) continue; - if (d->in == -1 && d->out == -1 && out <= 2) continue; - panner_list.insert(std::pair(d->panner_uri,d->name)); - } - panners.set_available_panners(_route, panner_list); + panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out)); } /* @@ -1891,10 +1875,13 @@ MixerStrip::show_send (boost::shared_ptr send) gain_meter().set_controls (_route, send->meter(), send->amp()); gain_meter().setup_meters (); + uint32_t const in = _current_delivery->pans_required(); + uint32_t const out = _current_delivery->pan_outs(); + panner_ui().set_panner (_current_delivery->panner_shell(), _current_delivery->panner()); - panner_ui().set_available_panners(boost::shared_ptr(), std::map()); + panner_ui().set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out)); panner_ui().setup_pan (); - panners.show_all (); + panner_ui().show_all (); input_button.set_sensitive (false); group_button.set_sensitive (false); diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc index ab4279a154..2a6568992b 100644 --- a/gtk2_ardour/panner_ui.cc +++ b/gtk2_ardour/panner_ui.cc @@ -388,7 +388,7 @@ PannerUI::build_pan_menu () items.push_back (MenuElem (_("Edit..."), sigc::mem_fun (*this, &PannerUI::pan_edit))); } - if (_route && _panner_list.size() > 1 && !_panshell->bypassed()) { + if (_panner_list.size() > 1 && !_panshell->bypassed()) { RadioMenuItem::Group group; items.push_back (SeparatorElem()); @@ -444,9 +444,7 @@ PannerUI::pan_reset () void PannerUI::pan_set_custom_type (std::string uri) { if (_suspend_menu_callbacks) return; - if (_route) { - _route->set_custom_panner_uri(uri); - } + _panshell->select_panner_by_uri(uri); } void @@ -644,8 +642,7 @@ PannerUI::position_adjusted () } void -PannerUI::set_available_panners(boost::shared_ptr r, std::map p) +PannerUI::set_available_panners(std::map p) { - _route = r; _panner_list = p; } diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h index dca24451d1..9b349d664f 100644 --- a/gtk2_ardour/panner_ui.h +++ b/gtk2_ardour/panner_ui.h @@ -73,7 +73,7 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr void set_width (Width); void setup_pan (); - void set_available_panners(boost::shared_ptr, std::map); + void set_available_panners(std::map); void effective_pan_display (); @@ -85,6 +85,7 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr private: friend class MixerStrip; + friend class SendUI; boost::shared_ptr _panshell; boost::shared_ptr _panner; @@ -161,7 +162,6 @@ class PannerUI : public Gtk::HBox, public ARDOUR::SessionHandlePtr void start_touch (boost::weak_ptr); void stop_touch (boost::weak_ptr); - boost::shared_ptr _route; std::map _panner_list; bool _suspend_menu_callbacks; }; diff --git a/gtk2_ardour/send_ui.cc b/gtk2_ardour/send_ui.cc index 90ee52b3ad..cdd8673da9 100644 --- a/gtk2_ardour/send_ui.cc +++ b/gtk2_ardour/send_ui.cc @@ -20,6 +20,7 @@ #include #include "ardour/io.h" +#include "ardour/panner_manager.h" #include "ardour/send.h" #include "ardour/rc_configuration.h" @@ -70,7 +71,11 @@ SendUI::SendUI (Gtk::Window* parent, boost::shared_ptr s, Session* session _send->output()->changed.connect (connections, invalidator (*this), boost::bind (&SendUI::outs_changed, this, _1, _2), gui_context()); + uint32_t const in = _send->pans_required(); + uint32_t const out = _send->pan_outs(); + _panners.set_width (Wide); + _panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out)); _panners.setup_pan (); _gpm.setup_meters (); @@ -97,7 +102,14 @@ SendUI::outs_changed (IOChange change, void* /*ignored*/) { ENSURE_GUI_THREAD (*this, &SendUI::outs_changed, change, ignored) if (change.type & IOChange::ConfigurationChanged) { + uint32_t const in = _send->pans_required(); + uint32_t const out = _send->pan_outs(); + if (_panners._panner == 0) { + _panners.set_panner (_send->panner_shell(), _send->panner()); + } + _panners.set_available_panners(PannerManager::instance().PannerManager::get_available_panners(in, out)); _panners.setup_pan (); + _panners.show_all (); _gpm.setup_meters (); } } diff --git a/libs/ardour/ardour/panner_manager.h b/libs/ardour/ardour/panner_manager.h index 7b52c65c0a..4a29e1c36b 100644 --- a/libs/ardour/ardour/panner_manager.h +++ b/libs/ardour/ardour/panner_manager.h @@ -26,6 +26,8 @@ namespace ARDOUR { +typedef std::map PannerUriMap; + struct PannerInfo { PanPluginDescriptor descriptor; void* module; @@ -50,7 +52,8 @@ public: std::list panner_info; PannerInfo* select_panner (ChanCount in, ChanCount out, std::string const uri = ""); - PannerInfo* get_by_uri (std::string uri); + PannerInfo* get_by_uri (std::string uri) const; + PannerUriMap get_available_panners(uint32_t const a_in, uint32_t const a_out) const; private: PannerManager(); diff --git a/libs/ardour/ardour/panner_shell.h b/libs/ardour/ardour/panner_shell.h index f798e0da97..765acad16a 100644 --- a/libs/ardour/ardour/panner_shell.h +++ b/libs/ardour/ardour/panner_shell.h @@ -75,6 +75,9 @@ public: std::string user_selected_panner_uri() const { return _user_selected_panner_uri; } std::string panner_gui_uri() const { return _panner_gui_uri; } + /* this function takes the process lock */ + bool select_panner_by_uri (std::string const uri); + private: friend class Route; void distribute_no_automation (BufferSet& src, BufferSet& dest, pframes_t nframes, gain_t gain_coeff); diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 11500b4b10..8e636ed861 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -364,6 +364,7 @@ Delivery::set_state (const XMLNode& node, int version) XMLNode* pannnode = node.child (X_("Pannable")); if (_panshell && _panshell->panner() && pannnode) { _panshell->pannable()->set_state (*pannnode, version); + _panshell->pannable()->set_panner(_panshell->panner()); } return 0; diff --git a/libs/ardour/panner_manager.cc b/libs/ardour/panner_manager.cc index 24fa10e225..ec5b675731 100644 --- a/libs/ardour/panner_manager.cc +++ b/libs/ardour/panner_manager.cc @@ -218,13 +218,35 @@ PannerManager::select_panner (ChanCount in, ChanCount out, std::string const uri } PannerInfo* -PannerManager::get_by_uri (std::string uri) +PannerManager::get_by_uri (std::string uri) const { PannerInfo* pi = NULL; - for (list::iterator p = panner_info.begin(); p != panner_info.end(); ++p) { + for (list::const_iterator p = panner_info.begin(); p != panner_info.end(); ++p) { if ((*p)->descriptor.panner_uri != uri) continue; pi = (*p); break; } return pi; } + +PannerUriMap +PannerManager::get_available_panners(uint32_t const a_in, uint32_t const a_out) const +{ + int const in = a_in; + int const out = a_out; + PannerUriMap panner_list; + + if (out < 2 || in == 0) { + return panner_list; + } + + /* get available panners for current configuration. */ + for (list::const_iterator p = panner_info.begin(); p != panner_info.end(); ++p) { + PanPluginDescriptor* d = &(*p)->descriptor; + if (d->in != -1 && d->in != in) continue; + if (d->out != -1 && d->out != out) continue; + if (d->in == -1 && d->out == -1 && out <= 2) continue; + panner_list.insert(std::pair(d->panner_uri,d->name)); + } + return panner_list; +} diff --git a/libs/ardour/panner_shell.cc b/libs/ardour/panner_shell.cc index a25cb49ab5..ccb8aa8e87 100644 --- a/libs/ardour/panner_shell.cc +++ b/libs/ardour/panner_shell.cc @@ -43,8 +43,10 @@ #include "evoral/Curve.hpp" #include "ardour/audio_buffer.h" +#include "ardour/audioengine.h" #include "ardour/buffer_set.h" #include "ardour/debug.h" +#include "ardour/pannable.h" #include "ardour/panner.h" #include "ardour/panner_manager.h" #include "ardour/panner_shell.h" @@ -393,3 +395,21 @@ PannerShell::set_user_selected_panner_uri (std::string const uri) _force_reselect = true; return true; } + +bool +PannerShell::select_panner_by_uri (std::string const uri) +{ + if (uri == _user_selected_panner_uri) return false; + _user_selected_panner_uri = uri; + if (uri == _current_panner_uri) return false; + _force_reselect = true; + if (_panner) { + Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); + ChanCount in = _panner->in(); + ChanCount out = _panner->out(); + configure_io(in, out); + pannable()->set_panner(_panner); + _session.set_dirty (); + } + return true; +} diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index a036c8feb0..ccfe38e9e1 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -1568,6 +1568,10 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams* return 0; } +#if 0 +/* currently unused (again) -- but will come in handy soon (again) + * once there is an option to link route + delivery panner settings + */ void Route::set_custom_panner_uri (std::string const panner_uri) { @@ -1619,6 +1623,7 @@ Route::set_custom_panner_uri (std::string const panner_uri) processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */ _session.set_dirty (); } +#endif void Route::reset_instrument_info () -- cgit v1.2.3 From e45151b89c64912077c03fc979f1581780ac9e27 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 13 Jan 2014 23:21:30 +0100 Subject: first stab at send+route panner link --- gtk2_ardour/ardour.menus.in | 1 + gtk2_ardour/processor_box.cc | 54 ++++++++++++++++++++++++++---- gtk2_ardour/processor_box.h | 2 ++ libs/ardour/ardour/panner_shell.h | 18 +++++++--- libs/ardour/ardour/rc_configuration_vars.h | 2 ++ libs/ardour/delivery.cc | 8 +++-- libs/ardour/panner_shell.cc | 52 ++++++++++++++++++++++++---- libs/ardour/route.cc | 11 +++--- 8 files changed, 121 insertions(+), 27 deletions(-) (limited to 'libs/ardour/ardour') diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index a354df603d..b6328963bb 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -551,6 +551,7 @@ + diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index 98bb3f13cd..c2421dcabf 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -45,8 +45,8 @@ #include "ardour/audioengine.h" #include "ardour/internal_return.h" #include "ardour/internal_send.h" +#include "ardour/panner_shell.h" #include "ardour/plugin_insert.h" -#include "ardour/pannable.h" #include "ardour/port_insert.h" #include "ardour/profile.h" #include "ardour/return.h" @@ -456,6 +456,34 @@ ProcessorEntry::toggle_control_visibility (Control* c) _parent->update_gui_object_state (this); } +Menu * +ProcessorEntry::build_send_options_menu () +{ + using namespace Menu_Helpers; + Menu* menu = manage (new Menu); + MenuList& items = menu->items (); + + boost::shared_ptr send = boost::dynamic_pointer_cast (_processor); + if (send) { + + items.push_back (CheckMenuElem (_("Link panner controls"))); + CheckMenuItem* c = dynamic_cast (&items.back ()); + c->set_active (send->panner_shell()->is_linked_to_route()); + c->signal_toggled().connect (sigc::mem_fun (*this, &ProcessorEntry::toggle_panner_link)); + + } + return menu; +} + +void +ProcessorEntry::toggle_panner_link () +{ + boost::shared_ptr send = boost::dynamic_pointer_cast (_processor); + if (send) { + send->panner_shell()->set_linked_to_route(!send->panner_shell()->is_linked_to_route()); + } +} + ProcessorEntry::Control::Control (boost::shared_ptr c, string const & n) : _control (c) , _adjustment (gain_to_slider_position_with_max (1.0, Config->get_max_gain()), 0, 1, 0.01, 0.1) @@ -1092,6 +1120,20 @@ ProcessorBox::show_processor_menu (int arg) } } + Gtk::MenuItem* send_menu_item = dynamic_cast(ActionManager::get_widget("/ProcessorMenu/send_options")); + if (send_menu_item) { + if (single_selection) { + Menu* m = single_selection->build_send_options_menu (); + if (m && !m->items().empty()) { + send_menu_item->set_submenu (*m); + send_menu_item->set_sensitive (true); + } else { + gtk_menu_item_set_submenu (send_menu_item->gobj(), 0); + send_menu_item->set_sensitive (false); + } + } + } + /* Sensitise actions as approprioate */ cut_action->set_sensitive (can_cut()); @@ -1403,8 +1445,7 @@ ProcessorBox::choose_insert () void ProcessorBox::choose_send () { - boost::shared_ptr sendpan(new Pannable (*_session)); - boost::shared_ptr send (new Send (*_session, sendpan, _route->mute_master())); + boost::shared_ptr send (new Send (*_session, _route->pannable(), _route->mute_master())); /* make an educated guess at the initial number of outputs for the send */ ChanCount outs = (_session->master_out()) @@ -2053,9 +2094,8 @@ ProcessorBox::paste_processor_state (const XMLNodeList& nlist, boost::shared_ptr continue; } - boost::shared_ptr sendpan(new Pannable (*_session)); XMLNode n (**niter); - InternalSend* s = new InternalSend (*_session, sendpan, _route->mute_master(), + InternalSend* s = new InternalSend (*_session, _route->pannable(), _route->mute_master(), boost::shared_ptr(), Delivery::Aux); IOProcessor::prepare_for_reset (n, s->name()); @@ -2069,9 +2109,8 @@ ProcessorBox::paste_processor_state (const XMLNodeList& nlist, boost::shared_ptr } else if (type->value() == "send") { - boost::shared_ptr sendpan(new Pannable (*_session)); XMLNode n (**niter); - Send* s = new Send (*_session, sendpan, _route->mute_master()); + Send* s = new Send (*_session, _route->pannable(), _route->mute_master()); IOProcessor::prepare_for_reset (n, s->name()); @@ -2404,6 +2443,7 @@ ProcessorBox::register_actions () ActionManager::register_action (popup_act_grp, X_("newaux"), _("New Aux Send ...")); ActionManager::register_action (popup_act_grp, X_("controls"), _("Controls")); + ActionManager::register_action (popup_act_grp, X_("send_options"), _("Send Options")); ActionManager::register_action (popup_act_grp, X_("clear"), _("Clear (all)"), sigc::ptr_fun (ProcessorBox::rb_clear)); diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index a66a6c4a56..021e557d36 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -138,6 +138,7 @@ public: void set_control_state (XMLNode const *); std::string state_id () const; Gtk::Menu* build_controls_menu (); + Gtk::Menu* build_send_options_menu (); protected: ArdourButton _button; @@ -205,6 +206,7 @@ private: std::list _controls; void toggle_control_visibility (Control *); + void toggle_panner_link (); class PortIcon : public Gtk::DrawingArea { public: diff --git a/libs/ardour/ardour/panner_shell.h b/libs/ardour/ardour/panner_shell.h index 765acad16a..60db264b4d 100644 --- a/libs/ardour/ardour/panner_shell.h +++ b/libs/ardour/ardour/panner_shell.h @@ -49,7 +49,7 @@ class Pannable; class PannerShell : public SessionObject { public: - PannerShell (std::string name, Session&, boost::shared_ptr); + PannerShell (std::string name, Session&, boost::shared_ptr, bool is_send = false); virtual ~PannerShell (); std::string describe_parameter (Evoral::Parameter param); @@ -63,19 +63,25 @@ public: XMLNode& get_state (); int set_state (const XMLNode&, int version); + PBD::Signal0 PannableChanged; /* Pannable changed -- l*/ PBD::Signal0 Changed; /* panner and/or outputs count and/or bypass state changed */ boost::shared_ptr panner() const { return _panner; } - boost::shared_ptr pannable() const { return _pannable; } + boost::shared_ptr pannable() const { return _panlinked ? _pannable_route : _pannable_internal; } bool bypassed () const; void set_bypassed (bool); + bool is_send () const { return (_is_send); } + bool is_linked_to_route () const { return (_is_send && _panlinked); } + /* this function takes the process lock: */ + void set_linked_to_route (bool); + std::string current_panner_uri() const { return _current_panner_uri; } std::string user_selected_panner_uri() const { return _user_selected_panner_uri; } std::string panner_gui_uri() const { return _panner_gui_uri; } - /* this function takes the process lock */ + /* this function takes the process lock: */ bool select_panner_by_uri (std::string const uri); private: @@ -84,7 +90,11 @@ public: bool set_user_selected_panner_uri (std::string const uri); boost::shared_ptr _panner; - boost::shared_ptr _pannable; + + boost::shared_ptr _pannable_internal; + boost::shared_ptr _pannable_route; + bool _is_send; + bool _panlinked; bool _bypassed; std::string _current_panner_uri; diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index e1f8b42914..b92d0e152a 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -113,6 +113,8 @@ CONFIG_VARIABLE (gain_t, solo_mute_gain, "solo-mute-gain", 0.0) CONFIG_VARIABLE (std::string, monitor_bus_preferred_bundle, "monitor-bus-preferred-bundle", "") CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true) +CONFIG_VARIABLE (bool, link_send_and_route_panner, "link-send-and-route-panner", true) + /* click */ CONFIG_VARIABLE (bool, clicking, "clicking", false) diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 8e636ed861..b4b9831d97 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -58,7 +58,9 @@ Delivery::Delivery (Session& s, boost::shared_ptr io, boost::shared_ptr(new PannerShell (_name, _session, pannable)); + bool is_send = false; + if (r & (Delivery::Send|Delivery::Aux)) is_send = true; + _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable, is_send)); } _display_to_user = false; @@ -80,7 +82,9 @@ Delivery::Delivery (Session& s, boost::shared_ptr pannable, boost::sha , _no_panner_reset (false) { if (pannable) { - _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable)); + bool is_send = false; + if (r & (Delivery::Send|Delivery::Aux)) is_send = true; + _panshell = boost::shared_ptr(new PannerShell (_name, _session, pannable, is_send)); } _display_to_user = false; diff --git a/libs/ardour/panner_shell.cc b/libs/ardour/panner_shell.cc index ccb8aa8e87..b489354e21 100644 --- a/libs/ardour/panner_shell.cc +++ b/libs/ardour/panner_shell.cc @@ -61,21 +61,31 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -PannerShell::PannerShell (string name, Session& s, boost::shared_ptr p) +PannerShell::PannerShell (string name, Session& s, boost::shared_ptr p, bool is_send) : SessionObject (s, name) - , _pannable (p) + , _pannable_route (p) + , _is_send (is_send) + , _panlinked (true) , _bypassed (false) , _current_panner_uri("") , _user_selected_panner_uri("") , _panner_gui_uri("") , _force_reselect (false) { + if (is_send) { + _pannable_internal.reset(new Pannable (s)); + if (Config->get_link_send_and_route_panner()) { + _panlinked = true; + } else { + _panlinked = false; + } + } set_name (name); } PannerShell::~PannerShell () { - DEBUG_TRACE(DEBUG::Destruction, string_compose ("panner shell %3 for %1 destructor, panner is %4, pannable is %2\n", _name, _pannable, this, _panner)); + DEBUG_TRACE(DEBUG::Destruction, string_compose ("panner shell %3 for %1 destructor, panner is %4, pannable is %2\n", _name, _pannable_route, this, _panner)); } void @@ -122,7 +132,8 @@ PannerShell::configure_io (ChanCount in, ChanCount out) speakers.reset (s); } - Panner* p = pi->descriptor.factory (_pannable, speakers); + /* TODO don't allow to link _is_send if internal & route panners are different types */ + Panner* p = pi->descriptor.factory (pannable(), speakers); // boost_debug_shared_ptr_mark_interesting (p, "Panner"); _panner.reset (p); _panner->configure_io (in, out); @@ -139,8 +150,9 @@ PannerShell::get_state () node->add_property (X_("bypassed"), _bypassed ? X_("yes") : X_("no")); node->add_property (X_("user-panner"), _user_selected_panner_uri); + node->add_property (X_("linked-to-route"), _panlinked ? X_("yes") : X_("no")); - if (_panner) { + if (_panner && _is_send) { node->add_child_nocopy (_panner->get_state ()); } @@ -159,6 +171,10 @@ PannerShell::set_state (const XMLNode& node, int version) set_bypassed (string_is_affirmative (prop->value ())); } + if ((prop = node.property (X_("linked-to-route"))) != 0) { + _panlinked = string_is_affirmative (prop->value ()); + } + if ((prop = node.property (X_("user-panner"))) != 0) { _user_selected_panner_uri = prop->value (); } @@ -172,7 +188,8 @@ PannerShell::set_state (const XMLNode& node, int version) if ((prop = (*niter)->property (X_("uri")))) { PannerInfo* p = PannerManager::instance().get_by_uri(prop->value()); if (p) { - _panner.reset (p->descriptor.factory (_pannable, _session.get_speakers ())); + _panner.reset (p->descriptor.factory ( + _is_send ? _pannable_internal : _pannable_route, _session.get_speakers ())); _current_panner_uri = p->descriptor.panner_uri; _panner_gui_uri = p->descriptor.gui_uri; if (_panner->set_state (**niter, version) == 0) { @@ -195,7 +212,8 @@ PannerShell::set_state (const XMLNode& node, int version) assumption, but it's still an assumption. */ - _panner.reset ((*p)->descriptor.factory (_pannable, _session.get_speakers ())); + _panner.reset ((*p)->descriptor.factory ( + _is_send ? _pannable_internal : _pannable_route, _session.get_speakers ())); _current_panner_uri = (*p)->descriptor.panner_uri; _panner_gui_uri = (*p)->descriptor.gui_uri; @@ -413,3 +431,23 @@ PannerShell::select_panner_by_uri (std::string const uri) } return true; } + +void +PannerShell::set_linked_to_route (bool onoff) +{ + if (!_is_send || onoff == _panlinked) { + return; + } + _panlinked = onoff; + + _force_reselect = true; + if (_panner) { + Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); + ChanCount in = _panner->in(); + ChanCount out = _panner->out(); + configure_io(in, out); + pannable()->set_panner(_panner); + _session.set_dirty (); + } + PannableChanged(); +} diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index ccfe38e9e1..a2176e8d45 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -1069,8 +1069,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version) } else if (node.name() == "Send") { - boost::shared_ptr sendpan (new Pannable (_session)); - processor.reset (new Send (_session, sendpan, _mute_master)); + processor.reset (new Send (_session, _pannable, _mute_master)); } else { @@ -2553,8 +2552,7 @@ Route::set_processor_state (const XMLNode& node) if (prop->value() == "intsend") { - boost::shared_ptr sendpan (new Pannable (_session)); - processor.reset (new InternalSend (_session, sendpan, _mute_master, boost::shared_ptr(), Delivery::Role (0))); + processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr(), Delivery::Aux)); } else if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "lv2" || @@ -2571,7 +2569,7 @@ Route::set_processor_state (const XMLNode& node) } else if (prop->value() == "send") { boost::shared_ptr sendpan (new Pannable (_session)); - processor.reset (new Send (_session, sendpan, _mute_master)); + processor.reset (new Send (_session, _pannable, _mute_master)); } else { error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg; @@ -2761,8 +2759,7 @@ Route::add_aux_send (boost::shared_ptr route, boost::shared_ptrprocess_lock ()); - boost::shared_ptr sendpan (new Pannable (_session)); - listener.reset (new InternalSend (_session, sendpan, _mute_master, route, Delivery::Aux)); + listener.reset (new InternalSend (_session, _pannable, _mute_master, route, Delivery::Aux)); } add_processor (listener, before); -- cgit v1.2.3