diff --git a/libs/ardour/ardour/export_channel.h b/libs/ardour/ardour/export_channel.h index 76b4b159e6..835502e8a2 100644 --- a/libs/ardour/ardour/export_channel.h +++ b/libs/ardour/ardour/export_channel.h @@ -63,6 +63,8 @@ public: virtual bool audio () const { return true; } virtual bool midi () const { return false; } + virtual std::string state_node_name () const = 0; + /// Adds state to node passed virtual void get_state (XMLNode* node) const = 0; @@ -89,6 +91,8 @@ public: bool empty () const { return ports.empty (); } + std::string state_node_name () const { return "PortExportChannel"; } + void get_state (XMLNode* node) const; void set_state (XMLNode* node, Session& session); @@ -123,11 +127,15 @@ public: bool audio () const { return false; } bool midi () const { return true; } + std::string state_node_name () const { return "PortExportMIDI"; } + void get_state (XMLNode* node) const; void set_state (XMLNode* node, Session& session); bool operator< (ExportChannel const& other) const; + boost::shared_ptr port () const { return _port.lock (); } + void set_port (boost::weak_ptr port) { _port = port; @@ -192,6 +200,8 @@ public: factory.read (channel, buf, samples_to_read); } + std::string state_node_name () const { return "RegionExportChannel"; } + void get_state (XMLNode* /*node*/) const {}; void set_state (XMLNode* /*node*/, Session& /*session*/){}; @@ -228,6 +238,7 @@ public: ~RouteExportChannel (); static void create_from_route (std::list& result, boost::shared_ptr route); + static void create_from_state (std::list& result, Session&, XMLNode*); public: // ExportChannel interface void prepare_export (samplecnt_t max_samples, sampleoffset_t common_latency); @@ -239,6 +250,10 @@ public: // ExportChannel interface bool audio () const; bool midi () const; + boost::shared_ptr route () const { return _remover->route (); } + + std::string state_node_name () const { return "RouteExportChannel"; } + void get_state (XMLNode* node) const; void set_state (XMLNode* node, Session& session); @@ -256,6 +271,8 @@ private: } ~ProcessorRemover (); + boost::shared_ptr route () const { return _route; } + private: boost::shared_ptr _route; boost::shared_ptr _processor; diff --git a/libs/ardour/ardour/export_channel_configuration.h b/libs/ardour/ardour/export_channel_configuration.h index f3ef95aeb8..d49b3eefac 100644 --- a/libs/ardour/ardour/export_channel_configuration.h +++ b/libs/ardour/ardour/export_channel_configuration.h @@ -2,6 +2,7 @@ * Copyright (C) 2008-2012 Sakari Bergen * Copyright (C) 2008-2013 Paul Davis * Copyright (C) 2009-2012 David Robillard + * Copyright (C) 2022 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/libs/ardour/export_channel.cc b/libs/ardour/export_channel.cc index cd12216f24..23cc1c0005 100644 --- a/libs/ardour/export_channel.cc +++ b/libs/ardour/export_channel.cc @@ -20,6 +20,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "pbd/types_convert.h" + #include "ardour/export_channel.h" #include "ardour/audio_buffer.h" #include "ardour/audio_port.h" @@ -376,6 +378,23 @@ RouteExportChannel::create_from_route (std::list& result, boos } } +void +RouteExportChannel::create_from_state (std::list& result, Session& s, XMLNode* node) +{ + XMLNode* xml_route = node->child ("Route"); + if (!xml_route) { + return; + } + PBD::ID rid; + if (!xml_route->get_property ("id", rid)) { + return; + } + boost::shared_ptr rt = s.route_by_id (rid); + if (rt) { + create_from_route (result, rt); + } +} + bool RouteExportChannel::audio () const { @@ -405,15 +424,16 @@ RouteExportChannel::read (Buffer const*& buf, samplecnt_t samples) const } void -RouteExportChannel::get_state (XMLNode*) const +RouteExportChannel::get_state (XMLNode* node) const { - // TODO + XMLNode* n = node->add_child ("Route"); + n->set_property ("id", route()->id ().to_s ()); } void RouteExportChannel::set_state (XMLNode*, Session&) { - // TODO + /* unused, see create_from_state() */ } bool diff --git a/libs/ardour/export_channel_configuration.cc b/libs/ardour/export_channel_configuration.cc index deb5ec09f0..2688309173 100644 --- a/libs/ardour/export_channel_configuration.cc +++ b/libs/ardour/export_channel_configuration.cc @@ -2,6 +2,7 @@ * Copyright (C) 2008-2009 Paul Davis * Copyright (C) 2008-2012 Sakari Bergen * Copyright (C) 2009-2012 David Robillard + * Copyright (C) 2022 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,14 +58,10 @@ ExportChannelConfiguration::get_state () const uint32_t i = 1; for (auto const& c : channels) { - channel = root->add_child ("Channel"); - if (!channel) { - continue; - } - + channel = root->add_child ("ExportChannel"); + channel->set_property ("type", c->state_node_name ()); channel->set_property ("number", i); c->get_state (channel); - ++i; } @@ -84,10 +81,42 @@ ExportChannelConfiguration::set_state (const XMLNode& root) set_region_processing_type ((RegionExportChannelFactory::Type) string_2_enum (str, RegionExportChannelFactory::Type)); } + /* load old state, if any */ XMLNodeList channels = root.children ("Channel"); - for (XMLNodeList::iterator it = channels.begin (); it != channels.end (); ++it) { + for (auto const& n : channels) { ExportChannelPtr channel (new PortExportChannel ()); - channel->set_state (*it, session); + channel->set_state (n, session); + register_channel (channel); + } + + XMLNodeList export_channels = root.children ("ExportChannel"); + for (auto const& n : export_channels) { + std::string type; + if (!n->get_property ("type", type)) { + assert (0); + continue; + } + ExportChannelPtr channel; + if (type == "PortExportChannel") { + channel = ExportChannelPtr (new PortExportChannel ()); + } else if (type == "PortExportMIDI") { + channel = ExportChannelPtr (new PortExportMIDI ()); + } else if (type == "RouteExportChannel") { + std::list list; + RouteExportChannel::create_from_state (list, session, n); + if (list.size () > 0) { + register_channels (list); + } + continue; + } else if (type == "RegionExportChannel") { + /* no state */ + continue; + } else { + assert (0); + continue; + } + + channel->set_state (n, session); register_channel (channel); }