From 5f5f4599f25d8d986eee833749a6c45f52c66334 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 22 Jul 2022 02:01:10 +0200 Subject: [PATCH] Fix MIDISource event-interpolation state save The actual goal here is to use direct InterpolationStyle serialization in MidiSource (identical to AutomationList). enum_2_string() does not work for Evoral types. As side-effect virtual base-classes have been changed to pass Parameters as const references --- libs/ardour/ardour/automatable.h | 2 +- libs/ardour/ardour/midi_model.h | 12 ++++++------ libs/ardour/ardour/midi_source.h | 13 +++++++------ libs/ardour/automatable.cc | 2 +- libs/ardour/midi_model.cc | 8 ++++---- libs/ardour/midi_source.cc | 30 +++++++++++++++++++----------- libs/evoral/evoral/ControlSet.h | 2 +- 7 files changed, 39 insertions(+), 30 deletions(-) diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h index 2bf122cbdb..c4b09cb367 100644 --- a/libs/ardour/ardour/automatable.h +++ b/libs/ardour/ardour/automatable.h @@ -121,7 +121,7 @@ protected: void can_automate(Evoral::Parameter); - virtual void automation_list_automation_state_changed (Evoral::Parameter, AutoState); + virtual void automation_list_automation_state_changed (Evoral::Parameter const&, AutoState); SerializedRCUManager _automated_controls; int load_automation (const std::string& path); diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h index 6f4966e175..b8eb9a2e25 100644 --- a/libs/ardour/ardour/midi_model.h +++ b/libs/ardour/ardour/midi_model.h @@ -33,9 +33,9 @@ #include "pbd/command.h" +#include "ardour/libardour_visibility.h" +#include "ardour/automation_list.h" #include "ardour/automatable_sequence.h" -#include "ardour/libardour_visibility.h" -#include "ardour/libardour_visibility.h" #include "ardour/source.h" #include "ardour/types.h" #include "ardour/types.h" @@ -348,10 +348,10 @@ public: private: friend class DeltaCommand; - 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 automation_list_automation_state_changed (Evoral::Parameter, AutoState); + void source_interpolation_changed (Evoral::Parameter const&, AutomationList::InterpolationStyle); + void source_automation_state_changed (Evoral::Parameter const&, AutoState); + void control_list_interpolation_changed (Evoral::Parameter const&, AutomationList::InterpolationStyle); + void automation_list_automation_state_changed (Evoral::Parameter const&, AutoState); void control_list_marked_dirty (); diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h index 78fcebb0b7..3a0b948a90 100644 --- a/libs/ardour/ardour/midi_source.h +++ b/libs/ardour/ardour/midi_source.h @@ -35,6 +35,7 @@ #include "temporal/range.h" #include "ardour/ardour.h" +#include "ardour/automation_list.h" #include "ardour/buffer.h" #include "ardour/midi_cursor.h" #include "ardour/source.h" @@ -185,20 +186,20 @@ class LIBARDOUR_API MidiSource : virtual public Source void set_model(const WriterLock& lock, boost::shared_ptr); void drop_model(const WriterLock& lock); - Evoral::ControlList::InterpolationStyle interpolation_of (Evoral::Parameter) const; - void set_interpolation_of (Evoral::Parameter, Evoral::ControlList::InterpolationStyle); + AutomationList::InterpolationStyle interpolation_of (Evoral::Parameter const&) const; + void set_interpolation_of (Evoral::Parameter const&, AutomationList::InterpolationStyle); void copy_interpolation_from (boost::shared_ptr); void copy_interpolation_from (MidiSource *); - AutoState automation_state_of (Evoral::Parameter) const; - void set_automation_state_of (Evoral::Parameter, AutoState); + AutoState automation_state_of (Evoral::Parameter const&) const; + void set_automation_state_of (Evoral::Parameter const&, AutoState); void copy_automation_state_from (boost::shared_ptr); void copy_automation_state_from (MidiSource *); /** Emitted when a different MidiModel is set */ PBD::Signal0 ModelChanged; /** Emitted when a parameter's interpolation style is changed */ - PBD::Signal2 InterpolationChanged; + PBD::Signal2 InterpolationChanged; /** Emitted when a parameter's automation state is changed */ PBD::Signal2 AutomationStateChanged; @@ -234,7 +235,7 @@ class LIBARDOUR_API MidiSource : virtual public Source /** Map of interpolation styles to use for Parameters; if they are not in this map, * the correct interpolation style can be obtained from EventTypeMap::interpolation_of () */ - typedef std::map InterpolationStyleMap; + typedef std::map InterpolationStyleMap; InterpolationStyleMap _interpolation_style; /** Map of automation states to use for Parameters; if they are not in this map, diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index c6d0364a94..4ba3784103 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -490,7 +490,7 @@ Automatable::automation_run (samplepos_t start, pframes_t nframes, bool only_act } void -Automatable::automation_list_automation_state_changed (Evoral::Parameter param, AutoState as) +Automatable::automation_list_automation_state_changed (Evoral::Parameter const& param, AutoState as) { { boost::shared_ptr c (automation_control(param)); diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 3ba6f62828..295a78fa87 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -1638,7 +1638,7 @@ MidiModel::insert_merge_policy () const * or the other is listened to by the GUI. */ void -MidiModel::source_interpolation_changed (Evoral::Parameter p, Evoral::ControlList::InterpolationStyle s) +MidiModel::source_interpolation_changed (Evoral::Parameter const& p, AutomationList::InterpolationStyle s) { { Glib::Threads::Mutex::Lock lm (_control_lock); @@ -1652,13 +1652,13 @@ MidiModel::source_interpolation_changed (Evoral::Parameter p, Evoral::ControlLis * MidiSource and ControlList interpolation state in sync, we pass this change onto our MidiSource. */ void -MidiModel::control_list_interpolation_changed (Evoral::Parameter p, Evoral::ControlList::InterpolationStyle s) +MidiModel::control_list_interpolation_changed (Evoral::Parameter const& p, AutomationList::InterpolationStyle s) { _midi_source.set_interpolation_of (p, s); } void -MidiModel::source_automation_state_changed (Evoral::Parameter p, AutoState s) +MidiModel::source_automation_state_changed (Evoral::Parameter const& p, AutoState s) { { Glib::Threads::Mutex::Lock lm (_control_lock); @@ -1670,7 +1670,7 @@ MidiModel::source_automation_state_changed (Evoral::Parameter p, AutoState s) } void -MidiModel::automation_list_automation_state_changed (Evoral::Parameter p, AutoState s) +MidiModel::automation_list_automation_state_changed (Evoral::Parameter const& p, AutoState s) { _midi_source.set_automation_state_of (p, s); } diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc index b7864c598a..916015999e 100644 --- a/libs/ardour/midi_source.cc +++ b/libs/ardour/midi_source.cc @@ -54,6 +54,8 @@ #include "ardour/session_directory.h" #include "ardour/source_factory.h" #include "ardour/tempo.h" +#include "ardour/evoral_types_convert.h" +#include "ardour/types_convert.h" #include "pbd/i18n.h" @@ -98,7 +100,7 @@ MidiSource::get_state () const for (InterpolationStyleMap::const_iterator i = _interpolation_style.begin(); i != _interpolation_style.end(); ++i) { XMLNode* child = node.add_child (X_("InterpolationStyle")); child->set_property (X_("parameter"), EventTypeMap::instance().to_symbol (i->first)); - child->set_property (X_("style"), enum_2_string (i->second)); + child->set_property (X_("style"), i->second); } for (AutomationStateMap::const_iterator i = _automation_state.begin(); i != _automation_state.end(); ++i) { @@ -139,12 +141,18 @@ MidiSource::set_state (const XMLNode& node, int /*version*/) continue; } - if (!(*i)->get_property (X_("style"), str)) { + /* backwards compat, older versions (<= 7000) saved an empty string for non default */ + if ((*i)->get_property (X_("style"), str)) { + if (str.empty ()) { + set_interpolation_of (p, EventTypeMap::instance().interpolation_of (p) == AutomationList::Discrete ? AutomationList::Linear : AutomationList::Discrete); + continue; + } + } + AutomationList::InterpolationStyle s; + if (!(*i)->get_property (X_("style"), s)) { error << _("Missing style property on InterpolationStyle") << endmsg; return -1; } - Evoral::ControlList::InterpolationStyle s = - static_cast(string_2_enum (str, s)); set_interpolation_of (p, s); } else if ((*i)->name() == X_("AutomationState")) { @@ -378,8 +386,8 @@ MidiSource::mark_midi_streaming_write_completed (const WriterLock& /* Make captured controls discrete to play back user input exactly. */ for (MidiModel::Controls::iterator i = _model->controls().begin(); i != _model->controls().end(); ++i) { if (i->second->list()) { - i->second->list()->set_interpolation(Evoral::ControlList::Discrete); - _interpolation_style.insert(std::make_pair(i->second->parameter(), Evoral::ControlList::Discrete)); + i->second->list()->set_interpolation (AutomationList::Discrete); + _interpolation_style.insert(std::make_pair(i->second->parameter(), AutomationList::Discrete)); } } } @@ -495,8 +503,8 @@ MidiSource::set_model (const WriterLock& lock, boost::shared_ptr m) ModelChanged (); /* EMIT SIGNAL */ } -Evoral::ControlList::InterpolationStyle -MidiSource::interpolation_of (Evoral::Parameter p) const +AutomationList::InterpolationStyle +MidiSource::interpolation_of (Evoral::Parameter const& p) const { InterpolationStyleMap::const_iterator i = _interpolation_style.find (p); if (i == _interpolation_style.end()) { @@ -507,7 +515,7 @@ MidiSource::interpolation_of (Evoral::Parameter p) const } AutoState -MidiSource::automation_state_of (Evoral::Parameter p) const +MidiSource::automation_state_of (Evoral::Parameter const& p) const { AutomationStateMap::const_iterator i = _automation_state.find (p); if (i == _automation_state.end()) { @@ -525,7 +533,7 @@ MidiSource::automation_state_of (Evoral::Parameter p) const * propagated to anyone who needs to know. */ void -MidiSource::set_interpolation_of (Evoral::Parameter p, Evoral::ControlList::InterpolationStyle s) +MidiSource::set_interpolation_of (Evoral::Parameter const& p, AutomationList::InterpolationStyle s) { if (interpolation_of (p) == s) { return; @@ -542,7 +550,7 @@ MidiSource::set_interpolation_of (Evoral::Parameter p, Evoral::ControlList::Inte } void -MidiSource::set_automation_state_of (Evoral::Parameter p, AutoState s) +MidiSource::set_automation_state_of (Evoral::Parameter const& p, AutoState s) { if (automation_state_of (p) == s) { return; diff --git a/libs/evoral/evoral/ControlSet.h b/libs/evoral/evoral/ControlSet.h index 7d20e46f8b..7990c43d1b 100644 --- a/libs/evoral/evoral/ControlSet.h +++ b/libs/evoral/evoral/ControlSet.h @@ -72,7 +72,7 @@ public: protected: virtual void control_list_marked_dirty () {} - virtual void control_list_interpolation_changed (Parameter, ControlList::InterpolationStyle) {} + virtual void control_list_interpolation_changed (Parameter const&, ControlList::InterpolationStyle) {} mutable Glib::Threads::Mutex _control_lock; Controls _controls;