From 48fdfbab53d728b37a368e0f4585558358e9ae9b Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 19 May 2022 06:00:39 +0200 Subject: [PATCH] Implement Session support for Mixer Scenes --- libs/ardour/ardour/session.h | 11 +++++++ libs/ardour/session.cc | 57 ++++++++++++++++++++++++++++++++++++ libs/ardour/session_state.cc | 43 +++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index c27b135c98..de4ec87871 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -153,6 +153,7 @@ class MidiPort; class MidiRegion; class MidiSource; class MidiTrack; +class MixerScene; class Playlist; class PluginInsert; class PluginInfo; @@ -1228,6 +1229,13 @@ public: boost::shared_ptr solo_cut_control() const; boost::shared_ptr recently_touched_controllable () const; + bool apply_nth_mixer_scene (size_t); + void store_nth_mixer_scene (size_t); + bool nth_mixer_scene_valid (size_t) const; + + boost::shared_ptr nth_mixer_scene (size_t, bool create_if_missing = false); + std::vector> mixer_scenes () const; + SessionConfiguration config; SessionConfiguration* cfg () { return &config; } @@ -1635,6 +1643,9 @@ private: SerializedRCUManager _io_plugins; + std::vector> _mixer_scenes; + mutable Glib::Threads::RWLock _mixer_scenes_lock; + Butler* _butler; TransportFSM* _transport_fsm; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index b0482c8550..9ac9b1f2f0 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -88,6 +88,7 @@ #include "ardour/midi_patch_manager.h" #include "ardour/midi_track.h" #include "ardour/midi_ui.h" +#include "ardour/mixer_scene.h" #include "ardour/operations.h" #include "ardour/playlist.h" #include "ardour/playlist_factory.h" @@ -7482,3 +7483,59 @@ Session::had_destructive_tracks() const return _had_destructive_tracks; } +bool +Session::nth_mixer_scene_valid (size_t nth) const +{ + Glib::Threads::RWLock::ReaderLock lm (_mixer_scenes_lock); + if (_mixer_scenes.size () <= nth) { + return false; + } + if (!_mixer_scenes[nth]) { + return false; + } + return !_mixer_scenes[nth]->empty (); +} + +bool +Session::apply_nth_mixer_scene (size_t nth) +{ + Glib::Threads::RWLock::ReaderLock lm (_mixer_scenes_lock); + if (_mixer_scenes.size () <= nth) { + return false; + } + if (!_mixer_scenes[nth]) { + return false; + } + return _mixer_scenes[nth]->apply (); +} + +void +Session::store_nth_mixer_scene (size_t nth) +{ + nth_mixer_scene (nth, true)->snapshot (); +} + +boost::shared_ptr +Session::nth_mixer_scene (size_t nth, bool create_if_missing) +{ + Glib::Threads::RWLock::ReaderLock lm (_mixer_scenes_lock); + if (create_if_missing && _mixer_scenes.size () <= nth) { + lm.release (); + Glib::Threads::RWLock::WriterLock lw (_mixer_scenes_lock); + _mixer_scenes.resize (nth + 1); + _mixer_scenes[nth] = boost::shared_ptr (new MixerScene (*this)); + set_dirty (); + return _mixer_scenes[nth]; + } + if (_mixer_scenes.size () <= nth) { + return boost::shared_ptr (); + } + return _mixer_scenes[nth]; +} + +std::vector> +Session::mixer_scenes () const +{ + Glib::Threads::RWLock::ReaderLock lm (_mixer_scenes_lock); + return _mixer_scenes; +} diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index c821365541..c016d7c1ec 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -112,6 +112,7 @@ #include "ardour/midi_scene_changer.h" #include "ardour/midi_source.h" #include "ardour/midi_track.h" +#include "ardour/mixer_scene.h" #include "ardour/playlist_factory.h" #include "ardour/playlist_source.h" #include "ardour/port.h" @@ -1483,6 +1484,34 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_ass node->add_child_nocopy (*script_node); } + { + Glib::Threads::RWLock::ReaderLock lm (_mixer_scenes_lock); + size_t idx = 0; + size_t last = 0; + for (auto const& i : _mixer_scenes) { + ++idx; + if (i && !i->empty ()) { + last = idx; + } + } + if (last > 0) { + idx = 0; + XMLNode* ms_node = new XMLNode (X_("MixerScenes")); + ms_node->set_property ("n_scenes", _mixer_scenes.size ()); + for (auto const& i : _mixer_scenes) { + if (i && !i->empty ()) { + XMLNode& ms_state (i->get_state ()); + ms_state.set_property ("index", idx); + ms_node->add_child_nocopy (ms_state); + } + if (++idx >= last) { + break; + } + } + node->add_child_nocopy (*ms_node); + } + } + { boost::shared_ptr iop (_io_plugins.reader ()); XMLNode* iop_node = new XMLNode (X_("IOPlugins")); @@ -1881,6 +1910,20 @@ Session::set_state (const XMLNode& node, int version) } } + if ((child = find_named_node (node, "MixerScenes"))) { + Glib::Threads::RWLock::WriterLock lm (_mixer_scenes_lock); + size_t n_scenes = 0; + child->get_property("n_scenes", n_scenes); + _mixer_scenes.resize (n_scenes); + for (auto const n : child->children () ) { + size_t index = 0; + if (n->get_property("index", index)) { + _mixer_scenes[index] = boost::shared_ptr (new MixerScene (*this)); + _mixer_scenes[index]->set_state (*n, version); + } + } + } + if ((child = find_named_node (node, "IOPlugins"))) { RCUWriter writer (_io_plugins); boost::shared_ptr iopl = writer.get_copy ();