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 {
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;
}
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);
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);
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;
MuteMaster::MutePoint mute_points () const;
protected:
- void master_changed (bool, PBD::Controllable::GroupControlDisposition);
void actually_set_value (double, PBD::Controllable::GroupControlDisposition group_override);
private:
XMLNode& get_state ();
protected:
- void master_changed (bool, PBD::Controllable::GroupControlDisposition);
void actually_set_value (double, PBD::Controllable::GroupControlDisposition group_override);
private:
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 */
vca_loaded_connection.disconnect ();
masters_string.clear ();
}
+
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)
{
bool
MuteControl::muted_by_others () const
{
- return _muteable.mute_master()->muted_by_others ();
+ return _muteable.mute_master()->muted_by_others () || get_masters_value();
}
{
_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
/* 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());
}
}
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);
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);
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 ();
}
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);
}
}
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.
*/
}
}
-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)
{
, Automatable (s)
, _number (num)
, _gain_control (new GainControl (s, Evoral::Parameter (GainAutomation), boost::shared_ptr<AutomationList> ()))
- , _solo_requested (false)
- , _mute_requested (false)
{
}
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;
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;
-}
GainLike = 0x2,
RealTime = 0x4,
NotAutomatable = 0x8,
-
};
Controllable (const std::string& name, Flag f = Flag (0));