From c45a6b80c769812a163a92ca4b2b26f77a5e6324 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 14 Apr 2022 13:18:42 +0200 Subject: [PATCH] Session support to add/remove save/load IOPlugs --- libs/ardour/ardour/session.h | 21 ++++++++++++ libs/ardour/ardour/types.h | 3 ++ libs/ardour/session.cc | 66 ++++++++++++++++++++++++++++++++++-- libs/ardour/session_state.cc | 28 +++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index a6b77d66c7..56975ac1c8 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -143,6 +143,7 @@ class ExportStatus; class Graph; struct GraphChain; class IO; +class IOPlug; class IOProcessor; class ImportStatus; class MidiClockTicker; @@ -939,6 +940,24 @@ public: PBD::Signal0 LuaScriptsChanged; + /* I/O Plugin */ + PBD::Signal0 IOPluginsChanged; + + void load_io_plugin (boost::shared_ptr); + bool unload_io_plugin (boost::shared_ptr); + + boost::shared_ptr nth_io_plug (uint32_t n) { + boost::shared_ptr iop (_io_plugins.reader ()); + if (n < iop->size ()) { + return (*iop)[n]; + } + return boost::shared_ptr (); + } + + boost::shared_ptr io_plugs () const { + return _io_plugins.reader (); + } + /* flattening stuff */ boost::shared_ptr write_one_track (Track&, samplepos_t start, samplepos_t end, @@ -1614,6 +1633,8 @@ private: void setup_lua (); void try_run_lua (pframes_t); + SerializedRCUManager _io_plugins; + Butler* _butler; TransportFSM* _transport_fsm; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index c61fb6f449..f9c79f4109 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -639,6 +639,9 @@ typedef std::list > VCAList; class Bundle; typedef std::vector > BundleList; +class IOPlug; +typedef std::vector > IOPlugList; + enum RegionEquivalence { Exact, Enclosed, diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index af252c70db..cb3fe254b1 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -81,6 +81,7 @@ #include "ardour/filename_extensions.h" #include "ardour/gain_control.h" #include "ardour/graph.h" +#include "ardour/io_plug.h" #include "ardour/luabindings.h" #include "ardour/midiport_manager.h" #include "ardour/scene_changer.h" @@ -92,6 +93,7 @@ #include "ardour/playlist_factory.h" #include "ardour/plugin.h" #include "ardour/plugin_insert.h" +#include "ardour/plugin_manager.h" #include "ardour/polarity_processor.h" #include "ardour/presentation_info.h" #include "ardour/process_thread.h" @@ -246,6 +248,7 @@ Session::Session (AudioEngine &eng, , _mempool ("Session", 3145728) , lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool)) , _n_lua_scripts (0) + , _io_plugins (new IOPlugList) , _butler (new Butler (*this)) , _transport_fsm (new TransportFSM (*this)) , _locations (new Locations (*this)) @@ -704,6 +707,16 @@ Session::destroy () } auditioner.reset (); + /* unregister IO Plugin */ + { + RCUWriter writer (_io_plugins); + boost::shared_ptr iop = writer.get_copy (); + for (auto const& i : *iop) { + i->DropReferences (); + } + iop->clear (); + } + /* drop references to routes held by the monitoring section * specifically _monitor_out aux/listen references */ remove_monitor_section(); @@ -712,6 +725,7 @@ Session::destroy () routes.flush (); _bundles.flush (); + _io_plugins.flush (); DiskReader::free_working_buffers(); @@ -1350,8 +1364,7 @@ Session::hookup_io () delete _bundle_xml_node; } - /* Get everything connected - */ + /* Get everything connected */ AudioEngine::instance()->reconnect_ports (); @@ -2122,6 +2135,11 @@ Session::set_block_size (pframes_t nframes) foreach_route (&Route::set_block_size, nframes); + boost::shared_ptr iop (_io_plugins.reader ()); + for (auto const& i : *iop) { + i->set_block_size (nframes); + } + DEBUG_TRACE (DEBUG::LatencyCompensation, "Session::set_block_size -> update worst i/o latency\n"); /* when this is called from the auto-connect thread, the process-lock is held */ Glib::Threads::Mutex::Lock lx (_update_latency_lock); @@ -3938,6 +3956,13 @@ Session::io_name_is_legal (const std::string& name) const } } + boost::shared_ptr iop (_io_plugins.reader ()); + for (auto const& i : *iop) { + if (i->io_name () == name) { + return false; + } + } + return true; } @@ -5033,6 +5058,38 @@ Session::audition_playlist () queue_event (ev); } +void +Session::load_io_plugin (boost::shared_ptr ioplugin) +{ + { + RCUWriter writer (_io_plugins); + boost::shared_ptr iop = writer.get_copy (); + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + ioplugin->ensure_io (); + iop->push_back (ioplugin); + ioplugin->LatencyChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, this, true, false)); + } + IOPluginsChanged (); /* EMIT SIGNAL */ + set_dirty(); +} + +bool +Session::unload_io_plugin (boost::shared_ptr ioplugin) +{ + { + RCUWriter writer (_io_plugins); + boost::shared_ptr iop = writer.get_copy (); + auto i = find (iop->begin (), iop->end (), ioplugin); + if (i == iop->end ()) { + return false; + } + (*i)->drop_references (); + iop->erase (i); + } + IOPluginsChanged (); /* EMIT SIGNAL */ + set_dirty(); + return true; +} void Session::register_lua_function ( @@ -6663,6 +6720,11 @@ Session::set_owned_port_public_latency (bool playback) } _click_io->set_public_port_latencies (_click_io->connected_latency (playback), playback); + boost::shared_ptr iop (_io_plugins.reader ()); + for (auto const& i : *iop) { + i->set_public_latency (playback); + } + if (_midi_ports) { _midi_ports->set_public_latency (playback); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index f7226987d2..214cdf4f18 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -104,6 +104,7 @@ #include "ardour/disk_reader.h" #include "ardour/filename_extensions.h" #include "ardour/graph.h" +#include "ardour/io_plug.h" #include "ardour/location.h" #include "ardour/lv2_plugin.h" #include "ardour/midi_model.h" @@ -1482,6 +1483,15 @@ Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_ass node->add_child_nocopy (*script_node); } + { + boost::shared_ptr iop (_io_plugins.reader ()); + XMLNode* iop_node = new XMLNode (X_("IOPlugins")); + for (auto const& i : *iop) { + iop_node->add_child_nocopy (i->get_state()); + } + node->add_child_nocopy (*iop_node); + } + return *node; } @@ -1871,6 +1881,24 @@ Session::set_state (const XMLNode& node, int version) } } + if ((child = find_named_node (node, "IOPlugins"))) { + RCUWriter writer (_io_plugins); + boost::shared_ptr iopl = writer.get_copy (); + for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) { + boost::shared_ptr iop = boost::make_shared(*this); + if (0 == iop->set_state (**n, version)) { + iopl->push_back (iop); + iop->LatencyChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, this, true, false)); + } else { + /* TODO Unknown I/O Plugin, retain state */ + } + } + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + for (auto const& i : *iopl) { + i->ensure_io (); + } + } + if ((child = find_named_node (node, X_("Selection")))) { _selection->set_state (*child, version); }