MixerScene: correctly restore controls with VCA master
The master needs to be restored first, otherwise setting the master value with be propagated. Furthermore the actual value is saved at the time of VCA assignment. Restoring the vaule needs to scale by the master-reduced value.
This commit is contained in:
parent
7d6e429001
commit
2129552777
|
@ -21,14 +21,15 @@
|
|||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "pbd/controllable.h"
|
||||
#include "pbd/properties.h"
|
||||
#include "pbd/stateful.h"
|
||||
|
||||
#include "ardour/automation_control.h"
|
||||
#include "ardour/libardour_visibility.h"
|
||||
#include "ardour/session_handle.h"
|
||||
|
||||
namespace PBD {
|
||||
class Controllable;
|
||||
}
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class LIBARDOUR_API MixerScene : public SessionHandleRef, public PBD::Stateful
|
||||
|
@ -50,6 +51,8 @@ public:
|
|||
private:
|
||||
typedef std::map<PBD::ID, double> ControllableValueMap;
|
||||
|
||||
bool recurse_to_master (boost::shared_ptr<PBD::Controllable>, std::set <PBD::ID>&) const;
|
||||
|
||||
ControllableValueMap _ctrl_map;
|
||||
std::string _name;
|
||||
};
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "pbd/controllable.h"
|
||||
#include "pbd/types_convert.h"
|
||||
|
||||
#include "ardour/automation_control.h"
|
||||
#include "ardour/mixer_scene.h"
|
||||
#include "ardour/slavable_automation_control.h"
|
||||
#include "ardour/session.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
@ -56,24 +59,68 @@ MixerScene::snapshot ()
|
|||
if (!boost::dynamic_pointer_cast<AutomationControl> (c)) {
|
||||
continue;
|
||||
}
|
||||
if (c->flags () & Controllable::HiddenControl) {
|
||||
continue;
|
||||
}
|
||||
_ctrl_map[c->id ()] = c->get_save_value ();
|
||||
}
|
||||
_session.set_dirty ();
|
||||
}
|
||||
|
||||
bool
|
||||
MixerScene::recurse_to_master (boost::shared_ptr<PBD::Controllable> c, std::set <PBD::ID>& done) const
|
||||
{
|
||||
if (done.find (c->id()) != done.end ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 1 /* ignore controls in Write, or Touch + touching() state */
|
||||
auto ac = boost::dynamic_pointer_cast<AutomationControl> (c);
|
||||
if (ac && ac->automation_write ()) {
|
||||
done.insert (c->id ());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto sc = boost::dynamic_pointer_cast<SlavableAutomationControl> (c);
|
||||
if (sc && sc->slaved ()) {
|
||||
/* first set masters, then set own value */
|
||||
for (auto const& m : sc->masters ()) {
|
||||
recurse_to_master (m, done);
|
||||
}
|
||||
}
|
||||
|
||||
ControllableValueMap::const_iterator it = _ctrl_map.find (c->id ());
|
||||
if (it == _ctrl_map.end ()) {
|
||||
done.insert (c->id ());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sc && sc->slaved ()) {
|
||||
double x = sc->reduce_by_masters (1.0);
|
||||
if (x <= 0) {
|
||||
c->set_value (0, Controllable::NoGroup);
|
||||
} else {
|
||||
c->set_value (it->second / x, Controllable::NoGroup);
|
||||
}
|
||||
} else {
|
||||
c->set_value (it->second, Controllable::NoGroup);
|
||||
}
|
||||
|
||||
done.insert (it->first);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MixerScene::apply () const
|
||||
{
|
||||
bool rv = false;
|
||||
// TODO special-case solo-iso, and solo (restore order, or ignore)
|
||||
std::set<PBD::ID> done;
|
||||
|
||||
for (auto const& c : Controllable::registered_controllables ()) {
|
||||
ControllableValueMap::const_iterator it = _ctrl_map.find (c->id ());
|
||||
if (it == _ctrl_map.end ()) {
|
||||
continue;
|
||||
}
|
||||
rv = true;
|
||||
c->set_value (it->second, Controllable::NoGroup);
|
||||
rv |= recurse_to_master (c, done);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue