diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/panner_manager.h | 8 | ||||
-rw-r--r-- | libs/ardour/ardour/panner_shell.h | 19 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 2 | ||||
-rw-r--r-- | libs/ardour/delivery.cc | 9 | ||||
-rw-r--r-- | libs/ardour/panner_manager.cc | 26 | ||||
-rw-r--r-- | libs/ardour/panner_shell.cc | 72 | ||||
-rw-r--r-- | libs/ardour/route.cc | 11 | ||||
-rw-r--r-- | libs/panners/vbap/vbap.cc | 6 |
8 files changed, 133 insertions, 20 deletions
diff --git a/libs/ardour/ardour/panner_manager.h b/libs/ardour/ardour/panner_manager.h index 80f8e8010a..73d667424f 100644 --- a/libs/ardour/ardour/panner_manager.h +++ b/libs/ardour/ardour/panner_manager.h @@ -20,6 +20,8 @@ #ifndef __ardour_panner_manager_h__ #define __ardour_panner_manager_h__ +#include <map> +#include <string> #include <glibmm/module.h> #include "ardour/panner.h" @@ -27,7 +29,10 @@ namespace ARDOUR { +typedef std::map<std::string,std::string> PannerUriMap; + struct LIBARDOUR_API PannerInfo { + PanPluginDescriptor descriptor; Glib::Module* module; @@ -51,7 +56,8 @@ public: std::list<PannerInfo*> 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 76df20489f..02f80c7b28 100644 --- a/libs/ardour/ardour/panner_shell.h +++ b/libs/ardour/ardour/panner_shell.h @@ -50,7 +50,7 @@ class Pannable; class LIBARDOUR_API PannerShell : public SessionObject { public: - PannerShell (std::string name, Session&, boost::shared_ptr<Pannable>); + PannerShell (std::string name, Session&, boost::shared_ptr<Pannable>, bool is_send = false); virtual ~PannerShell (); std::string describe_parameter (Evoral::Parameter param); @@ -64,25 +64,38 @@ public: XMLNode& get_state (); int set_state (const XMLNode&, int version); + PBD::Signal0<void> PannableChanged; /* Pannable changed -- l*/ PBD::Signal0<void> Changed; /* panner and/or outputs count and/or bypass state changed */ boost::shared_ptr<Panner> panner() const { return _panner; } - boost::shared_ptr<Pannable> pannable() const { return _pannable; } + boost::shared_ptr<Pannable> 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: */ + 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); bool set_user_selected_panner_uri (std::string const uri); boost::shared_ptr<Panner> _panner; - boost::shared_ptr<Pannable> _pannable; + + boost::shared_ptr<Pannable> _pannable_internal; + boost::shared_ptr<Pannable> _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 23973f6a1a..adae854ca7 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 11500b4b10..b4b9831d97 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -58,7 +58,9 @@ Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pann , _no_panner_reset (false) { if (pannable) { - _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable)); + bool is_send = false; + if (r & (Delivery::Send|Delivery::Aux)) is_send = true; + _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, is_send)); } _display_to_user = false; @@ -80,7 +82,9 @@ Delivery::Delivery (Session& s, boost::shared_ptr<Pannable> pannable, boost::sha , _no_panner_reset (false) { if (pannable) { - _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable)); + bool is_send = false; + if (r & (Delivery::Send|Delivery::Aux)) is_send = true; + _panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, is_send)); } _display_to_user = false; @@ -364,6 +368,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 3c9623f3e6..0084a62285 100644 --- a/libs/ardour/panner_manager.cc +++ b/libs/ardour/panner_manager.cc @@ -222,13 +222,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<PannerInfo*>::iterator p = panner_info.begin(); p != panner_info.end(); ++p) { + for (list<PannerInfo*>::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<PannerInfo*>::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<std::string,std::string>(d->panner_uri,d->name)); + } + return panner_list; +} diff --git a/libs/ardour/panner_shell.cc b/libs/ardour/panner_shell.cc index a25cb49ab5..b489354e21 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" @@ -59,21 +61,31 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -PannerShell::PannerShell (string name, Session& s, boost::shared_ptr<Pannable> p) +PannerShell::PannerShell (string name, Session& s, boost::shared_ptr<Pannable> 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 @@ -120,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); @@ -137,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 ()); } @@ -157,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 (); } @@ -170,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) { @@ -193,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; @@ -393,3 +413,41 @@ 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; +} + +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 1b40df24dd..6279dbacf6 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 () @@ -2553,8 +2558,7 @@ Route::set_processor_state (const XMLNode& node) if (prop->value() == "intsend") { - boost::shared_ptr<Pannable> sendpan (new Pannable (_session)); - processor.reset (new InternalSend (_session, sendpan, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0))); + processor.reset (new InternalSend (_session, _pannable, _mute_master, boost::shared_ptr<Route>(), Delivery::Aux)); } else if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "lv2" || @@ -2570,8 +2574,7 @@ Route::set_processor_state (const XMLNode& node) } else if (prop->value() == "send") { - boost::shared_ptr<Pannable> 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; diff --git a/libs/panners/vbap/vbap.cc b/libs/panners/vbap/vbap.cc index 23683fde08..0de8d3a29a 100644 --- a/libs/panners/vbap/vbap.cc +++ b/libs/panners/vbap/vbap.cc @@ -477,7 +477,11 @@ void VBAPanner::reset () { set_position (0); - set_width (1); + if (_signals.size() > 1) { + set_width (1.0 - (1.0 / (double)_signals.size())); + } else { + set_width (0); + } set_elevation (0); update (); |