diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2016-04-15 00:38:03 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-05-31 15:30:41 -0400 |
commit | 6de4953be8dc5cd413b405d4801f086567923965 (patch) | |
tree | 4e428efc0668e9dc78d8cfee407042b7f976742d /libs | |
parent | 7d493b091ae2741db39a65cc62e9d17ef57d7606 (diff) |
a variety of changes that get closer to correctly functioning behaviour for VCA solo+mute (BUT ARE NOT DONE YET)
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/automation_control.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/gain_control.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/mute_control.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/mute_master.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 3 | ||||
-rw-r--r-- | libs/ardour/gain_control.cc | 22 | ||||
-rw-r--r-- | libs/ardour/mute_control.cc | 65 | ||||
-rw-r--r-- | libs/ardour/mute_master.cc | 1 | ||||
-rw-r--r-- | libs/ardour/route.cc | 18 | ||||
-rw-r--r-- | libs/ardour/slavable_automation_control.cc | 79 | ||||
-rw-r--r-- | libs/ardour/solo_control.cc | 3 |
11 files changed, 132 insertions, 69 deletions
diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index f576cb52c0..6195f90a68 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -152,8 +152,6 @@ class SlavableAutomationControl : public AutomationControl boost::shared_ptr<ARDOUR::AutomationList> l=boost::shared_ptr<ARDOUR::AutomationList>(), const std::string& name=""); - ~SlavableAutomationControl (); - double get_value () const; void add_master (boost::shared_ptr<AutomationControl>); @@ -200,7 +198,7 @@ class SlavableAutomationControl : public AutomationControl virtual void recompute_masters_ratios (double val) { /* do nothing by default */} virtual double get_masters_value_locked () const; double get_value_locked() const; - + void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override); }; diff --git a/libs/ardour/ardour/gain_control.h b/libs/ardour/ardour/gain_control.h index f68ec00452..32d1ad1229 100644 --- a/libs/ardour/ardour/gain_control.h +++ b/libs/ardour/ardour/gain_control.h @@ -59,8 +59,6 @@ class LIBARDOUR_API GainControl : public SlavableAutomationControl { void vcas_loaded(); void recompute_masters_ratios (double val); - - void actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override); }; } /* namespace */ diff --git a/libs/ardour/ardour/mute_control.h b/libs/ardour/ardour/mute_control.h index 8e5e3fd27a..f7a7814f00 100644 --- a/libs/ardour/ardour/mute_control.h +++ b/libs/ardour/ardour/mute_control.h @@ -53,6 +53,7 @@ class LIBARDOUR_API MuteControl : public SlavableAutomationControl */ bool muted () const; + bool muted_by_self () const; bool muted_by_others_soloing () const; bool muted_by_others () const; @@ -61,6 +62,7 @@ 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: diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h index d147a58771..d8b2bf0021 100644 --- a/libs/ardour/ardour/mute_master.h +++ b/libs/ardour/ardour/mute_master.h @@ -70,7 +70,7 @@ class LIBARDOUR_API MuteMaster : public SessionHandleRef, public PBD::Stateful void set_solo_ignore (bool yn) { _solo_ignore = yn; } void mod_muted_by_others (int32_t delta); - bool muted_by_others () const { return _muted_by_others; } + int32_t muted_by_others () const { return _muted_by_others; } PBD::Signal0<void> MutePointChanged; diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 6c0380963d..9f66b95b6c 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -460,8 +460,9 @@ public: bool can_be_muted_by_others () const { return !is_master(); } bool muted () const { return _mute_control->muted(); } + bool muted_by_others () const { return _mute_control->muted_by_others(); } + bool muted_by_self () const { return _mute_control->muted_by_self(); } bool muted_by_others_soloing () const; - bool muted_by_others () const; boost::shared_ptr<SoloIsolateControl> solo_isolate_control() const { return _solo_isolate_control; diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc index 508ddd12a6..3ffeb057da 100644 --- a/libs/ardour/gain_control.cc +++ b/libs/ardour/gain_control.cc @@ -43,28 +43,6 @@ GainControl::GainControl (Session& session, const Evoral::Parameter ¶m, boos range_db = accurate_coefficient_to_dB (_desc.upper) - lower_db; } -void -GainControl::actually_set_value (double val, Controllable::GroupControlDisposition group_override) -{ - val = std::max (std::min (val, (double)_desc.upper), (double)_desc.lower); - - { - Glib::Threads::RWLock::WriterLock lm (master_lock); - - if (!_masters.empty()) { - recompute_masters_ratios (val); - } - } - - /* this sets the Evoral::Control::_user_value for us, which will - be retrieved by AutomationControl::get_value () - */ - - AutomationControl::actually_set_value (val, group_override); - - _session.set_dirty (); -} - double GainControl::internal_to_interface (double v) const { diff --git a/libs/ardour/mute_control.cc b/libs/ardour/mute_control.cc index a639cbda7a..8d35b02445 100644 --- a/libs/ardour/mute_control.cc +++ b/libs/ardour/mute_control.cc @@ -42,7 +42,7 @@ MuteControl::MuteControl (Session& session, std::string const & name, Muteable& void MuteControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd) { - if (muted() != bool (val)) { + if (muted_by_self() != bool (val)) { _muteable.mute_master()->set_muted_by_self (val); /* allow the Muteable to respond to the mute change @@ -54,12 +54,63 @@ MuteControl::actually_set_value (double val, Controllable::GroupControlDispositi AutomationControl::actually_set_value (val, gcd); } +void +MuteControl::master_changed (bool self_change, Controllable::GroupControlDisposition gcd) +{ + double m = get_masters_value (); + const int32_t old_muted_by_others = _muteable.mute_master()->muted_by_others (); + std::cerr << "master " << (self_change ? " self " : " not-self") << " changed to " << m << " old others = " << old_muted_by_others << std::endl; + + _muteable.mute_master()->mod_muted_by_others (m ? 1 : -1); + + if (m) { + /* master(s) are now muted. If we are self-muted, this + doesn't change our status. If we are not self-muted, + then it changes our status if either: + + - the master had its own self-muted status changed OR + - the total number of masters that are muted used to be zero + */ + + if (!muted_by_self()) { + if (self_change || old_muted_by_others == 0) { + /* note false as the first argument - our own + value was not changed + */ + Changed (false, gcd); + } else { + cerr << " no Change signal\n"; + } + } else { + cerr << "muted by self, not relevant\n"; + } + } else { + /* no master(s) are now muted. If we are self-muted, this + doesn't change our status. If we are not self-muted, + then it changes our status if either: + + - the master had its own self-muted status changed OR + - the total number of masters that are muted used to be non-zero + */ + + if (!muted_by_self()) { + if (self_change || old_muted_by_others != 0) { + Changed (false, gcd); + } else { + cerr << " No change signal\n"; + } + } else { + cerr << "muted by self, not relevant\n"; + } + } +} + double MuteControl::get_value () const { - if (slaved()) { + if (slaved ()) { Glib::Threads::RWLock::ReaderLock lm (master_lock); - return get_masters_value_locked () ? 1.0 : 0.0; + return get_masters_value_locked (); } if (_list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback()) { @@ -90,11 +141,17 @@ MuteControl::mute_points () const bool MuteControl::muted () const { + return _muteable.mute_master()->muted_by_self() || _muteable.mute_master()->muted_by_others(); +} + +bool +MuteControl::muted_by_self () const +{ return _muteable.mute_master()->muted_by_self(); } bool MuteControl::muted_by_others () const { - return _muteable.mute_master()->muted_by_others () || get_masters_value(); + return _muteable.mute_master()->muted_by_others (); } diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc index 6817374dc7..c13131c11b 100644 --- a/libs/ardour/mute_master.cc +++ b/libs/ardour/mute_master.cc @@ -173,4 +173,5 @@ void MuteMaster::mod_muted_by_others (int32_t delta) { _muted_by_others = max (0, _muted_by_others + delta); + std::cerr << this << " mod others by " << delta << " to get " << _muted_by_others << endl; } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index a45e30a91b..7da7e42abf 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -5481,27 +5481,13 @@ Route::vca_unassign (boost::shared_ptr<VCA> vca) bool Route::muted_by_others_soloing () const { - // This method is only used by route_ui for display state. - // The DSP version is MuteMaster::muted_by_others_at() - if (!can_be_muted_by_others ()) { return false; } - return _session.soloing() && !_solo_control->soloed() && !_solo_isolate_control->solo_isolated(); -} - -bool -Route::muted_by_others () const -{ - // This method is only used by route_ui for display state. - // The DSP version is MuteMaster::muted_by_others_at() - - if (!can_be_muted_by_others()) { - return false; - } + /* XXX something needed here re: mute-overrides-solo */ - return _mute_master->muted_by_others(); + return _session.soloing() && !_solo_control->soloed() && !_solo_isolate_control->solo_isolated(); } void diff --git a/libs/ardour/slavable_automation_control.cc b/libs/ardour/slavable_automation_control.cc index 07a2d5633a..624fa484ca 100644 --- a/libs/ardour/slavable_automation_control.cc +++ b/libs/ardour/slavable_automation_control.cc @@ -19,6 +19,8 @@ #ifndef __libardour_slavable_automation_control_h__ #define __libardour_slavable_automation_control_h__ +#include "pbd/enumwriter.h" + #include "ardour/automation_control.h" #include "ardour/session.h" @@ -35,29 +37,26 @@ SlavableAutomationControl::SlavableAutomationControl(ARDOUR::Session& s, { } -SlavableAutomationControl::~SlavableAutomationControl () -{ - -} - double SlavableAutomationControl::get_masters_value_locked () const { - gain_t v = _desc.normal; + double v = _desc.normal; - for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) { - if (_desc.toggled) { - /* if any master is enabled, the slaves are too */ + if (_desc.toggled) { + for (Masters::const_iterator mr = _masters.begin(); mr != _masters.end(); ++mr) { 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 _desc.lower; + } + + 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(); } - return min (_desc.upper, v); + return min ((double) _desc.upper, v); } double @@ -69,6 +68,16 @@ SlavableAutomationControl::get_value_locked() const return Control::get_double (false, _session.transport_frame()); } + if (_desc.toggled) { + /* for boolean/toggle controls, if this slave OR any master is + * enabled, this slave is enabled. So check our own value + * first, because if we are enabled, we can return immediately. + */ + if (Control::get_double (false, _session.transport_frame())) { + return _desc.upper; + } + } + return get_masters_value_locked (); } @@ -87,6 +96,27 @@ SlavableAutomationControl::get_value() const } void +SlavableAutomationControl::actually_set_value (double val, Controllable::GroupControlDisposition group_override) +{ + val = std::max (std::min (val, (double)_desc.upper), (double)_desc.lower); + + { + Glib::Threads::RWLock::WriterLock lm (master_lock); + + if (!_masters.empty()) { + recompute_masters_ratios (val); + } + } + + /* this sets the Evoral::Control::_user_value for us, which will + be retrieved by AutomationControl::get_value () + */ + AutomationControl::actually_set_value (val, group_override); + + _session.set_dirty (); +} + +void SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m) { double current_value; @@ -103,7 +133,9 @@ SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m) if (res.second) { - recompute_masters_ratios (current_value); + if (_desc.toggled) { + recompute_masters_ratios (current_value); + } /* note that we bind @param m as a weak_ptr<AutomationControl>, thus avoiding holding a reference to the control in the binding @@ -145,13 +177,17 @@ 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. */ - Changed (false, gcd); /* EMIT SIGNAL */ + /* propagate master state into our own control so that if we stop + * being slaved, our value doesn't change, and propagate to any + * group this control is part of. + */ + + cerr << this << ' ' << enum_2_string ((AutomationType) _parameter.type()) << " pass along " << get_masters_value() << " from master to group\n"; + actually_set_value (get_masters_value(), Controllable::UseGroup); } void @@ -168,6 +204,7 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m { double current_value; double new_value; + bool masters_left; Masters::size_type erased = 0; { @@ -177,6 +214,7 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m if (erased) { recompute_masters_ratios (current_value); } + masters_left = _masters.size (); new_value = get_value_locked (); } @@ -185,7 +223,12 @@ SlavableAutomationControl::remove_master (boost::shared_ptr<AutomationControl> m } if (new_value != current_value) { - Changed (false, Controllable::NoGroup); + if (masters_left == 0) { + /* no masters left, make sure we keep the same value + that we had before. + */ + actually_set_value (current_value, Controllable::UseGroup); + } } } diff --git a/libs/ardour/solo_control.cc b/libs/ardour/solo_control.cc index 936cc2263a..76e7ca536a 100644 --- a/libs/ardour/solo_control.cc +++ b/libs/ardour/solo_control.cc @@ -155,8 +155,7 @@ SoloControl::actually_set_value (double val, PBD::Controllable::GroupControlDisp be retrieved by AutomationControl::get_value (), and emits Changed */ - AutomationControl::actually_set_value (val, group_override); - _session.set_dirty (); + SlavableAutomationControl::actually_set_value (val, group_override); } double |