a slew of as-yet incomplete work to get VCA solo+mute closer to working
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 11 Apr 2016 20:37:51 +0000 (16:37 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 31 May 2016 19:30:40 +0000 (15:30 -0400)
13 files changed:
gtk2_ardour/route_ui.cc
gtk2_ardour/vca_master_strip.cc
libs/ardour/ardour/automation_control.h
libs/ardour/ardour/mute_control.h
libs/ardour/ardour/solo_control.h
libs/ardour/ardour/vca.h
libs/ardour/gain_control.cc
libs/ardour/mute_control.cc
libs/ardour/route.cc
libs/ardour/slavable_automation_control.cc
libs/ardour/solo_control.cc
libs/ardour/vca.cc
libs/pbd/pbd/controllable.h

index 730cc055149ab3e1b932b2054357a10ed1cae75d..695c2d3eaf24e28d9394da33502070b078b9e1a3 100644 (file)
@@ -1225,10 +1225,12 @@ RouteUI::mute_active_state (Session* s, boost::shared_ptr<Route> r)
 
        if (Config->get_show_solo_mutes() && !Config->get_solo_control_is_listen_control ()) {
 
+               cerr << r->name() << " muted " << r->muted () << " others-soloing " << r->muted_by_others_soloing() << " master " << r->mute_control()->get_masters_value() << endl;
+
                if (r->muted ()) {
                        /* full mute */
                        return Gtkmm2ext::ExplicitActive;
-               } else if (r->muted_by_others_soloing ()) {
+               } else if (r->muted_by_others_soloing () || r->mute_control()->get_masters_value()) {
                        /* this will reflect both solo mutes AND master mutes */
                        return Gtkmm2ext::ImplicitActive;
                } else {
index fa5ab1c3457c8af3b6197ef858f6c3bf62295a01..80c981be563a299316fe87a9c9d6304b01f9a9ce 100644 (file)
@@ -198,14 +198,15 @@ VCAMasterStrip::set_selected (bool yn)
 bool
 VCAMasterStrip::solo_release (GdkEventButton*)
 {
-       _vca->solo_control()->set_value (_vca->soloed() ? 0.0 : 1.0, Controllable::NoGroup);
+       std::cerr << "VCA solo release, from " << _vca->solo_control()->get_value() << std::endl;
+       _vca->solo_control()->set_value (_vca->solo_control()->get_value() ? 0.0 : 1.0, Controllable::NoGroup);
        return true;
 }
 
 bool
 VCAMasterStrip::mute_release (GdkEventButton*)
 {
-       _vca->mute_control()->set_value (_vca->muted() ? 0.0 : 1.0, Controllable::NoGroup);
+       _vca->mute_control()->set_value (_vca->mute_control()->get_value() ? 0.0 : 1.0, Controllable::NoGroup);
        return true;
 }
 
@@ -229,7 +230,7 @@ VCAMasterStrip::set_solo_text ()
 void
 VCAMasterStrip::mute_changed ()
 {
-       if (_vca->muted()) {
+       if (_vca->mute_control()->muted()) {
                mute_button.set_active_state (ExplicitActive);
        } else {
                mute_button.set_active_state (Gtkmm2ext::Off);
@@ -239,7 +240,7 @@ VCAMasterStrip::mute_changed ()
 void
 VCAMasterStrip::solo_changed ()
 {
-       if (_vca->soloed()) {
+       if (_vca->solo_control()->soloed()) {
                solo_button.set_active_state (ExplicitActive);
        } else {
                solo_button.set_active_state (Gtkmm2ext::Off);
index a2eff17d9aea5aaa8dc048b851c917dbd71589d3..f576cb52c0285da3977a64de611d40e4da9f07a7 100644 (file)
@@ -161,6 +161,11 @@ class SlavableAutomationControl : public AutomationControl
        void clear_masters ();
        bool slaved_to (boost::shared_ptr<AutomationControl>) const;
        bool slaved () const;
+       double get_masters_value () const {
+               Glib::Threads::RWLock::ReaderLock lm (master_lock);
+               return get_masters_value_locked ();
+       }
+
        std::vector<PBD::ID> masters () const;
 
        PBD::Signal0<void> MasterStatusChange;
index f9a55cacfca6a3ebda7e3fd8630ef8e91241b231..8e5e3fd27ad5d2c9d08e872499dcde06abe841d8 100644 (file)
@@ -61,7 +61,6 @@ class LIBARDOUR_API MuteControl : public SlavableAutomationControl
        MuteMaster::MutePoint mute_points () const;
 
   protected:
-       void master_changed (bool, PBD::Controllable::GroupControlDisposition);
        void actually_set_value (double, PBD::Controllable::GroupControlDisposition group_override);
 
   private:
index 7f7e532669412d72144520884da1ff5f853784c5..d034456a3b204b3ed5398ee4b4ae87264072bdcd 100644 (file)
@@ -80,7 +80,6 @@ class LIBARDOUR_API SoloControl : public SlavableAutomationControl
        XMLNode& get_state ();
 
   protected:
-       void master_changed (bool, PBD::Controllable::GroupControlDisposition);
        void actually_set_value (double, PBD::Controllable::GroupControlDisposition group_override);
 
   private:
index 1c247c0e929c004316ebaa8fd9bc5566f1556499..1b7aa8fed8d7b02019bc6c3806a8334d92c2a554 100644 (file)
@@ -115,19 +115,12 @@ class LIBARDOUR_API VCA : public Stripable, public Soloable, public Muteable, pu
        boost::shared_ptr<SoloControl> _solo_control;
        boost::shared_ptr<MuteControl> _mute_control;
 
-       bool _solo_requested;
-       bool _mute_requested;
-
        static gint next_number;
 
        void solo_target_going_away (boost::weak_ptr<Route>);
        void mute_target_going_away (boost::weak_ptr<Route>);
        bool soloed_locked () const;
        bool muted_locked () const;
-
-       void set_solo (bool yn);
-       void set_mute (bool yn);
-
 };
 
 } /* namespace */
index 3cb82301985f01f9747af96f91e93f18a02bf230..508ddd12a6ca100eb2c587997bfbac51866e3919 100644 (file)
@@ -244,3 +244,4 @@ GainControl::vcas_loaded ()
        vca_loaded_connection.disconnect ();
        masters_string.clear ();
 }
+
index b0513d113849d856746aef0c5149acc91028b934..a639cbda7a848f153660659497e78b0f9781d75b 100644 (file)
@@ -39,21 +39,6 @@ MuteControl::MuteControl (Session& session, std::string const & name, Muteable&
        set_flags (Controllable::Flag (flags() | Controllable::RealTime));
 }
 
-void
-MuteControl::master_changed (bool from_self, PBD::Controllable::GroupControlDisposition gcd)
-{
-       bool master_muted;
-
-       {
-               Glib::Threads::RWLock::ReaderLock lm (master_lock);
-               master_muted = (bool) get_masters_value_locked ();
-       }
-
-       _muteable.mute_master()->mod_muted_by_others (master_muted ? 1 : -1);
-
-       SlavableAutomationControl::master_changed (false, gcd);
-}
-
 void
 MuteControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd)
 {
@@ -111,5 +96,5 @@ MuteControl::muted () const
 bool
 MuteControl::muted_by_others () const
 {
-       return _muteable.mute_master()->muted_by_others ();
+       return _muteable.mute_master()->muted_by_others () || get_masters_value();
 }
index 29709e3cbaafdf0eebf46ce8f930486433be6a7e..a45e30a91b4bab0ddf8c4d9255047bc5416a055d 100644 (file)
@@ -5460,7 +5460,7 @@ Route::vca_assign (boost::shared_ptr<VCA> vca)
 {
        _gain_control->add_master (vca->gain_control());
        _solo_control->add_master (vca->solo_control());
-       // _mute_control->add_master (vca->mute_control());
+       _mute_control->add_master (vca->mute_control());
 }
 
 void
@@ -5470,11 +5470,11 @@ Route::vca_unassign (boost::shared_ptr<VCA> vca)
                /* unassign from all */
                _gain_control->clear_masters ();
                _solo_control->clear_masters ();
-               //_mute_control->clear_masters ();
+               _mute_control->clear_masters ();
        } else {
                _gain_control->remove_master (vca->gain_control());
                _solo_control->remove_master (vca->solo_control());
-               //_mute_control->remove_master (vca->mute_control());
+               _mute_control->remove_master (vca->mute_control());
        }
 }
 
index 900e640e552c5668de9df0df03306ca66759cb3d..07a2d5633a70779b0b15986b3acaf6455b150409 100644 (file)
@@ -43,11 +43,18 @@ SlavableAutomationControl::~SlavableAutomationControl ()
 double
 SlavableAutomationControl::get_masters_value_locked () const
 {
-       gain_t v = 1.0;
+       gain_t v = _desc.normal;
 
        for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) {
-               /* get current master value, scale by our current ratio with that master */
-               v *= mr->second.master()->get_value () * mr->second.ratio();
+               if (_desc.toggled) {
+                       /* if any master is enabled, the slaves are too */
+                       if (mr->second.master()->get_value()) {
+                               return _desc.upper;
+                       }
+               } else {
+                       /* get current master value, scale by our current ratio with that master */
+                       v *= mr->second.master()->get_value () * mr->second.ratio();
+               }
        }
 
        return min (_desc.upper, v);
@@ -69,7 +76,7 @@ SlavableAutomationControl::get_value_locked() const
 double
 SlavableAutomationControl::get_value() const
 {
-       bool from_list = _list && ((AutomationList*)_list.get())->automation_playback();
+       bool from_list = _list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback();
 
        if (!from_list) {
                Glib::Threads::RWLock::ReaderLock lm (master_lock);
@@ -113,8 +120,8 @@ SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
                           because the change came from the master.
                        */
 
-
                        m->Changed.connect_same_thread (res.first->second.connection, boost::bind (&SlavableAutomationControl::master_changed, this, _1, _2));
+                       cerr << this << enum_2_string ((AutomationType) _parameter.type()) << " now listening to Changed from " << m << endl;
                }
 
                new_value = get_value_locked ();
@@ -126,13 +133,11 @@ SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
        }
 
        if (new_value != current_value) {
-               /* force a call to to ::master_changed() to carry the
-                * consequences that would occur if the master assumed
-                * its current value WHILE we were slaved.
+               /* need to do this without a writable() check in case
+                * the master is removed while this control is doing
+                * automation playback.
                 */
-               master_changed (false, Controllable::NoGroup);
-               /* effective value changed by master */
-               Changed (false, Controllable::NoGroup);
+                actually_set_value (new_value, Controllable::NoGroup);
        }
 
 }
@@ -140,6 +145,8 @@ SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
 void
 SlavableAutomationControl::master_changed (bool /*from_self*/, GroupControlDisposition gcd)
 {
+       cerr << this << enum_2_string ((AutomationType)_parameter.type()) << " master changed, relay changed along\n";
+
        /* our value has (likely) changed, but not because we were
         * modified. Just the master.
         */
index e8fbb6664372660b94e88b0179d1dff6b034265c..936cc2263a50ca80f5c59a8d2a037a7c1eef9766 100644 (file)
@@ -62,31 +62,6 @@ SoloControl::set_mute_master_solo ()
        }
 }
 
-void
-SoloControl::master_changed (bool from_self, PBD::Controllable::GroupControlDisposition gcd)
-{
-       if (_soloable.is_safe() || !_soloable.can_solo()) {
-               return;
-       }
-
-       bool master_soloed;
-
-       {
-               Glib::Threads::RWLock::ReaderLock lm (master_lock);
-               master_soloed = (bool) get_masters_value_locked ();
-       }
-
-       /* Master is considered equivalent to an upstream solo control, not
-        * direct control over self-soloed.
-        */
-
-       mod_solo_by_others_upstream (master_soloed ? 1 : -1);
-
-       /* no need to call AutomationControl::master_changed() since it just
-          emits Changed() which we already did in mod_solo_by_others_upstream()
-       */
-}
-
 void
 SoloControl::mod_solo_by_others_downstream (int32_t delta)
 {
index 39303fc8cadbe9818ffdadfefba64cfc2f91c882..edad50ebdbc311990681e05e63fd984174d07264 100644 (file)
@@ -67,8 +67,6 @@ VCA::VCA (Session& s,  uint32_t num, const string& name)
        , Automatable (s)
        , _number (num)
        , _gain_control (new GainControl (s, Evoral::Parameter (GainAutomation), boost::shared_ptr<AutomationList> ()))
-       , _solo_requested (false)
-       , _mute_requested (false)
 {
 }
 
@@ -102,10 +100,10 @@ VCA::get_state ()
        XMLNode* node = new XMLNode (xml_node_name);
        node->add_property (X_("name"), _name);
        node->add_property (X_("number"), _number);
-       node->add_property (X_("soloed"), (_solo_requested ? X_("yes") : X_("no")));
-       node->add_property (X_("muted"), (_mute_requested ? X_("yes") : X_("no")));
 
        node->add_child_nocopy (_gain_control->get_state());
+       node->add_child_nocopy (_solo_control->get_state());
+       node->add_child_nocopy (_mute_control->get_state());
        node->add_child_nocopy (get_automation_xml_state());
 
        return *node;
@@ -127,36 +125,26 @@ VCA::set_state (XMLNode const& node, int version)
        XMLNodeList const &children (node.children());
        for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
                if ((*i)->name() == Controllable::xml_node_name) {
+
                        XMLProperty* prop = (*i)->property ("name");
-                       if (prop && prop->value() == X_("gaincontrol")) {
+
+                       if (!prop) {
+                               continue;
+                       }
+
+                       if (prop->value() == _gain_control->name()) {
                                _gain_control->set_state (**i, version);
                        }
+                       if (prop->value() == _solo_control->name()) {
+                               _solo_control->set_state (**i, version);
+                       }
+                       if (prop->value() == _mute_control->name()) {
+                               _mute_control->set_state (**i, version);
+                       }
                }
        }
 
        return 0;
 }
 
-void
-VCA::set_solo (bool yn)
-{
-       _solo_requested = yn;
-}
-
-void
-VCA::set_mute (bool yn)
-{
-       _mute_requested = yn;
-}
 
-bool
-VCA::soloed () const
-{
-       return _solo_requested;
-}
-
-bool
-VCA::muted () const
-{
-       return _mute_requested;
-}
index d2296c59aeddd415c001a38ba558e1f4048fe4da..4168bbc2a0224d2240f0879f876d65481e0f4113 100644 (file)
@@ -56,7 +56,6 @@ class LIBPBD_API Controllable : public PBD::StatefulDestructible {
                GainLike = 0x2,
                RealTime = 0x4,
                NotAutomatable = 0x8,
-               
        };
 
        Controllable (const std::string& name, Flag f = Flag (0));