summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/luabindings.cc1
-rw-r--r--libs/ardour/route.cc1
-rw-r--r--libs/ardour/session_state.cc74
-rw-r--r--scripts/_export_tracks.lua10
5 files changed, 86 insertions, 1 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 0b1f98e4b1..fbd5412d66 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -563,6 +563,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
XMLNode& get_state();
int set_state(const XMLNode& node, int version); // not idempotent
XMLNode& get_template();
+ bool export_track_state (boost::shared_ptr<RouteList> rl, const std::string& path);
/// The instant xml file is written to the session directory
void add_instant_xml (XMLNode&, bool write_to_config = true);
diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc
index a42aee18d3..d368eff6ca 100644
--- a/libs/ardour/luabindings.cc
+++ b/libs/ardour/luabindings.cc
@@ -2060,6 +2060,7 @@ LuaBindings::session (lua_State* L)
.addFunction ("save_state", &Session::save_state)
.addFunction ("set_dirty", &Session::set_dirty)
.addFunction ("unknown_processors", &Session::unknown_processors)
+ .addFunction ("export_track_state", &Session::export_track_state)
.addFunction<RouteList (Session::*)(uint32_t, PresentationInfo::order_t, const std::string&, const std::string&, PlaylistDisposition)> ("new_route_from_template", &Session::new_route_from_template)
// TODO session_add_audio_track session_add_midi_track session_add_mixed_track
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 6b16867e59..7cb47c2076 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -2235,7 +2235,6 @@ Route::state(bool full_state)
{
LocaleGuard lg;
if (!_session._template_state_dir.empty()) {
- assert (!full_state); // only for templates
foreach_processor (sigc::bind (sigc::mem_fun (*this, &Route::set_plugin_state_dir), _session._template_state_dir));
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 7121326458..bae1f46d01 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -1053,6 +1053,80 @@ Session::get_template()
return state(false);
}
+typedef std::set<boost::shared_ptr<Playlist> > PlaylistSet;
+typedef std::set<boost::shared_ptr<Source> > SourceSet;
+
+bool
+Session::export_track_state (boost::shared_ptr<RouteList> rl, const string& path)
+{
+ if (Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
+ return false;
+ }
+ if (g_mkdir_with_parents (path.c_str(), 0755) != 0) {
+ return false;
+ }
+
+ PBD::Unwinder<std::string> uw (_template_state_dir, path);
+
+ LocaleGuard lg;
+ XMLNode* node = new XMLNode("TrackState"); // XXX
+ XMLNode* child;
+
+ PlaylistSet playlists; // SessionPlaylists
+ SourceSet sources;
+
+ // these will work with new_route_from_template()
+ // TODO: LV2 plugin-state-dir needs to be relative (on load?)
+ child = node->add_child ("Routes");
+ for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+ if ((*i)->is_auditioner()) {
+ continue;
+ }
+ if ((*i)->is_master() || (*i)->is_monitor()) {
+ continue;
+ }
+ child->add_child_nocopy ((*i)->get_state());
+ boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (*i);
+ if (track) {
+ playlists.insert (track->playlist ());
+ }
+ }
+
+ // on load, Regions in the playlists need to resolve and map Source-IDs
+ // also playlist needs to be merged or created with new-name..
+ // ... and Diskstream in tracks adjusted to use the correct playlist
+ child = node->add_child ("Playlists"); // SessionPlaylists::add_state
+ for (PlaylistSet::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ child->add_child_nocopy ((*i)->get_state ());
+ boost::shared_ptr<RegionList> prl = (*i)->region_list ();
+ for (RegionList::const_iterator s = prl->begin(); s != prl->end(); ++s) {
+ const Region::SourceList& sl = (*s)->sources ();
+ for (Region::SourceList::const_iterator sli = sl.begin(); sli != sl.end(); ++sli) {
+ sources.insert (*sli);
+ }
+ }
+ }
+
+ child = node->add_child ("Sources");
+ for (SourceSet::const_iterator i = sources.begin(); i != sources.end(); ++i) {
+ child->add_child_nocopy ((*i)->get_state ());
+ boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (*i);
+ if (fs) {
+#ifdef PLATFORM_WINDOWS
+ fs->close ();
+#endif
+ string p = fs->path ();
+ PBD::copy_file (p, Glib::build_filename (path, Glib::path_get_basename (p)));
+ }
+ }
+
+ std::string sn = Glib::build_filename (path, "share.axml");
+
+ XMLTree tree;
+ tree.set_root (node);
+ return tree.write (sn.c_str());
+}
+
XMLNode&
Session::state (bool full_state)
{
diff --git a/scripts/_export_tracks.lua b/scripts/_export_tracks.lua
new file mode 100644
index 0000000000..7db8dabe84
--- /dev/null
+++ b/scripts/_export_tracks.lua
@@ -0,0 +1,10 @@
+ardour { ["type"] = "Snippet", name = "Export Track XML" }
+
+function factory () return function ()
+ local rlp = ARDOUR.RouteListPtr ()
+ local sel = Editor:get_selection ()
+ for r in sel.tracks:routelist ():iter () do
+ rlp:push_back (r)
+ end
+ print (Session:export_track_state (rlp, "/tmp/rexport"))
+end end