summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/mixer_actor.cc27
-rw-r--r--gtk2_ardour/mixer_actor.h7
-rw-r--r--gtk2_ardour/mixer_strip.cc51
-rw-r--r--gtk2_ardour/mixer_strip.h5
-rw-r--r--gtk2_ardour/mixer_ui.cc14
-rw-r--r--gtk2_ardour/mixer_ui.h3
-rw-r--r--libs/ardour/ardour/gain_control.h1
-rw-r--r--libs/ardour/ardour/route.h7
-rw-r--r--libs/ardour/gain_control.cc7
-rw-r--r--libs/ardour/route.cc13
10 files changed, 129 insertions, 6 deletions
diff --git a/gtk2_ardour/mixer_actor.cc b/gtk2_ardour/mixer_actor.cc
index ada3b3f500..7ffcc6f3a8 100644
--- a/gtk2_ardour/mixer_actor.cc
+++ b/gtk2_ardour/mixer_actor.cc
@@ -250,3 +250,30 @@ MixerActor::ab_plugins ()
}
}
+void
+MixerActor::vca_assign (boost::shared_ptr<VCA> vca)
+{
+ set_route_targets_for_operation ();
+
+ BOOST_FOREACH(RouteUI* r, _route_targets) {
+ MixerStrip* ms = dynamic_cast<MixerStrip*> (r);
+ if (ms) {
+ ms->vca_assign (vca);
+ }
+ }
+}
+
+void
+MixerActor::vca_unassign (boost::shared_ptr<VCA> vca)
+{
+ set_route_targets_for_operation ();
+
+ BOOST_FOREACH(RouteUI* r, _route_targets) {
+ MixerStrip* ms = dynamic_cast<MixerStrip*> (r);
+ if (ms) {
+ ms->vca_unassign (vca);
+ }
+ }
+}
+
+
diff --git a/gtk2_ardour/mixer_actor.h b/gtk2_ardour/mixer_actor.h
index 6e94147604..16b450133d 100644
--- a/gtk2_ardour/mixer_actor.h
+++ b/gtk2_ardour/mixer_actor.h
@@ -29,6 +29,10 @@ namespace Gtk {
class ActionGroup;
}
+namespace ARDOUR {
+ class VCA;
+}
+
class MixerActor : virtual public sigc::trackable
{
public:
@@ -48,6 +52,9 @@ class MixerActor : virtual public sigc::trackable
virtual void set_route_targets_for_operation () = 0;
+ void vca_assign (boost::shared_ptr<ARDOUR::VCA>);
+ void vca_unassign (boost::shared_ptr<ARDOUR::VCA>);
+
void solo_action ();
void mute_action ();
void rec_enable_action ();
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 673bce61d1..d080e79c38 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -2492,7 +2492,7 @@ MixerStrip::set_meter_type (MeterType t)
}
void
-MixerStrip::vca_menu_toggle (uint32_t n)
+MixerStrip::vca_menu_toggle (MenuItem* m, uint32_t n)
{
if (!_route) {
return;
@@ -2504,9 +2504,44 @@ MixerStrip::vca_menu_toggle (uint32_t n)
return;
}
+ RadioMenuItem* ri = dynamic_cast<RadioMenuItem*> (m);
+
+ if (!ri) {
+ return;
+ }
+
+ if (!ri->get_active()) {
+ _mixer.do_vca_unassign (vca);
+ return;
+ }
+
+ /* Now invoke a global method to apply this all relevant strips/routes */
+
+ _mixer.do_vca_assign (vca);
+}
+
+void
+MixerStrip::vca_assign (boost::shared_ptr<VCA> vca)
+{
+ if (!vca || !_route) {
+ return;
+ }
+
vca->add (_route);
}
+void
+MixerStrip::vca_unassign (boost::shared_ptr<VCA> vca)
+{
+ if (!_route) {
+ return;
+ }
+
+ if (!vca) {
+ /* null VCA means drop all VCA assignments */
+ }
+}
+
bool
MixerStrip::vca_button_release (GdkEventButton* ev, uint32_t which)
{
@@ -2516,6 +2551,11 @@ MixerStrip::vca_button_release (GdkEventButton* ev, uint32_t which)
return false;
}
+ if (!_route) {
+ /* no route - nothing to do */
+ return false;
+ }
+
VCAList vcas (_session->vca_manager().vcas());
if (vcas.empty()) {
@@ -2527,8 +2567,15 @@ MixerStrip::vca_button_release (GdkEventButton* ev, uint32_t which)
MenuList& items = menu->items();
RadioMenuItem::Group group;
+ items.push_back (MenuElem (_("Unassign"), sigc::bind (sigc::mem_fun (_mixer, &Mixer_UI::do_vca_unassign), boost::shared_ptr<VCA>())));
+
for (VCAList::iterator v = vcas.begin(); v != vcas.end(); ++v) {
- items.push_back (RadioMenuElem (group, (*v)->name(), sigc::bind (sigc::mem_fun (*this, &MixerStrip::vca_menu_toggle), (*v)->number())));
+ items.push_back (RadioMenuElem (group, (*v)->name()));
+ RadioMenuItem* item = dynamic_cast<RadioMenuItem*> (&items.back());
+ if (_route->slaved_to (*v)) {
+ item->set_active (true);
+ }
+ item->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &MixerStrip::vca_menu_toggle), item, (*v)->number()));
}
menu->popup (1, ev->time);
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index 1fbdb04120..670bab0561 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -131,6 +131,9 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
void toggle_processors ();
void ab_plugins ();
+ void vca_assign (boost::shared_ptr<ARDOUR::VCA>);
+ void vca_unassign (boost::shared_ptr<ARDOUR::VCA>);
+
void set_selected(bool yn);
bool is_selected() {return _selected;}
@@ -320,7 +323,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
std::string meter_point_string (ARDOUR::MeterPoint);
- void vca_menu_toggle (uint32_t n);
+ void vca_menu_toggle (Gtk::MenuItem*, uint32_t n);
bool vca_button_release (GdkEventButton* ev, uint32_t which);
};
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index f847678df8..a321085e23 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -2579,3 +2579,17 @@ Mixer_UI::plugin_drop (const Glib::RefPtr<Gdk::DragContext>&, const Gtk::Selecti
manager.set_status (ppp->_pip->type, ppp->_pip->unique_id, status);
manager.save_statuses ();
}
+
+void
+Mixer_UI::do_vca_assign (boost::shared_ptr<VCA> vca)
+{
+ /* call protected MixerActor:: method */
+ vca_assign (vca);
+}
+
+void
+Mixer_UI::do_vca_unassign (boost::shared_ptr<VCA> vca)
+{
+ /* call protected MixerActor:: method */
+ vca_unassign (vca);
+}
diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h
index 198d510a14..d818ee214a 100644
--- a/gtk2_ardour/mixer_ui.h
+++ b/gtk2_ardour/mixer_ui.h
@@ -116,6 +116,9 @@ class Mixer_UI : public Gtkmm2ext::Tabbable, public PBD::ScopedConnectionList, p
bool window_not_visible () const;
+ void do_vca_assign (boost::shared_ptr<ARDOUR::VCA>);
+ void do_vca_unassign (boost::shared_ptr<ARDOUR::VCA>);
+
protected:
void set_route_targets_for_operation ();
diff --git a/libs/ardour/ardour/gain_control.h b/libs/ardour/ardour/gain_control.h
index c6421a6922..7845679220 100644
--- a/libs/ardour/ardour/gain_control.h
+++ b/libs/ardour/ardour/gain_control.h
@@ -57,6 +57,7 @@ class LIBARDOUR_API GainControl : public AutomationControl {
void add_master (boost::shared_ptr<GainControl>);
void remove_master (boost::shared_ptr<GainControl>);
void clear_masters ();
+ bool slaved_to (boost::shared_ptr<GainControl>) const;
private:
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 3ade22319d..ed32769058 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -72,6 +72,7 @@ class MonitorProcessor;
class Pannable;
class CapturingProcessor;
class InternalSend;
+class VCA;
class LIBARDOUR_API Route : public SessionObject, public Automatable, public RouteGroupMember, public GraphNode, public boost::enable_shared_from_this<Route>
{
@@ -707,8 +708,10 @@ public:
void monitor_run (framepos_t start_frame, framepos_t end_frame,
pframes_t nframes, int declick);
-protected:
- friend class Session;
+ bool slaved_to (boost::shared_ptr<VCA>) const;
+
+ protected:
+ friend class Session;
void catch_up_on_solo_mute_override ();
void mod_solo_by_others_upstream (int32_t);
diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc
index eeb49e7de0..5ba7179231 100644
--- a/libs/ardour/gain_control.cc
+++ b/libs/ardour/gain_control.cc
@@ -176,3 +176,10 @@ GainControl::clear_masters ()
Changed(); /* EMIT SIGNAL */
}
}
+
+bool
+GainControl::slaved_to (boost::shared_ptr<GainControl> gc) const
+{
+ Glib::Threads::Mutex::Lock lm (master_lock);
+ return find (_masters.begin(), _masters.end(), gc) != _masters.end();
+}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 49528e30e3..8b1f47ec4e 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -69,6 +69,7 @@
#include "ardour/session.h"
#include "ardour/unknown_processor.h"
#include "ardour/utils.h"
+#include "ardour/vca.h"
#include "i18n.h"
@@ -3345,7 +3346,7 @@ Route::set_processor_state (const XMLNode& node)
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- XMLProperty const * prop = (*niter)->property ("type");
+ XMLProperty* prop = (*niter)->property ("type");
if (prop->value() == "amp") {
_amp->set_state (**niter, Stateful::current_state_version);
@@ -5883,3 +5884,13 @@ Route::master_send_enable_controllable () const
return boost::shared_ptr<AutomationControl>();
#endif
}
+
+bool
+Route::slaved_to (boost::shared_ptr<VCA> vca) const
+{
+ if (!vca || !_gain_control) {
+ return false;
+ }
+
+ return _gain_control->slaved_to (vca->control());
+}