a slew of as-yet incomplete work to get VCA solo+mute closer to working
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -244,3 +244,4 @@ GainControl::vcas_loaded ()
|
||||
vca_loaded_connection.disconnect ();
|
||||
masters_string.clear ();
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user