mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-16 19:56:31 +01:00
Fix save/load of MIDI automation state. Fixes #3354.
git-svn-id: svn://localhost/ardour2/branches/3.0@7578 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
7c5f1b7a26
commit
78986385e1
14 changed files with 136 additions and 49 deletions
|
|
@ -151,9 +151,7 @@ AutomationStreamView::display_region(AutomationRegionView* region_view)
|
||||||
void
|
void
|
||||||
AutomationStreamView::set_automation_state (AutoState state)
|
AutomationStreamView::set_automation_state (AutoState state)
|
||||||
{
|
{
|
||||||
/* XXX: not sure if this is right, but for now the automation state is basically held by
|
/* Setting the automation state for this view sets the state of all regions' lists to the same thing */
|
||||||
the regions' AutomationLists. Each region is always set to have the same AutoState.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (region_views.empty()) {
|
if (region_views.empty()) {
|
||||||
_pending_automation_state = state;
|
_pending_automation_state = state;
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ GenericPluginUI::automation_state_changed (ControlUI* cui)
|
||||||
|
|
||||||
// don't lock to avoid deadlock because we're triggered by
|
// don't lock to avoid deadlock because we're triggered by
|
||||||
// AutomationControl::Changed() while the automation lock is taken
|
// AutomationControl::Changed() while the automation lock is taken
|
||||||
switch (insert->get_parameter_automation_state (cui->parameter(), false)
|
switch (insert->get_parameter_automation_state (cui->parameter())
|
||||||
& (Off|Play|Touch|Write)) {
|
& (Off|Play|Touch|Write)) {
|
||||||
case Off:
|
case Off:
|
||||||
cui->automate_button.set_label (_("Manual"));
|
cui->automate_button.set_label (_("Manual"));
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ public:
|
||||||
|
|
||||||
virtual std::string describe_parameter(Evoral::Parameter param);
|
virtual std::string describe_parameter(Evoral::Parameter param);
|
||||||
|
|
||||||
AutoState get_parameter_automation_state (Evoral::Parameter param, bool lock = true);
|
AutoState get_parameter_automation_state (Evoral::Parameter param);
|
||||||
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
|
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
|
||||||
|
|
||||||
AutoStyle get_parameter_automation_style (Evoral::Parameter param);
|
AutoStyle get_parameter_automation_style (Evoral::Parameter param);
|
||||||
|
|
@ -95,16 +95,13 @@ public:
|
||||||
|
|
||||||
int set_automation_state (const XMLNode&, Evoral::Parameter default_param);
|
int set_automation_state (const XMLNode&, Evoral::Parameter default_param);
|
||||||
XMLNode& get_automation_state();
|
XMLNode& get_automation_state();
|
||||||
|
|
||||||
/** Emitted when the automation state of one of our controls changes */
|
|
||||||
PBD::Signal1<void, Evoral::Parameter> AutomationStateChanged;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Session& _a_session;
|
Session& _a_session;
|
||||||
|
|
||||||
void can_automate(Evoral::Parameter);
|
void can_automate(Evoral::Parameter);
|
||||||
|
|
||||||
virtual void auto_state_changed (Evoral::Parameter /*which*/) {}
|
virtual void automation_list_automation_state_changed (Evoral::Parameter, AutoState) {}
|
||||||
|
|
||||||
int load_automation (const std::string& path);
|
int load_automation (const std::string& path);
|
||||||
int old_set_automation_state(const XMLNode&);
|
int old_set_automation_state(const XMLNode&);
|
||||||
|
|
@ -116,7 +113,6 @@ public:
|
||||||
static nframes_t _automation_interval;
|
static nframes_t _automation_interval;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void automation_state_changed (Evoral::Parameter const &);
|
|
||||||
PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
|
PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlL
|
||||||
|
|
||||||
void set_automation_state (AutoState);
|
void set_automation_state (AutoState);
|
||||||
AutoState automation_state() const { return _state; }
|
AutoState automation_state() const { return _state; }
|
||||||
PBD::Signal0<void> automation_state_changed;
|
PBD::Signal1<void, AutoState> automation_state_changed;
|
||||||
|
|
||||||
void set_automation_style (AutoStyle m);
|
void set_automation_style (AutoStyle m);
|
||||||
AutoStyle automation_style() const { return _style; }
|
AutoStyle automation_style() const { return _style; }
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,9 @@ private:
|
||||||
friend class DeltaCommand;
|
friend class DeltaCommand;
|
||||||
|
|
||||||
void source_interpolation_changed (Evoral::Parameter, Evoral::ControlList::InterpolationStyle);
|
void source_interpolation_changed (Evoral::Parameter, Evoral::ControlList::InterpolationStyle);
|
||||||
|
void source_automation_state_changed (Evoral::Parameter, AutoState);
|
||||||
void control_list_interpolation_changed (Evoral::Parameter, Evoral::ControlList::InterpolationStyle);
|
void control_list_interpolation_changed (Evoral::Parameter, Evoral::ControlList::InterpolationStyle);
|
||||||
|
void automation_list_automation_state_changed (Evoral::Parameter, AutoState);
|
||||||
|
|
||||||
PBD::ScopedConnectionList _midi_source_connections;
|
PBD::ScopedConnectionList _midi_source_connections;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,10 +122,17 @@ class MidiSource : virtual public Source
|
||||||
void copy_interpolation_from (boost::shared_ptr<MidiSource>);
|
void copy_interpolation_from (boost::shared_ptr<MidiSource>);
|
||||||
void copy_interpolation_from (MidiSource *);
|
void copy_interpolation_from (MidiSource *);
|
||||||
|
|
||||||
|
AutoState automation_state_of (Evoral::Parameter) const;
|
||||||
|
void set_automation_state_of (Evoral::Parameter, AutoState);
|
||||||
|
void copy_automation_state_from (boost::shared_ptr<MidiSource>);
|
||||||
|
void copy_automation_state_from (MidiSource *);
|
||||||
|
|
||||||
/** Emitted when a different MidiModel is set */
|
/** Emitted when a different MidiModel is set */
|
||||||
PBD::Signal0<void> ModelChanged;
|
PBD::Signal0<void> ModelChanged;
|
||||||
/** Emitted when a parameter's interpolation style is changed */
|
/** Emitted when a parameter's interpolation style is changed */
|
||||||
PBD::Signal2<void, Evoral::Parameter, Evoral::ControlList::InterpolationStyle> InterpolationChanged;
|
PBD::Signal2<void, Evoral::Parameter, Evoral::ControlList::InterpolationStyle> InterpolationChanged;
|
||||||
|
/** Emitted when a parameter's automation state is changed */
|
||||||
|
PBD::Signal2<void, Evoral::Parameter, AutoState> AutomationStateChanged;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void flush_midi() = 0;
|
virtual void flush_midi() = 0;
|
||||||
|
|
@ -159,6 +166,12 @@ class MidiSource : virtual public Source
|
||||||
*/
|
*/
|
||||||
typedef std::map<Evoral::Parameter, Evoral::ControlList::InterpolationStyle> InterpolationStyleMap;
|
typedef std::map<Evoral::Parameter, Evoral::ControlList::InterpolationStyle> InterpolationStyleMap;
|
||||||
InterpolationStyleMap _interpolation_style;
|
InterpolationStyleMap _interpolation_style;
|
||||||
|
|
||||||
|
/** Map of automation states to use for Parameters; if they are not in this map,
|
||||||
|
* the correct automation state is Off.
|
||||||
|
*/
|
||||||
|
typedef std::map<Evoral::Parameter, AutoState> AutomationStateMap;
|
||||||
|
AutomationStateMap _automation_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ class PluginInsert : public Processor
|
||||||
void connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now = 0);
|
void connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now = 0);
|
||||||
|
|
||||||
void set_automatable ();
|
void set_automatable ();
|
||||||
void auto_state_changed (Evoral::Parameter which);
|
void control_list_automation_state_changed (Evoral::Parameter, AutoState);
|
||||||
void set_parameter_state (const XMLNode& node, int version);
|
void set_parameter_state (const XMLNode& node, int version);
|
||||||
void set_parameter_state_2X (const XMLNode& node, int version);
|
void set_parameter_state_2X (const XMLNode& node, int version);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,19 +147,17 @@ Automatable::add_control(boost::shared_ptr<Evoral::Control> ac)
|
||||||
{
|
{
|
||||||
Evoral::Parameter param = ac->parameter();
|
Evoral::Parameter param = ac->parameter();
|
||||||
|
|
||||||
ControlSet::add_control(ac);
|
boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (ac->list ());
|
||||||
_can_automate_list.insert(param);
|
assert (al);
|
||||||
auto_state_changed(param); // sync everything up
|
|
||||||
|
al->automation_state_changed.connect_same_thread (
|
||||||
|
_list_connections, boost::bind (&Automatable::automation_list_automation_state_changed, this, ac->parameter(), _1)
|
||||||
|
);
|
||||||
|
|
||||||
/* connect to automation_state_changed so that we can emit a signal when one of our controls'
|
ControlSet::add_control (ac);
|
||||||
automation state changes
|
_can_automate_list.insert (param);
|
||||||
*/
|
|
||||||
boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl> (ac);
|
automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up
|
||||||
if (c) {
|
|
||||||
c->alist()->automation_state_changed.connect_same_thread (
|
|
||||||
_control_connections, boost::bind (&Automatable::automation_state_changed, this, c->parameter())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -315,21 +313,16 @@ Automatable::set_parameter_automation_state (Evoral::Parameter param, AutoState
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoState
|
AutoState
|
||||||
Automatable::get_parameter_automation_state (Evoral::Parameter param, bool lock)
|
Automatable::get_parameter_automation_state (Evoral::Parameter param)
|
||||||
{
|
{
|
||||||
AutoState result = Off;
|
AutoState result = Off;
|
||||||
|
|
||||||
if (lock)
|
|
||||||
control_lock().lock();
|
|
||||||
|
|
||||||
boost::shared_ptr<Evoral::Control> c = control(param);
|
boost::shared_ptr<Evoral::Control> c = control(param);
|
||||||
boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list());
|
boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list());
|
||||||
|
|
||||||
if (c)
|
if (c) {
|
||||||
result = l->automation_state();
|
result = l->automation_state();
|
||||||
|
}
|
||||||
if (lock)
|
|
||||||
control_lock().unlock();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -479,16 +472,9 @@ Automatable::automation_control (const Evoral::Parameter& id) const
|
||||||
return boost::dynamic_pointer_cast<const AutomationControl>(Evoral::ControlSet::control(id));
|
return boost::dynamic_pointer_cast<const AutomationControl>(Evoral::ControlSet::control(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Automatable::automation_state_changed (Evoral::Parameter const & p)
|
|
||||||
{
|
|
||||||
AutomationStateChanged (p); /* EMIT SIGNAL */
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Automatable::clear_controls ()
|
Automatable::clear_controls ()
|
||||||
{
|
{
|
||||||
_control_connections.drop_connections ();
|
_control_connections.drop_connections ();
|
||||||
ControlSet::clear_controls ();
|
ControlSet::clear_controls ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ AutomationList::set_automation_state (AutoState s)
|
||||||
{
|
{
|
||||||
if (s != _state) {
|
if (s != _state) {
|
||||||
_state = s;
|
_state = s;
|
||||||
automation_state_changed (); /* EMIT SIGNAL */
|
automation_state_changed (s); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1094,14 +1094,18 @@ MidiModel::set_midi_source (MidiSource* s)
|
||||||
_midi_source->InterpolationChanged.connect_same_thread (
|
_midi_source->InterpolationChanged.connect_same_thread (
|
||||||
_midi_source_connections, boost::bind (&MidiModel::source_interpolation_changed, this, _1, _2)
|
_midi_source_connections, boost::bind (&MidiModel::source_interpolation_changed, this, _1, _2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_midi_source->AutomationStateChanged.connect_same_thread (
|
||||||
|
_midi_source_connections, boost::bind (&MidiModel::source_automation_state_changed, this, _1, _2)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The source has signalled that the interpolation style for a parameter has changed. In order to
|
/** The source has signalled that the interpolation style for a parameter has changed. In order to
|
||||||
* keep MidiSource and ControlList interpolation state the same, we pass this change onto the
|
* keep MidiSource and ControlList interpolation state the same, we pass this change onto the
|
||||||
* appropriate ControlList.
|
* appropriate ControlList.
|
||||||
*
|
*
|
||||||
* The idea is that MidiSource and the MidiModel's ControlList states are kept in sync, and the
|
* The idea is that MidiSource and the MidiModel's ControlList states are kept in sync, and one
|
||||||
* MidiSource's InterpolationChanged signal is listened to by the GUI.
|
* or the other is listened to by the GUI.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
MidiModel::source_interpolation_changed (Evoral::Parameter p, Evoral::ControlList::InterpolationStyle s)
|
MidiModel::source_interpolation_changed (Evoral::Parameter p, Evoral::ControlList::InterpolationStyle s)
|
||||||
|
|
@ -1119,18 +1123,37 @@ MidiModel::control_list_interpolation_changed (Evoral::Parameter p, Evoral::Cont
|
||||||
_midi_source->set_interpolation_of (p, s);
|
_midi_source->set_interpolation_of (p, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiModel::source_automation_state_changed (Evoral::Parameter p, AutoState s)
|
||||||
|
{
|
||||||
|
Glib::Mutex::Lock lm (_control_lock);
|
||||||
|
boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (control(p)->list ());
|
||||||
|
al->set_automation_state (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiModel::automation_list_automation_state_changed (Evoral::Parameter p, AutoState s)
|
||||||
|
{
|
||||||
|
_midi_source->set_automation_state_of (p, s);
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Evoral::Control>
|
boost::shared_ptr<Evoral::Control>
|
||||||
MidiModel::control_factory (Evoral::Parameter const & p)
|
MidiModel::control_factory (Evoral::Parameter const & p)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Evoral::Control> c = Automatable::control_factory (p);
|
boost::shared_ptr<Evoral::Control> c = Automatable::control_factory (p);
|
||||||
|
|
||||||
/* Set up newly created control's lists to the appropriate interpolation state
|
/* Set up newly created control's lists to the appropriate interpolation and
|
||||||
from our source.
|
automation state from our source.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
assert (_midi_source);
|
assert (_midi_source);
|
||||||
|
|
||||||
c->list()->set_interpolation (_midi_source->interpolation_of (p));
|
c->list()->set_interpolation (_midi_source->interpolation_of (p));
|
||||||
|
|
||||||
|
boost::shared_ptr<AutomationList> al = boost::dynamic_pointer_cast<AutomationList> (c->list ());
|
||||||
|
assert (al);
|
||||||
|
|
||||||
|
al->set_automation_state (_midi_source->automation_state_of (p));
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ MidiRegion::model_changed ()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* watch for changes to controls' AutoState */
|
/* watch for changes to controls' AutoState */
|
||||||
model()->AutomationStateChanged.connect_same_thread (
|
midi_source()->AutomationStateChanged.connect_same_thread (
|
||||||
_model_connection, boost::bind (&MidiRegion::model_automation_state_changed, this, _1)
|
_model_connection, boost::bind (&MidiRegion::model_automation_state_changed, this, _1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,13 @@ MidiSource::get_state ()
|
||||||
child->add_property (X_("parameter"), EventTypeMap::instance().to_symbol (i->first));
|
child->add_property (X_("parameter"), EventTypeMap::instance().to_symbol (i->first));
|
||||||
child->add_property (X_("style"), enum_2_string (i->second));
|
child->add_property (X_("style"), enum_2_string (i->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (AutomationStateMap::const_iterator i = _automation_state.begin(); i != _automation_state.end(); ++i) {
|
||||||
|
XMLNode* child = node.add_child (X_("AutomationState"));
|
||||||
|
child->add_property (X_("parameter"), EventTypeMap::instance().to_symbol (i->first));
|
||||||
|
child->add_property (X_("state"), enum_2_string (i->second));
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,6 +140,25 @@ MidiSource::set_state (const XMLNode& node, int /*version*/)
|
||||||
|
|
||||||
Evoral::ControlList::InterpolationStyle s = static_cast<Evoral::ControlList::InterpolationStyle> (string_2_enum (prop->value(), s));
|
Evoral::ControlList::InterpolationStyle s = static_cast<Evoral::ControlList::InterpolationStyle> (string_2_enum (prop->value(), s));
|
||||||
set_interpolation_of (p, s);
|
set_interpolation_of (p, s);
|
||||||
|
|
||||||
|
} else if ((*i)->name() == X_("AutomationState")) {
|
||||||
|
|
||||||
|
XMLProperty* prop;
|
||||||
|
|
||||||
|
if ((prop = (*i)->property (X_("parameter"))) == 0) {
|
||||||
|
error << _("Missing parameter property on AutomationState") << endmsg;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Evoral::Parameter p = EventTypeMap::instance().new_parameter (prop->value());
|
||||||
|
|
||||||
|
if ((prop = (*i)->property (X_("state"))) == 0) {
|
||||||
|
error << _("Missing state property on AutomationState") << endmsg;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoState s = static_cast<AutoState> (string_2_enum (prop->value(), s));
|
||||||
|
set_automation_state_of (p, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,6 +315,7 @@ MidiSource::clone (Evoral::MusicalTime begin, Evoral::MusicalTime end)
|
||||||
|
|
||||||
newsrc->set_timeline_position(_timeline_position);
|
newsrc->set_timeline_position(_timeline_position);
|
||||||
newsrc->copy_interpolation_from (this);
|
newsrc->copy_interpolation_from (this);
|
||||||
|
newsrc->copy_automation_state_from (this);
|
||||||
|
|
||||||
if (_model) {
|
if (_model) {
|
||||||
if (begin == Evoral::MinMusicalTime && end == Evoral::MaxMusicalTime) {
|
if (begin == Evoral::MinMusicalTime && end == Evoral::MaxMusicalTime) {
|
||||||
|
|
@ -385,6 +411,17 @@ MidiSource::interpolation_of (Evoral::Parameter p) const
|
||||||
return i->second;
|
return i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoState
|
||||||
|
MidiSource::automation_state_of (Evoral::Parameter p) const
|
||||||
|
{
|
||||||
|
AutomationStateMap::const_iterator i = _automation_state.find (p);
|
||||||
|
if (i == _automation_state.end()) {
|
||||||
|
return Off;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
/** Set interpolation style to be used for a given parameter. This change will be
|
/** Set interpolation style to be used for a given parameter. This change will be
|
||||||
* propagated to anyone who needs to know.
|
* propagated to anyone who needs to know.
|
||||||
*/
|
*/
|
||||||
|
|
@ -405,12 +442,35 @@ MidiSource::set_interpolation_of (Evoral::Parameter p, Evoral::ControlList::Inte
|
||||||
InterpolationChanged (p, s); /* EMIT SIGNAL */
|
InterpolationChanged (p, s); /* EMIT SIGNAL */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiSource::set_automation_state_of (Evoral::Parameter p, AutoState s)
|
||||||
|
{
|
||||||
|
if (automation_state_of (p) == s) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s == Off) {
|
||||||
|
/* automation state is being set to the default, so we don't need a note in our map */
|
||||||
|
_automation_state.erase (p);
|
||||||
|
} else {
|
||||||
|
_automation_state[p] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomationStateChanged (p, s); /* EMIT SIGNAL */
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiSource::copy_interpolation_from (boost::shared_ptr<MidiSource> s)
|
MidiSource::copy_interpolation_from (boost::shared_ptr<MidiSource> s)
|
||||||
{
|
{
|
||||||
copy_interpolation_from (s.get ());
|
copy_interpolation_from (s.get ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiSource::copy_automation_state_from (boost::shared_ptr<MidiSource> s)
|
||||||
|
{
|
||||||
|
copy_automation_state_from (s.get ());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiSource::copy_interpolation_from (MidiSource* s)
|
MidiSource::copy_interpolation_from (MidiSource* s)
|
||||||
{
|
{
|
||||||
|
|
@ -418,3 +478,11 @@ MidiSource::copy_interpolation_from (MidiSource* s)
|
||||||
|
|
||||||
/* XXX: should probably emit signals here */
|
/* XXX: should probably emit signals here */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiSource::copy_automation_state_from (MidiSource* s)
|
||||||
|
{
|
||||||
|
_automation_state = s->_automation_state;
|
||||||
|
|
||||||
|
/* XXX: should probably emit signals here */
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ PluginInsert::~PluginInsert ()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginInsert::auto_state_changed (Evoral::Parameter which)
|
PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
|
||||||
{
|
{
|
||||||
if (which.type() != PluginAutomation)
|
if (which.type() != PluginAutomation)
|
||||||
return;
|
return;
|
||||||
|
|
@ -122,7 +122,7 @@ PluginInsert::auto_state_changed (Evoral::Parameter which)
|
||||||
boost::shared_ptr<AutomationControl> c
|
boost::shared_ptr<AutomationControl> c
|
||||||
= boost::dynamic_pointer_cast<AutomationControl>(control (which));
|
= boost::dynamic_pointer_cast<AutomationControl>(control (which));
|
||||||
|
|
||||||
if (c && ((AutomationList*)c->list().get())->automation_state() != Off) {
|
if (c && s != Off) {
|
||||||
_plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
|
_plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,10 +74,11 @@ protected:
|
||||||
mutable Glib::Mutex _control_lock;
|
mutable Glib::Mutex _control_lock;
|
||||||
Controls _controls;
|
Controls _controls;
|
||||||
|
|
||||||
|
PBD::ScopedConnectionList _list_connections;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
PBD::ScopedConnectionList _control_connections;
|
PBD::ScopedConnectionList _control_connections;
|
||||||
PBD::ScopedConnectionList _list_connections;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue