Fix a tiny memory leak, add_instant_xml() copies the node
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2013 Paul Davis
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20
21 #ifdef WAF_BUILD
22 #include "libardour-config.h"
23 #endif
24
25 #include <stdint.h>
26
27 #include <algorithm>
28 #include <string>
29 #include <cerrno>
30 #include <cstdio> /* snprintf(3) ... grrr */
31 #include <cmath>
32
33 #include <unistd.h>
34 #include <climits>
35 #include <signal.h>
36 #include <sys/time.h>
37
38 #ifdef HAVE_SYS_VFS_H
39 #include <sys/vfs.h>
40 #endif
41
42 #if defined(__APPLE__) || defined(__FreeBSD__)
43 #include <sys/param.h>
44 #include <sys/mount.h>
45 #endif
46
47 #ifdef HAVE_SYS_STATVFS_H
48 #include <sys/statvfs.h>
49 #endif
50
51 #include <glib.h>
52 #include "pbd/gstdio_compat.h"
53 #include "pbd/locale_guard.h"
54
55 #include <glibmm.h>
56 #include <glibmm/threads.h>
57 #include <glibmm/fileutils.h>
58
59 #include <boost/algorithm/string.hpp>
60
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
63
64 #include "evoral/SMF.hpp"
65
66 #include "pbd/basename.h"
67 #include "pbd/debug.h"
68 #include "pbd/enumwriter.h"
69 #include "pbd/error.h"
70 #include "pbd/file_utils.h"
71 #include "pbd/pathexpand.h"
72 #include "pbd/pthread_utils.h"
73 #include "pbd/stacktrace.h"
74 #include "pbd/types_convert.h"
75 #include "pbd/localtime_r.h"
76 #include "pbd/unwind.h"
77
78 #include "ardour/amp.h"
79 #include "ardour/async_midi_port.h"
80 #include "ardour/audio_track.h"
81 #include "ardour/audioengine.h"
82 #include "ardour/audiofilesource.h"
83 #include "ardour/audioregion.h"
84 #include "ardour/auditioner.h"
85 #include "ardour/automation_control.h"
86 #include "ardour/boost_debug.h"
87 #include "ardour/butler.h"
88 #include "ardour/control_protocol_manager.h"
89 #include "ardour/directory_names.h"
90 #include "ardour/disk_reader.h"
91 #include "ardour/filename_extensions.h"
92 #include "ardour/graph.h"
93 #include "ardour/location.h"
94 #ifdef LV2_SUPPORT
95 #include "ardour/lv2_plugin.h"
96 #endif
97 #include "ardour/midi_model.h"
98 #include "ardour/midi_patch_manager.h"
99 #include "ardour/midi_region.h"
100 #include "ardour/midi_scene_changer.h"
101 #include "ardour/midi_source.h"
102 #include "ardour/midi_track.h"
103 #include "ardour/pannable.h"
104 #include "ardour/playlist_factory.h"
105 #include "ardour/playlist_source.h"
106 #include "ardour/port.h"
107 #include "ardour/processor.h"
108 #include "ardour/progress.h"
109 #include "ardour/profile.h"
110 #include "ardour/proxy_controllable.h"
111 #include "ardour/recent_sessions.h"
112 #include "ardour/region_factory.h"
113 #include "ardour/revision.h"
114 #include "ardour/route_group.h"
115 #include "ardour/send.h"
116 #include "ardour/selection.h"
117 #include "ardour/session.h"
118 #include "ardour/session_directory.h"
119 #include "ardour/session_metadata.h"
120 #include "ardour/session_playlists.h"
121 #include "ardour/session_state_utils.h"
122 #include "ardour/silentfilesource.h"
123 #include "ardour/smf_source.h"
124 #include "ardour/sndfilesource.h"
125 #include "ardour/source_factory.h"
126 #include "ardour/speakers.h"
127 #include "ardour/template_utils.h"
128 #include "ardour/tempo.h"
129 #include "ardour/ticker.h"
130 #include "ardour/transport_master_manager.h"
131 #include "ardour/types_convert.h"
132 #include "ardour/user_bundle.h"
133 #include "ardour/vca.h"
134 #include "ardour/vca_manager.h"
135
136 #include "control_protocol/control_protocol.h"
137
138 #include "LuaBridge/LuaBridge.h"
139
140 #include "pbd/i18n.h"
141 #include <locale.h>
142
143 using namespace std;
144 using namespace ARDOUR;
145 using namespace PBD;
146
147 #define DEBUG_UNDO_HISTORY(msg) DEBUG_TRACE (PBD::DEBUG::UndoHistory, string_compose ("%1: %2\n", __LINE__, msg));
148
149 void
150 Session::pre_engine_init (string fullpath)
151 {
152         if (fullpath.empty()) {
153                 destroy ();
154                 throw failed_constructor();
155         }
156
157         /* discover canonical fullpath */
158
159         _path = canonical_path(fullpath);
160
161         /* is it new ? */
162         if (Profile->get_trx() ) {
163                 // Waves TracksLive has a usecase of session replacement with a new one.
164                 // We should check session state file (<session_name>.ardour) existance
165                 // to determine if the session is new or not
166
167                 string full_session_name = Glib::build_filename( fullpath, _name );
168                 full_session_name += statefile_suffix;
169
170                 _is_new = !Glib::file_test (full_session_name, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
171         } else {
172                 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
173         }
174
175         /* finish initialization that can't be done in a normal C++ constructor
176            definition.
177         */
178
179         timerclear (&last_mmc_step);
180         g_atomic_int_set (&processing_prohibited, 0);
181         g_atomic_int_set (&_record_status, Disabled);
182         g_atomic_int_set (&_playback_load, 100);
183         g_atomic_int_set (&_capture_load, 100);
184         set_next_event ();
185         _all_route_group->set_active (true, this);
186
187         if (config.get_use_video_sync()) {
188                 waiting_for_sync_offset = true;
189         } else {
190                 waiting_for_sync_offset = false;
191         }
192
193         last_rr_session_dir = session_dirs.begin();
194
195         set_history_depth (Config->get_history_depth());
196
197         /* default: assume simple stereo speaker configuration */
198
199         _speakers->setup_default_speakers (2);
200
201         _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
202                                 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
203                                 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
204         add_controllable (_solo_cut_control);
205
206         /* These are all static "per-class" signals */
207
208         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
209         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
210         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
211         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
212         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
213
214         /* stop IO objects from doing stuff until we're ready for them */
215
216         Delivery::disable_panners ();
217         IO::disable_connecting ();
218 }
219
220 int
221 Session::post_engine_init ()
222 {
223         BootMessage (_("Set block size and sample rate"));
224
225         set_block_size (_engine.samples_per_cycle());
226         set_sample_rate (_engine.sample_rate());
227
228         BootMessage (_("Using configuration"));
229
230         _midi_ports = new MidiPortManager;
231
232         MIDISceneChanger* msc;
233
234         _scene_changer = msc = new MIDISceneChanger (*this);
235         msc->set_input_port (boost::dynamic_pointer_cast<MidiPort>(scene_input_port()));
236         msc->set_output_port (boost::dynamic_pointer_cast<MidiPort>(scene_output_port()));
237
238         boost::function<samplecnt_t(void)> timer_func (boost::bind (&Session::audible_sample, this, (bool*)(0)));
239         boost::dynamic_pointer_cast<AsyncMIDIPort>(scene_input_port())->set_timer (timer_func);
240
241         setup_midi_machine_control ();
242
243         if (_butler->start_thread()) {
244                 error << _("Butler did not start") << endmsg;
245                 return -1;
246         }
247
248         if (start_midi_thread ()) {
249                 error << _("MIDI I/O thread did not start") << endmsg;
250                 return -1;
251         }
252
253         setup_click_sounds (0);
254         setup_midi_control ();
255
256         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
257         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
258
259         try {
260                 /* tempo map requires sample rate knowledge */
261
262                 delete _tempo_map;
263                 _tempo_map = new TempoMap (_current_sample_rate);
264                 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
265                 _tempo_map->MetricPositionChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
266         } catch (std::exception const & e) {
267                 error << _("Unexpected exception during session setup: ") << e.what() << endmsg;
268                 return -2;
269         } catch (...) {
270                 error << _("Unknown exception during session setup") << endmsg;
271                 return -3;
272         }
273
274         try {
275                 /* MidiClock requires a tempo map */
276
277                 delete midi_clock;
278                 midi_clock = new MidiClockTicker ();
279                 midi_clock->set_session (this);
280
281                 /* crossfades require sample rate knowledge */
282
283                 SndFileSource::setup_standard_crossfades (*this, sample_rate());
284                 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
285                 _engine.MidiSelectionPortsChanged.connect_same_thread (*this, boost::bind (&Session::rewire_midi_selection_ports, this));
286
287                 DiskReader::allocate_working_buffers();
288                 refresh_disk_space ();
289
290                 /* we're finally ready to call set_state() ... all objects have
291                  * been created, the engine is running.
292                  */
293
294                 if (state_tree) {
295                         try {
296                                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
297                                         error << _("Could not set session state from XML") << endmsg;
298                                         return -4;
299                                 }
300                         } catch (PBD::unknown_enumeration& e) {
301                                 error << _("Session state: ") << e.what() << endmsg;
302                                 return -4;
303                         }
304                 } else {
305                         // set_state() will call setup_raid_path(), but if it's a new session we need
306                         // to call setup_raid_path() here.
307                         setup_raid_path (_path);
308                 }
309
310                 /* ENGINE */
311
312                 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
313                 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
314
315                 Config->map_parameters (ff);
316                 config.map_parameters (ft);
317                 _butler->map_parameters ();
318
319                 /* Reset all panners */
320
321                 Delivery::reset_panners ();
322
323                 /* this will cause the CPM to instantiate any protocols that are in use
324                  * (or mandatory), which will pass it this Session, and then call
325                  * set_state() on each instantiated protocol to match stored state.
326                  */
327
328                 ControlProtocolManager::instance().set_session (this);
329
330                 /* This must be done after the ControlProtocolManager set_session above,
331                    as it will set states for ports which the ControlProtocolManager creates.
332                 */
333
334                 // XXX set state of MIDI::Port's
335                 // MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
336
337                 /* And this must be done after the MIDI::Manager::set_port_states as
338                  * it will try to make connections whose details are loaded by set_port_states.
339                  */
340
341                 hookup_io ();
342
343                 /* Let control protocols know that we are now all connected, so they
344                  * could start talking to surfaces if they want to.
345                  */
346
347                 ControlProtocolManager::instance().midi_connectivity_established ();
348
349                 if (_is_new && !no_auto_connect()) {
350                         Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
351                         auto_connect_master_bus ();
352                 }
353
354                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
355
356                 /* update latencies */
357
358                 initialize_latencies ();
359
360                 _locations->added.connect_same_thread (*this, boost::bind (&Session::location_added, this, _1));
361                 _locations->removed.connect_same_thread (*this, boost::bind (&Session::location_removed, this, _1));
362                 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
363
364         } catch (AudioEngine::PortRegistrationFailure& err) {
365                 error << err.what() << endmsg;
366                 return -5;
367         } catch (std::exception const & e) {
368                 error << _("Unexpected exception during session setup: ") << e.what() << endmsg;
369                 return -6;
370         } catch (...) {
371                 error << _("Unknown exception during session setup") << endmsg;
372                 return -7;
373         }
374
375         BootMessage (_("Reset Remote Controls"));
376
377         // send_full_time_code (0);
378         _engine.transport_locate (0);
379
380         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
381         send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
382
383         MIDI::Name::MidiPatchManager::instance().add_search_path (session_directory().midi_patch_path() );
384
385         ltc_tx_initialize();
386         /* initial program change will be delivered later; see ::config_changed() */
387
388         _state_of_the_state = Clean;
389
390         Port::set_connecting_blocked (false);
391
392         DirtyChanged (); /* EMIT SIGNAL */
393
394         if (_is_new) {
395                 save_state ("");
396         } else if (state_was_pending) {
397                 save_state ("");
398                 remove_pending_capture_state ();
399                 state_was_pending = false;
400         }
401
402         /* Now, finally, we can fill the playback buffers */
403
404         BootMessage (_("Filling playback buffers"));
405
406         boost::shared_ptr<RouteList> rl = routes.reader();
407         for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
408                 boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (*r);
409                 if (trk && !trk->is_private_route()) {
410                         trk->seek (_transport_sample, true);
411                 }
412         }
413
414         return 0;
415 }
416
417 void
418 Session::session_loaded ()
419 {
420         SessionLoaded();
421
422         _state_of_the_state = Clean;
423
424         DirtyChanged (); /* EMIT SIGNAL */
425
426         if (_is_new) {
427                 save_state ("");
428         } else if (state_was_pending) {
429                 save_state ("");
430                 remove_pending_capture_state ();
431                 state_was_pending = false;
432         }
433
434         /* Now, finally, we can fill the playback buffers */
435
436         BootMessage (_("Filling playback buffers"));
437         force_locate (_transport_sample, false);
438 }
439
440 string
441 Session::raid_path () const
442 {
443         Searchpath raid_search_path;
444
445         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
446                 raid_search_path += (*i).path;
447         }
448
449         return raid_search_path.to_string ();
450 }
451
452 void
453 Session::setup_raid_path (string path)
454 {
455         if (path.empty()) {
456                 return;
457         }
458
459         space_and_path sp;
460         string fspath;
461
462         session_dirs.clear ();
463
464         Searchpath search_path(path);
465         Searchpath sound_search_path;
466         Searchpath midi_search_path;
467
468         for (Searchpath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
469                 sp.path = *i;
470                 sp.blocks = 0; // not needed
471                 session_dirs.push_back (sp);
472
473                 SessionDirectory sdir(sp.path);
474
475                 sound_search_path += sdir.sound_path ();
476                 midi_search_path += sdir.midi_path ();
477         }
478
479         // reset the round-robin soundfile path thingie
480         last_rr_session_dir = session_dirs.begin();
481 }
482
483 bool
484 Session::path_is_within_session (const std::string& path)
485 {
486         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
487                 if (PBD::path_is_within (i->path, path)) {
488                         return true;
489                 }
490         }
491         return false;
492 }
493
494 int
495 Session::ensure_subdirs ()
496 {
497         string dir;
498
499         dir = session_directory().peak_path();
500
501         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
502                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
503                 return -1;
504         }
505
506         dir = session_directory().sound_path();
507
508         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
509                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
510                 return -1;
511         }
512
513         dir = session_directory().midi_path();
514
515         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
516                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
517                 return -1;
518         }
519
520         dir = session_directory().dead_path();
521
522         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
523                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
524                 return -1;
525         }
526
527         dir = session_directory().export_path();
528
529         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
530                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
531                 return -1;
532         }
533
534         dir = analysis_dir ();
535
536         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
537                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
538                 return -1;
539         }
540
541         dir = plugins_dir ();
542
543         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
544                 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
545                 return -1;
546         }
547
548         dir = externals_dir ();
549
550         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
551                 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
552                 return -1;
553         }
554
555         return 0;
556 }
557
558 /** @param session_template directory containing session template, or empty.
559  *  Caller must not hold process lock.
560  */
561 int
562 Session::create (const string& session_template, BusProfile* bus_profile)
563 {
564         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
565                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
566                 return -1;
567         }
568
569         if (ensure_subdirs ()) {
570                 return -1;
571         }
572
573         _writable = exists_and_writable (_path);
574
575         if (!session_template.empty()) {
576                 string in_path = (ARDOUR::Profile->get_trx () ? session_template : session_template_dir_to_file (session_template));
577
578                 FILE* in = g_fopen (in_path.c_str(), "rb");
579
580                 if (in) {
581                         /* no need to call legalize_for_path() since the string
582                          * in session_template is already a legal path name
583                          */
584                         string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
585
586                         FILE* out = g_fopen (out_path.c_str(), "wb");
587
588                         if (out) {
589                                 char buf[1024];
590                                 stringstream new_session;
591
592                                 while (!feof (in)) {
593                                         size_t charsRead = fread (buf, sizeof(char), 1024, in);
594
595                                         if (ferror (in)) {
596                                                 error << string_compose (_("Error reading session template file %1 (%2)"), in_path, strerror (errno)) << endmsg;
597                                                 fclose (in);
598                                                 fclose (out);
599                                                 return -1;
600                                         }
601                                         if (charsRead == 0) {
602                                                 break;
603                                         }
604                                         new_session.write (buf, charsRead);
605                                 }
606                                 fclose (in);
607
608                                 string file_contents = new_session.str();
609                                 size_t writeSize = file_contents.length();
610                                 if (fwrite (file_contents.c_str(), sizeof(char), writeSize, out) != writeSize) {
611                                         error << string_compose (_("Error writing session template file %1 (%2)"), out_path, strerror (errno)) << endmsg;
612                                         fclose (out);
613                                         return -1;
614                                 }
615                                 fclose (out);
616
617                                 _is_new = false;
618
619                                 if (!ARDOUR::Profile->get_trx()) {
620                                         /* Copy plugin state files from template to new session */
621                                         std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
622                                         copy_recurse (template_plugins, plugins_dir ());
623                                 }
624
625                                 return 0;
626
627                         } else {
628                                 error << string_compose (_("Could not open %1 for writing session template"), out_path)
629                                         << endmsg;
630                                 fclose(in);
631                                 return -1;
632                         }
633
634                 } else {
635                         error << string_compose (_("Could not open session template %1 for reading"), in_path)
636                                 << endmsg;
637                         return -1;
638                 }
639
640         }
641
642         if (Profile->get_trx()) {
643
644                 /* set initial start + end point : ARDOUR::Session::session_end_shift long.
645                  * Remember that this is a brand new session. Sessions
646                  * loaded from saved state will get this range from the saved state.
647                  */
648
649                 set_session_range_location (0, 0);
650
651                 /* Initial loop location, from absolute zero, length 10 seconds  */
652
653                 Location* loc = new Location (*this, 0, 10.0 * _engine.sample_rate(), _("Loop"),  Location::IsAutoLoop, 0);
654                 _locations->add (loc, true);
655                 set_auto_loop_location (loc);
656         }
657
658         _state_of_the_state = Clean;
659
660         /* set up Master Out and Monitor Out if necessary */
661
662         if (bus_profile) {
663                 RouteList rl;
664                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
665                 if (bus_profile->master_out_channels) {
666                         int rv = add_master_bus (count);
667
668                         if (rv) {
669                                 return rv;
670                         }
671
672                         if (Config->get_use_monitor_bus())
673                                 add_monitor_section ();
674                 }
675         }
676
677         return 0;
678 }
679
680 void
681 Session::maybe_write_autosave()
682 {
683         if (dirty() && record_status() != Recording) {
684                 save_state("", true);
685         }
686 }
687
688 void
689 Session::remove_pending_capture_state ()
690 {
691         std::string pending_state_file_path(_session_dir->root_path());
692
693         pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
694
695         if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
696
697         if (g_remove (pending_state_file_path.c_str()) != 0) {
698                 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
699                                 pending_state_file_path, g_strerror (errno)) << endmsg;
700         }
701 }
702
703 /** Rename a state file.
704  *  @param old_name Old snapshot name.
705  *  @param new_name New snapshot name.
706  */
707 void
708 Session::rename_state (string old_name, string new_name)
709 {
710         if (old_name == _current_snapshot_name || old_name == _name) {
711                 /* refuse to rename the current snapshot or the "main" one */
712                 return;
713         }
714
715         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
716         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
717
718         const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
719         const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
720
721         if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
722                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
723                                 old_name, new_name, g_strerror(errno)) << endmsg;
724         }
725 }
726
727 /** Remove a state file.
728  *  @param snapshot_name Snapshot name.
729  */
730 void
731 Session::remove_state (string snapshot_name)
732 {
733         if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
734                 // refuse to remove the current snapshot or the "main" one
735                 return;
736         }
737
738         std::string xml_path(_session_dir->root_path());
739
740         xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
741
742         if (!create_backup_file (xml_path)) {
743                 // don't remove it if a backup can't be made
744                 // create_backup_file will log the error.
745                 return;
746         }
747
748         // and delete it
749         if (g_remove (xml_path.c_str()) != 0) {
750                 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
751                                 xml_path, g_strerror (errno)) << endmsg;
752         }
753
754         StateSaved (snapshot_name); /* EMIT SIGNAL */
755 }
756
757 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
758 int
759 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot, bool template_only, bool for_archive, bool only_used_assets)
760 {
761         DEBUG_TRACE (DEBUG::Locale, string_compose ("Session::save_state locale '%1'\n", setlocale (LC_NUMERIC, NULL)));
762
763         XMLTree tree;
764         std::string xml_path(_session_dir->root_path());
765
766         /* prevent concurrent saves from different threads */
767
768         Glib::Threads::Mutex::Lock lm (save_state_lock);
769         Glib::Threads::Mutex::Lock lx (save_source_lock, Glib::Threads::NOT_LOCK);
770         if (!for_archive) {
771                 lx.acquire ();
772         }
773
774         if (!_writable || (_state_of_the_state & CannotSave)) {
775                 return 1;
776         }
777
778         if (g_atomic_int_get(&_suspend_save)) {
779                 _save_queued = true;
780                 return 1;
781         }
782         _save_queued = false;
783
784         snapshot_t fork_state = NormalSave;
785         if (!snapshot_name.empty() && snapshot_name != _current_snapshot_name && !template_only && !pending && !for_archive) {
786                 /* snapshot, close midi */
787                 fork_state = switch_to_snapshot ? SwitchToSnapshot : SnapshotKeep;
788         }
789
790 #ifndef NDEBUG
791         const int64_t save_start_time = g_get_monotonic_time();
792 #endif
793
794         /* tell sources we're saving first, in case they write out to a new file
795          * which should be saved with the state rather than the old one */
796         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
797                 try {
798                         i->second->session_saved();
799                 } catch (Evoral::SMF::FileError& e) {
800                         error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
801                 }
802         }
803
804         PBD::Unwinder<bool> uw (LV2Plugin::force_state_save, for_archive);
805
806         SessionSaveUnderway (); /* EMIT SIGNAL */
807
808         bool mark_as_clean = true;
809         if (!snapshot_name.empty() && !switch_to_snapshot) {
810                 mark_as_clean = false;
811         }
812
813         if (template_only) {
814                 mark_as_clean = false;
815                 tree.set_root (&get_template());
816         } else {
817                 tree.set_root (&state (false, fork_state, only_used_assets));
818         }
819
820         if (snapshot_name.empty()) {
821                 snapshot_name = _current_snapshot_name;
822         } else if (switch_to_snapshot) {
823                 set_snapshot_name (snapshot_name);
824         }
825
826         assert (!snapshot_name.empty());
827
828         if (!pending) {
829
830                 /* proper save: use statefile_suffix (.ardour in English) */
831
832                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
833
834                 /* make a backup copy of the old file */
835
836                 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
837                         // create_backup_file will log the error
838                         return -1;
839                 }
840
841         } else {
842
843                 /* pending save: use pending_suffix (.pending in English) */
844                 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
845         }
846
847         std::string tmp_path(_session_dir->root_path());
848         tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
849
850 #ifndef NDEBUG
851         cerr << "actually writing state to " << tmp_path << endl;
852 #endif
853
854         if (!tree.write (tmp_path)) {
855                 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
856                 if (g_remove (tmp_path.c_str()) != 0) {
857                         error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
858                                         tmp_path, g_strerror (errno)) << endmsg;
859                 }
860                 return -1;
861
862         } else {
863
864 #ifndef NDEBUG
865                 cerr << "renaming state to " << xml_path << endl;
866 #endif
867
868                 if (::g_rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
869                         error << string_compose (_("could not rename temporary session file %1 to %2 (%3)"),
870                                         tmp_path, xml_path, g_strerror(errno)) << endmsg;
871                         if (g_remove (tmp_path.c_str()) != 0) {
872                                 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
873                                                 tmp_path, g_strerror (errno)) << endmsg;
874                         }
875                         return -1;
876                 }
877         }
878
879         //Mixbus auto-backup mechanism
880         if(Profile->get_mixbus()) {
881                 if (pending) {  //"pending" save means it's a backup, or some other non-user-initiated save;  a good time to make a backup
882                         // make a serialized safety backup
883                         // (will make one periodically but only one per hour is left on disk)
884                         // these backup files go into a separated folder
885                         char timebuf[128];
886                         time_t n;
887                         struct tm local_time;
888                         time (&n);
889                         localtime_r (&n, &local_time);
890                         strftime (timebuf, sizeof(timebuf), "%y-%m-%d.%H", &local_time);
891                         std::string save_path(session_directory().backup_path());
892                         save_path += G_DIR_SEPARATOR;
893                         save_path += legalize_for_path(_current_snapshot_name);
894                         save_path += "-";
895                         save_path += timebuf;
896                         save_path += statefile_suffix;
897                         if ( !tree.write (save_path) )
898                                         error << string_compose(_("Could not save backup file at path \"%1\" (%2)"),
899                                                         save_path, g_strerror (errno)) << endmsg;
900                 }
901
902                 StateSaved (snapshot_name); /* EMIT SIGNAL */
903         }
904
905         if (!pending && !for_archive) {
906
907                 save_history (snapshot_name);
908
909                 if (mark_as_clean) {
910                         bool was_dirty = dirty();
911
912                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
913
914                         if (was_dirty) {
915                                 DirtyChanged (); /* EMIT SIGNAL */
916                         }
917                 }
918
919                 StateSaved (snapshot_name); /* EMIT SIGNAL */
920         }
921
922 #ifndef NDEBUG
923         const int64_t elapsed_time_us = g_get_monotonic_time() - save_start_time;
924         cerr << "saved state in " << fixed << setprecision (1) << elapsed_time_us / 1000. << " ms\n";
925 #endif
926         return 0;
927 }
928
929 int
930 Session::restore_state (string snapshot_name)
931 {
932         try {
933                 if (load_state (snapshot_name) == 0) {
934                         set_state (*state_tree->root(), Stateful::loading_state_version);
935                 }
936         } catch (...) {
937                 // SessionException
938                 // unknown_enumeration
939                 return -1;
940         }
941
942         return 0;
943 }
944
945 int
946 Session::load_state (string snapshot_name)
947 {
948         delete state_tree;
949         state_tree = 0;
950
951         state_was_pending = false;
952
953         /* check for leftover pending state from a crashed capture attempt */
954
955         std::string xmlpath(_session_dir->root_path());
956         xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
957
958         if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
959
960                 /* there is pending state from a crashed capture attempt */
961
962                 boost::optional<int> r = AskAboutPendingState();
963                 if (r.get_value_or (1)) {
964                         state_was_pending = true;
965                 }
966         }
967
968         if (!state_was_pending) {
969                 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
970         }
971
972         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
973                 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
974                 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
975                         error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
976                         return 1;
977                 }
978         }
979
980         state_tree = new XMLTree;
981
982         set_dirty();
983
984         _writable = exists_and_writable (xmlpath) && exists_and_writable(Glib::path_get_dirname(xmlpath));
985
986         if (!state_tree->read (xmlpath)) {
987                 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
988                 delete state_tree;
989                 state_tree = 0;
990                 return -1;
991         }
992
993         XMLNode const & root (*state_tree->root());
994
995         if (root.name() != X_("Session")) {
996                 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
997                 delete state_tree;
998                 state_tree = 0;
999                 return -1;
1000         }
1001
1002         std::string version;
1003         root.get_property ("version", version);
1004         Stateful::loading_state_version = parse_stateful_loading_version (version);
1005
1006         if ((Stateful::loading_state_version / 1000L) > (CURRENT_SESSION_FILE_VERSION / 1000L)) {
1007                 cerr << "Session-version: " << Stateful::loading_state_version << " is not supported. Current: " << CURRENT_SESSION_FILE_VERSION << "\n";
1008                 throw SessionException (string_compose (_("Incomatible Session Version. That session was created with a newer version of %1"), PROGRAM_NAME));
1009         }
1010
1011         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
1012
1013                 std::string backup_path(_session_dir->root_path());
1014                 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
1015                 backup_path = Glib::build_filename (backup_path, backup_filename);
1016
1017                 // only create a backup for a given statefile version once
1018
1019                 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
1020
1021                         VersionMismatch (xmlpath, backup_path);
1022
1023                         if (!copy_file (xmlpath, backup_path)) {;
1024                                 return -1;
1025                         }
1026                 }
1027         }
1028
1029         save_snapshot_name (snapshot_name);
1030
1031         return 0;
1032 }
1033
1034 int
1035 Session::load_options (const XMLNode& node)
1036 {
1037         config.set_variables (node);
1038         return 0;
1039 }
1040
1041 bool
1042 Session::save_default_options ()
1043 {
1044         return config.save_state();
1045 }
1046
1047 XMLNode&
1048 Session::get_state ()
1049 {
1050         /* this is not directly called, but required by PBD::Stateful */
1051         assert (0);
1052         return state (false, NormalSave);
1053 }
1054
1055 XMLNode&
1056 Session::get_template ()
1057 {
1058         /* if we don't disable rec-enable, diskstreams
1059            will believe they need to store their capture
1060            sources in their state node.
1061         */
1062
1063         disable_record (false);
1064
1065         return state (true, NormalSave);
1066 }
1067
1068 typedef std::set<boost::shared_ptr<Playlist> > PlaylistSet;
1069 typedef std::set<boost::shared_ptr<Source> > SourceSet;
1070
1071 bool
1072 Session::export_track_state (boost::shared_ptr<RouteList> rl, const string& path)
1073 {
1074         if (Glib::file_test (path, Glib::FILE_TEST_EXISTS))  {
1075                 return false;
1076         }
1077         if (g_mkdir_with_parents (path.c_str(), 0755) != 0) {
1078                 return false;
1079         }
1080
1081         PBD::Unwinder<std::string> uw (_template_state_dir, path);
1082
1083         LocaleGuard lg;
1084         XMLNode* node = new XMLNode("TrackState"); // XXX
1085         XMLNode* child;
1086
1087         PlaylistSet playlists; // SessionPlaylists
1088         SourceSet sources;
1089
1090         // these will work with  new_route_from_template()
1091         // TODO: LV2 plugin-state-dir needs to be relative (on load?)
1092         child = node->add_child ("Routes");
1093         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1094                 if ((*i)->is_auditioner()) {
1095                         continue;
1096                 }
1097                 if ((*i)->is_master() || (*i)->is_monitor()) {
1098                         continue;
1099                 }
1100                 child->add_child_nocopy ((*i)->get_state());
1101                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (*i);
1102                 if (track) {
1103                         playlists.insert (track->playlist ());
1104                 }
1105         }
1106
1107         // on load, Regions in the playlists need to resolve and map Source-IDs
1108         // also playlist needs to be merged or created with new-name..
1109         // ... and Diskstream in tracks adjusted to use the correct playlist
1110         child = node->add_child ("Playlists"); // SessionPlaylists::add_state
1111         for (PlaylistSet::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
1112                 child->add_child_nocopy ((*i)->get_state ());
1113                 boost::shared_ptr<RegionList> prl = (*i)->region_list ();
1114                 for (RegionList::const_iterator s = prl->begin(); s != prl->end(); ++s) {
1115                         const Region::SourceList& sl = (*s)->sources ();
1116                         for (Region::SourceList::const_iterator sli = sl.begin(); sli != sl.end(); ++sli) {
1117                                 sources.insert (*sli);
1118                         }
1119                 }
1120         }
1121
1122         child = node->add_child ("Sources");
1123         for (SourceSet::const_iterator i = sources.begin(); i != sources.end(); ++i) {
1124                 child->add_child_nocopy ((*i)->get_state ());
1125                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (*i);
1126                 if (fs) {
1127 #ifdef PLATFORM_WINDOWS
1128                         fs->close ();
1129 #endif
1130                         string p = fs->path ();
1131                         PBD::copy_file (p, Glib::build_filename (path, Glib::path_get_basename (p)));
1132                 }
1133         }
1134
1135         std::string sn = Glib::build_filename (path, "share.axml");
1136
1137         XMLTree tree;
1138         tree.set_root (node);
1139         return tree.write (sn.c_str());
1140 }
1141
1142 static void
1143 merge_all_sources (boost::shared_ptr<const Playlist> pl, std::set<boost::shared_ptr<Source> >* all_sources)
1144 {
1145         pl->deep_sources (*all_sources);
1146 }
1147
1148 namespace
1149 {
1150 struct route_id_compare {
1151         bool
1152         operator() (const boost::shared_ptr<Route>& r1, const boost::shared_ptr<Route>& r2)
1153         {
1154                 return r1->id () < r2->id ();
1155         }
1156 };
1157 } // anon namespace
1158
1159 XMLNode&
1160 Session::state (bool save_template, snapshot_t snapshot_type, bool only_used_assets)
1161 {
1162         LocaleGuard lg;
1163         XMLNode* node = new XMLNode("Session");
1164         XMLNode* child;
1165
1166         PBD::Unwinder<bool> uw (Automatable::skip_saving_automation, save_template);
1167
1168         node->set_property("version", CURRENT_SESSION_FILE_VERSION);
1169
1170         child = node->add_child ("ProgramVersion");
1171         child->set_property("created-with", created_with);
1172
1173         std::string modified_with = string_compose ("%1 %2", PROGRAM_NAME, revision);
1174         child->set_property("modified-with", modified_with);
1175
1176         /* store configuration settings */
1177
1178         if (!save_template) {
1179
1180                 node->set_property ("name", _name);
1181                 node->set_property ("sample-rate", _base_sample_rate);
1182
1183                 if (session_dirs.size() > 1) {
1184
1185                         string p;
1186
1187                         vector<space_and_path>::iterator i = session_dirs.begin();
1188                         vector<space_and_path>::iterator next;
1189
1190                         ++i; /* skip the first one */
1191                         next = i;
1192                         ++next;
1193
1194                         while (i != session_dirs.end()) {
1195
1196                                 p += (*i).path;
1197
1198                                 if (next != session_dirs.end()) {
1199                                         p += G_SEARCHPATH_SEPARATOR;
1200                                 } else {
1201                                         break;
1202                                 }
1203
1204                                 ++next;
1205                                 ++i;
1206                         }
1207
1208                         child = node->add_child ("Path");
1209                         child->add_content (p);
1210                 }
1211                 node->set_property ("end-is-free", _session_range_end_is_free);
1212         }
1213
1214         /* save the ID counter */
1215
1216         node->set_property ("id-counter", ID::counter());
1217
1218         node->set_property ("name-counter", name_id_counter ());
1219
1220         /* save the event ID counter */
1221
1222         node->set_property ("event-counter", Evoral::event_id_counter());
1223
1224         /* save the VCA counter */
1225
1226         node->set_property ("vca-counter", VCA::get_next_vca_number());
1227
1228         /* various options */
1229
1230         list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
1231         if (!midi_port_nodes.empty()) {
1232                 XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
1233                 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
1234                         midi_port_stuff->add_child_nocopy (**n);
1235                 }
1236                 node->add_child_nocopy (*midi_port_stuff);
1237         }
1238
1239         XMLNode& cfgxml (config.get_variables ());
1240         if (save_template) {
1241                 /* exclude search-paths from template */
1242                 cfgxml.remove_nodes_and_delete ("name", "audio-search-path");
1243                 cfgxml.remove_nodes_and_delete ("name", "midi-search-path");
1244                 cfgxml.remove_nodes_and_delete ("name", "raid-path");
1245         }
1246         node->add_child_nocopy (cfgxml);
1247
1248         node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1249
1250         child = node->add_child ("Sources");
1251
1252         if (!save_template) {
1253                 Glib::Threads::Mutex::Lock sl (source_lock);
1254
1255                 set<boost::shared_ptr<Source> > sources_used_by_this_snapshot;
1256
1257                 if (only_used_assets) {
1258                         playlists->sync_all_regions_with_regions ();
1259                         playlists->foreach (boost::bind (merge_all_sources, _1, &sources_used_by_this_snapshot), false);
1260                 }
1261
1262                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1263
1264                         /* Don't save information about non-file Sources, or
1265                          * about non-destructive file sources that are empty
1266                          * and unused by any regions.
1267                          */
1268                         boost::shared_ptr<FileSource> fs;
1269
1270                         if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) == 0) {
1271                                 continue;
1272                         }
1273
1274                         if (!fs->destructive()) {
1275                                 if (fs->empty() && !fs->used()) {
1276                                         continue;
1277                                 }
1278                         }
1279
1280                         if (only_used_assets) {
1281                                 /* skip only unused audio files */
1282                                 boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (fs);
1283                                 if (afs && !afs->used()) {
1284                                         continue;
1285                                 }
1286                                 if (afs && sources_used_by_this_snapshot.find (afs) == sources_used_by_this_snapshot.end ()) {
1287                                         continue;
1288                                 }
1289                         }
1290
1291                         if (snapshot_type != NormalSave && fs->within_session ()) {
1292                                 /* copy MIDI sources to new file
1293                                  *
1294                                  * We cannot replace the midi-source and MidiRegion::clobber_sources,
1295                                  * because the GUI (midi_region) has a direct pointer to the midi-model
1296                                  * of the source, as does UndoTransaction.
1297                                  *
1298                                  * On the upside, .mid files are not kept open. The file is only open
1299                                  * when reading the model initially and when flushing the model to disk:
1300                                  * source->session_saved () or export.
1301                                  *
1302                                  * We can change the _path of the existing source under the hood, keeping
1303                                  * all IDs, references and pointers intact.
1304                                  * */
1305                                 boost::shared_ptr<SMFSource> ms;
1306                                 if ((ms = boost::dynamic_pointer_cast<SMFSource> (siter->second)) != 0) {
1307                                         const std::string ancestor_name = ms->ancestor_name();
1308                                         const std::string base          = PBD::basename_nosuffix(ancestor_name);
1309                                         const string path               = new_midi_source_path (base, false);
1310
1311                                         /* use SMF-API to clone data (use the midi_model, not data on disk) */
1312                                         boost::shared_ptr<SMFSource> newsrc (new SMFSource (*this, path, SndFileSource::default_writable_flags));
1313                                         Source::Lock lm (ms->mutex());
1314
1315                                         // TODO special-case empty, removable() files: just create a new removable.
1316                                         // (load + write flushes the model and creates the file)
1317                                         if (!ms->model()) {
1318                                                 ms->load_model (lm);
1319                                         }
1320                                         if (ms->write_to (lm, newsrc, Temporal::Beats(), std::numeric_limits<Temporal::Beats>::max())) {
1321                                                 error << string_compose (_("Session-Save: Failed to copy MIDI Source '%1' for snapshot"), ancestor_name) << endmsg;
1322                                         } else {
1323                                                 if (snapshot_type == SnapshotKeep) {
1324                                                         /* keep working on current session.
1325                                                          *
1326                                                          * Save snapshot-state with the original filename.
1327                                                          * Switch to use new path for future saves of the main session.
1328                                                          */
1329                                                         child->add_child_nocopy (ms->get_state());
1330                                                 }
1331
1332                                                 /* swap file-paths.
1333                                                  * ~SMFSource  unlinks removable() files.
1334                                                  */
1335                                                 std::string npath (ms->path ());
1336                                                 ms->replace_file (newsrc->path ());
1337                                                 newsrc->replace_file (npath);
1338
1339                                                 if (snapshot_type == SwitchToSnapshot) {
1340                                                         /* save and switch to snapshot.
1341                                                          *
1342                                                          * Leave the old file in place (as is).
1343                                                          * Snapshot uses new source directly
1344                                                          */
1345                                                         child->add_child_nocopy (ms->get_state());
1346                                                 }
1347                                                 continue;
1348                                         }
1349                                 }
1350                         }
1351
1352                         child->add_child_nocopy (siter->second->get_state());
1353                 }
1354         }
1355
1356         child = node->add_child ("Regions");
1357
1358         if (!save_template) {
1359                 Glib::Threads::Mutex::Lock rl (region_lock);
1360
1361                 if (!only_used_assets) {
1362                         const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1363                         for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1364                                 boost::shared_ptr<Region> r = i->second;
1365                                 /* only store regions not attached to playlists */
1366                                 if (r->playlist() == 0) {
1367                                         if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1368                                                 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1369                                         } else {
1370                                                 child->add_child_nocopy (r->get_state ());
1371                                         }
1372                                 }
1373                         }
1374                 }
1375
1376                 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1377
1378                 if (!cassocs.empty()) {
1379                         XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1380
1381                         for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1382                                 if (i->first->playlist () == 0 && only_used_assets) {
1383                                         continue;
1384                                 }
1385                                 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1386                                 can->set_property (X_("copy"), i->first->id());
1387                                 can->set_property (X_("original"), i->second->id());
1388                                 ca->add_child_nocopy (*can);
1389                                 /* see above, child is still "Regions" here  */
1390                                 if (i->second->playlist() == 0 && only_used_assets) {
1391                                         if (boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>( i->second)) {
1392                                                 child->add_child_nocopy (ar->get_basic_state ());
1393                                         } else {
1394                                                 child->add_child_nocopy (ar->get_state ());
1395                                         }
1396                                 }
1397                         }
1398                 }
1399         }
1400
1401         if (!save_template) {
1402
1403                 node->add_child_nocopy (_selection->get_state());
1404
1405                 if (_locations) {
1406                         node->add_child_nocopy (_locations->get_state());
1407                 }
1408         } else {
1409                 Locations loc (*this);
1410                 const bool was_dirty = dirty();
1411                 // for a template, just create a new Locations, populate it
1412                 // with the default start and end, and get the state for that.
1413                 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange, 0);
1414                 range->set (max_samplepos, 0);
1415                 loc.add (range);
1416                 XMLNode& locations_state = loc.get_state();
1417
1418                 if (ARDOUR::Profile->get_trx() && _locations) {
1419                         // For tracks we need stored the Auto Loop Range and all MIDI markers.
1420                         for (Locations::LocationList::const_iterator i = _locations->list ().begin (); i != _locations->list ().end (); ++i) {
1421                                 if ((*i)->is_mark () || (*i)->is_auto_loop ()) {
1422                                         locations_state.add_child_nocopy ((*i)->get_state ());
1423                                 }
1424                         }
1425                 }
1426                 node->add_child_nocopy (locations_state);
1427
1428                 /* adding a location above will have marked the session
1429                  * dirty. This is an artifact, so fix it if the session wasn't
1430                  * already dirty
1431                  */
1432
1433                 if (!was_dirty) {
1434                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
1435                 }
1436         }
1437
1438         child = node->add_child ("Bundles");
1439         {
1440                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1441                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1442                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1443                         if (b) {
1444                                 child->add_child_nocopy (b->get_state());
1445                         }
1446                 }
1447         }
1448
1449         node->add_child_nocopy (_vca_manager->get_state());
1450
1451         child = node->add_child ("Routes");
1452         {
1453                 boost::shared_ptr<RouteList> r = routes.reader ();
1454
1455                 route_id_compare cmp;
1456                 RouteList xml_node_order (*r);
1457                 xml_node_order.sort (cmp);
1458
1459                 for (RouteList::const_iterator i = xml_node_order.begin(); i != xml_node_order.end(); ++i) {
1460                         if (!(*i)->is_auditioner()) {
1461                                 if (save_template) {
1462                                         child->add_child_nocopy ((*i)->get_template());
1463                                 } else {
1464                                         child->add_child_nocopy ((*i)->get_state());
1465                                 }
1466                         }
1467                 }
1468         }
1469
1470         playlists->add_state (node, save_template, !only_used_assets);
1471
1472         child = node->add_child ("RouteGroups");
1473         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1474                 child->add_child_nocopy ((*i)->get_state());
1475         }
1476
1477         if (_click_io) {
1478                 XMLNode* gain_child = node->add_child ("Click");
1479                 gain_child->add_child_nocopy (_click_io->get_state ());
1480                 gain_child->add_child_nocopy (_click_gain->get_state ());
1481         }
1482
1483         if (_ltc_output) {
1484                 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1485                 ltc_output_child->add_child_nocopy (_ltc_output->get_state ());
1486         }
1487
1488         node->add_child_nocopy (_speakers->get_state());
1489         node->add_child_nocopy (_tempo_map->get_state());
1490         node->add_child_nocopy (get_control_protocol_state());
1491
1492         if (_extra_xml) {
1493                 node->add_child_copy (*_extra_xml);
1494         }
1495
1496         {
1497                 Glib::Threads::Mutex::Lock lm (lua_lock);
1498                 std::string saved;
1499                 {
1500                         luabridge::LuaRef savedstate ((*_lua_save)());
1501                         saved = savedstate.cast<std::string>();
1502                 }
1503                 lua.collect_garbage ();
1504                 lm.release ();
1505
1506                 gchar* b64 = g_base64_encode ((const guchar*)saved.c_str (), saved.size ());
1507                 std::string b64s (b64);
1508                 g_free (b64);
1509
1510                 XMLNode* script_node = new XMLNode (X_("Script"));
1511                 script_node->set_property (X_("lua"), LUA_VERSION);
1512                 script_node->add_content (b64s);
1513                 node->add_child_nocopy (*script_node);
1514         }
1515
1516         return *node;
1517 }
1518
1519 XMLNode&
1520 Session::get_control_protocol_state ()
1521 {
1522         return ControlProtocolManager::instance().get_state ();
1523 }
1524
1525 int
1526 Session::set_state (const XMLNode& node, int version)
1527 {
1528         LocaleGuard lg;
1529         XMLNodeList nlist;
1530         XMLNode* child;
1531         int ret = -1;
1532
1533         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1534
1535         if (node.name() != X_("Session")) {
1536                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1537                 goto out;
1538         }
1539
1540         node.get_property ("name", _name);
1541
1542         if (node.get_property (X_("sample-rate"), _base_sample_rate)) {
1543
1544                 _nominal_sample_rate = _base_sample_rate;
1545
1546                 assert (AudioEngine::instance()->running ());
1547                 if (_base_sample_rate != AudioEngine::instance()->sample_rate ()) {
1548                         boost::optional<int> r = AskAboutSampleRateMismatch (_base_sample_rate, _current_sample_rate);
1549                         if (r.get_value_or (0)) {
1550                                 goto out;
1551                         }
1552                 }
1553         }
1554
1555         created_with = "unknown";
1556         if ((child = find_named_node (node, "ProgramVersion")) != 0) {
1557                 child->get_property (X_("created-with"), created_with);
1558         }
1559
1560         setup_raid_path(_session_dir->root_path());
1561
1562         node.get_property (X_("end-is-free"), _session_range_end_is_free);
1563
1564         uint64_t counter;
1565         if (node.get_property (X_("id-counter"), counter)) {
1566                 ID::init_counter (counter);
1567         } else {
1568                 /* old sessions used a timebased counter, so fake
1569                  * the startup ID counter based on a standard
1570                  * timestamp.
1571                  */
1572                 time_t now;
1573                 time (&now);
1574                 ID::init_counter (now);
1575         }
1576
1577         if (node.get_property (X_("name-counter"), counter)) {
1578                 init_name_id_counter (counter);
1579         }
1580
1581         if (node.get_property (X_("event-counter"), counter)) {
1582                 Evoral::init_event_id_counter (counter);
1583         }
1584
1585         if (node.get_property (X_("vca-counter"), counter)) {
1586                 VCA::set_next_vca_number (counter);
1587         } else {
1588                 VCA::set_next_vca_number (1);
1589         }
1590
1591         if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1592                 _midi_ports->set_midi_port_states (child->children());
1593         }
1594
1595         IO::disable_connecting ();
1596
1597         Stateful::save_extra_xml (node);
1598
1599         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1600                 load_options (*child);
1601         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1602                 load_options (*child);
1603         } else {
1604                 error << _("Session: XML state has no options section") << endmsg;
1605         }
1606
1607         if (version >= 3000) {
1608                 if ((child = find_named_node (node, "Metadata")) == 0) {
1609                         warning << _("Session: XML state has no metadata section") << endmsg;
1610                 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1611                         goto out;
1612                 }
1613         }
1614
1615         if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1616                 _speakers->set_state (*child, version);
1617         }
1618
1619         if ((child = find_named_node (node, "Sources")) == 0) {
1620                 error << _("Session: XML state has no sources section") << endmsg;
1621                 goto out;
1622         } else if (load_sources (*child)) {
1623                 goto out;
1624         }
1625
1626         if ((child = find_named_node (node, "TempoMap")) == 0) {
1627                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1628                 goto out;
1629         } else if (_tempo_map->set_state (*child, version)) {
1630                 goto out;
1631         }
1632
1633         if ((child = find_named_node (node, "Locations")) == 0) {
1634                 error << _("Session: XML state has no locations section") << endmsg;
1635                 goto out;
1636         } else if (_locations->set_state (*child, version)) {
1637                 goto out;
1638         }
1639
1640         locations_changed ();
1641
1642         if (_session_range_location) {
1643                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1644         }
1645
1646         if ((child = find_named_node (node, "Regions")) == 0) {
1647                 error << _("Session: XML state has no Regions section") << endmsg;
1648                 goto out;
1649         } else if (load_regions (*child)) {
1650                 goto out;
1651         }
1652
1653         if ((child = find_named_node (node, "Playlists")) == 0) {
1654                 error << _("Session: XML state has no playlists section") << endmsg;
1655                 goto out;
1656         } else if (playlists->load (*this, *child)) {
1657                 goto out;
1658         }
1659
1660         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1661                 // this is OK
1662         } else if (playlists->load_unused (*this, *child)) {
1663                 goto out;
1664         }
1665
1666         if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1667                 if (load_compounds (*child)) {
1668                         goto out;
1669                 }
1670         }
1671
1672         if (version >= 3000) {
1673                 if ((child = find_named_node (node, "Bundles")) == 0) {
1674                         warning << _("Session: XML state has no bundles section") << endmsg;
1675                         //goto out;
1676                 } else {
1677                         /* We can't load Bundles yet as they need to be able
1678                          * to convert from port names to Port objects, which can't happen until
1679                          * later */
1680                         _bundle_xml_node = new XMLNode (*child);
1681                 }
1682         }
1683
1684         if ((child = find_named_node (node, VCAManager::xml_node_name)) != 0) {
1685                 _vca_manager->set_state (*child, version);
1686         }
1687
1688         if ((child = find_named_node (node, "Routes")) == 0) {
1689                 error << _("Session: XML state has no routes section") << endmsg;
1690                 goto out;
1691         } else if (load_routes (*child, version)) {
1692                 goto out;
1693         }
1694
1695         /* Now that we have Routes and masters loaded, connect them if appropriate */
1696
1697         Slavable::Assign (_vca_manager); /* EMIT SIGNAL */
1698
1699         if (version >= 3000) {
1700
1701                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1702                         error << _("Session: XML state has no route groups section") << endmsg;
1703                         goto out;
1704                 } else if (load_route_groups (*child, version)) {
1705                         goto out;
1706                 }
1707
1708         } else if (version < 3000) {
1709
1710                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1711                         error << _("Session: XML state has no edit groups section") << endmsg;
1712                         goto out;
1713                 } else if (load_route_groups (*child, version)) {
1714                         goto out;
1715                 }
1716
1717                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1718                         error << _("Session: XML state has no mix groups section") << endmsg;
1719                         goto out;
1720                 } else if (load_route_groups (*child, version)) {
1721                         goto out;
1722                 }
1723         }
1724
1725         if ((child = find_named_node (node, "Click")) == 0) {
1726                 warning << _("Session: XML state has no click section") << endmsg;
1727         } else if (_click_io) {
1728                 setup_click_state (&node);
1729         }
1730
1731         if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1732                 ControlProtocolManager::instance().set_state (*child, 1 /* here: session-specific state */);
1733         }
1734
1735         if ((child = find_named_node (node, "Script"))) {
1736                 for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) {
1737                         if (!(*n)->is_content ()) { continue; }
1738                         gsize size;
1739                         guchar* buf = g_base64_decode ((*n)->content ().c_str (), &size);
1740                         try {
1741                                 Glib::Threads::Mutex::Lock lm (lua_lock);
1742                                 (*_lua_load)(std::string ((const char*)buf, size));
1743                         } catch (luabridge::LuaException const& e) {
1744                                 cerr << "LuaException:" << e.what () << endl;
1745                         } catch (...) { }
1746                         g_free (buf);
1747                 }
1748         }
1749
1750         if ((child = find_named_node (node, X_("Selection")))) {
1751                 _selection->set_state (*child, version);
1752         }
1753
1754         update_route_record_state ();
1755
1756         /* here beginneth the second phase ... */
1757         set_snapshot_name (_current_snapshot_name);
1758
1759         StateReady (); /* EMIT SIGNAL */
1760
1761         delete state_tree;
1762         state_tree = 0;
1763         return 0;
1764
1765 out:
1766         delete state_tree;
1767         state_tree = 0;
1768         return ret;
1769 }
1770
1771 int
1772 Session::load_routes (const XMLNode& node, int version)
1773 {
1774         XMLNodeList nlist;
1775         XMLNodeConstIterator niter;
1776         RouteList new_routes;
1777
1778         nlist = node.children();
1779
1780         set_dirty();
1781
1782         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1783
1784                 boost::shared_ptr<Route> route;
1785
1786                 if (version < 3000) {
1787                         route = XMLRouteFactory_2X (**niter, version);
1788                 } else if (version < 5000) {
1789                         route = XMLRouteFactory_3X (**niter, version);
1790                 } else {
1791                         route = XMLRouteFactory (**niter, version);
1792                 }
1793
1794                 if (route == 0) {
1795                         error << _("Session: cannot create Route from XML description.") << endmsg;
1796                         return -1;
1797                 }
1798
1799                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1800
1801                 new_routes.push_back (route);
1802         }
1803
1804         BootMessage (_("Tracks/busses loaded;  Adding to Session"));
1805
1806         add_routes (new_routes, false, false, false, PresentationInfo::max_order);
1807
1808         BootMessage (_("Finished adding tracks/busses"));
1809
1810         return 0;
1811 }
1812
1813 boost::shared_ptr<Route>
1814 Session::XMLRouteFactory (const XMLNode& node, int version)
1815 {
1816         boost::shared_ptr<Route> ret;
1817
1818         if (node.name() != "Route") {
1819                 return ret;
1820         }
1821
1822         XMLProperty const * pl_prop = node.property (X_("audio-playlist"));
1823
1824         if (!pl_prop) {
1825                 pl_prop = node.property (X_("midi-playlist"));
1826         }
1827
1828         DataType type = DataType::AUDIO;
1829         node.get_property("default-type", type);
1830
1831         assert (type != DataType::NIL);
1832
1833         if (pl_prop) {
1834
1835                 /* has at least 1 playlist, therefore a track ... */
1836
1837                 boost::shared_ptr<Track> track;
1838
1839                 if (type == DataType::AUDIO) {
1840                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1841                 } else {
1842                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1843                 }
1844
1845                 if (track->init()) {
1846                         return ret;
1847                 }
1848
1849                 if (track->set_state (node, version)) {
1850                         return ret;
1851                 }
1852
1853                 BOOST_MARK_TRACK (track);
1854                 ret = track;
1855
1856         } else {
1857                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1858                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1859
1860
1861                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1862                         BOOST_MARK_ROUTE (r);
1863                         ret = r;
1864                 }
1865         }
1866
1867         return ret;
1868 }
1869
1870 boost::shared_ptr<Route>
1871 Session::XMLRouteFactory_3X (const XMLNode& node, int version)
1872 {
1873         boost::shared_ptr<Route> ret;
1874
1875         if (node.name() != "Route") {
1876                 return ret;
1877         }
1878
1879         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1880
1881         DataType type = DataType::AUDIO;
1882         node.get_property("default-type", type);
1883
1884         assert (type != DataType::NIL);
1885
1886         if (ds_child) {
1887
1888                 boost::shared_ptr<Track> track;
1889
1890                 if (type == DataType::AUDIO) {
1891                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1892                 } else {
1893                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1894                 }
1895
1896                 if (track->init()) {
1897                         return ret;
1898                 }
1899
1900                 if (track->set_state (node, version)) {
1901                         return ret;
1902                 }
1903
1904                 BOOST_MARK_TRACK (track);
1905                 ret = track;
1906
1907         } else {
1908                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1909                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1910
1911                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1912                         BOOST_MARK_ROUTE (r);
1913                         ret = r;
1914                 }
1915         }
1916
1917         return ret;
1918 }
1919
1920 boost::shared_ptr<Route>
1921 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1922 {
1923         boost::shared_ptr<Route> ret;
1924
1925         if (node.name() != "Route") {
1926                 return ret;
1927         }
1928
1929         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1930         if (!ds_prop) {
1931                 ds_prop = node.property (X_("diskstream"));
1932         }
1933
1934         DataType type = DataType::AUDIO;
1935         node.get_property("default-type", type);
1936
1937         assert (type != DataType::NIL);
1938
1939         if (ds_prop) {
1940
1941                 /* see comment in current ::set_state() regarding diskstream
1942                  * state and DiskReader/DiskWRiter.
1943                  */
1944
1945                 error << _("Could not find diskstream for route") << endmsg;
1946                 return boost::shared_ptr<Route> ();
1947
1948                 boost::shared_ptr<Track> track;
1949
1950                 if (type == DataType::AUDIO) {
1951                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1952                 } else {
1953                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1954                 }
1955
1956                 if (track->init()) {
1957                         return ret;
1958                 }
1959
1960                 if (track->set_state (node, version)) {
1961                         return ret;
1962                 }
1963
1964                 BOOST_MARK_TRACK (track);
1965                 ret = track;
1966
1967         } else {
1968                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1969                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1970
1971                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1972                         BOOST_MARK_ROUTE (r);
1973                         ret = r;
1974                 }
1975         }
1976
1977         return ret;
1978 }
1979
1980 int
1981 Session::load_regions (const XMLNode& node)
1982 {
1983         XMLNodeList nlist;
1984         XMLNodeConstIterator niter;
1985         boost::shared_ptr<Region> region;
1986
1987         nlist = node.children();
1988
1989         set_dirty();
1990
1991         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1992                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1993                         error << _("Session: cannot create Region from XML description.");
1994                         XMLProperty const * name = (**niter).property("name");
1995
1996                         if (name) {
1997                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1998                         }
1999
2000                         error << endmsg;
2001                 }
2002         }
2003
2004         return 0;
2005 }
2006
2007 int
2008 Session::load_compounds (const XMLNode& node)
2009 {
2010         XMLNodeList calist = node.children();
2011         XMLNodeConstIterator caiter;
2012         XMLProperty const * caprop;
2013
2014         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
2015                 XMLNode* ca = *caiter;
2016                 ID orig_id;
2017                 ID copy_id;
2018
2019                 if ((caprop = ca->property (X_("original"))) == 0) {
2020                         continue;
2021                 }
2022                 orig_id = caprop->value();
2023
2024                 if ((caprop = ca->property (X_("copy"))) == 0) {
2025                         continue;
2026                 }
2027                 copy_id = caprop->value();
2028
2029                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
2030                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
2031
2032                 if (!orig || !copy) {
2033                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
2034                                                    orig_id, copy_id)
2035                                 << endmsg;
2036                         continue;
2037                 }
2038
2039                 RegionFactory::add_compound_association (orig, copy);
2040         }
2041
2042         return 0;
2043 }
2044
2045 void
2046 Session::load_nested_sources (const XMLNode& node)
2047 {
2048         XMLNodeList nlist;
2049         XMLNodeConstIterator niter;
2050
2051         nlist = node.children();
2052
2053         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2054                 if ((*niter)->name() == "Source") {
2055
2056                         /* it may already exist, so don't recreate it unnecessarily
2057                          */
2058
2059                         XMLProperty const * prop = (*niter)->property (X_("id"));
2060                         if (!prop) {
2061                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
2062                                 continue;
2063                         }
2064
2065                         ID source_id (prop->value());
2066
2067                         if (!source_by_id (source_id)) {
2068
2069                                 try {
2070                                         SourceFactory::create (*this, **niter, true);
2071                                 }
2072                                 catch (failed_constructor& err) {
2073                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
2074                                 }
2075                         }
2076                 }
2077         }
2078 }
2079
2080 boost::shared_ptr<Region>
2081 Session::XMLRegionFactory (const XMLNode& node, bool full)
2082 {
2083         XMLProperty const * type = node.property("type");
2084
2085         try {
2086
2087                 const XMLNodeList& nlist = node.children();
2088
2089                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
2090                         XMLNode *child = (*niter);
2091                         if (child->name() == "NestedSource") {
2092                                 load_nested_sources (*child);
2093                         }
2094                 }
2095
2096                 if (!type || type->value() == "audio") {
2097                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
2098                 } else if (type->value() == "midi") {
2099                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
2100                 }
2101
2102         } catch (failed_constructor& err) {
2103                 return boost::shared_ptr<Region> ();
2104         }
2105
2106         return boost::shared_ptr<Region> ();
2107 }
2108
2109 boost::shared_ptr<AudioRegion>
2110 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
2111 {
2112         XMLProperty const * prop;
2113         boost::shared_ptr<Source> source;
2114         boost::shared_ptr<AudioSource> as;
2115         SourceList sources;
2116         SourceList master_sources;
2117         uint32_t nchans = 1;
2118         char buf[128];
2119
2120         if (node.name() != X_("Region")) {
2121                 return boost::shared_ptr<AudioRegion>();
2122         }
2123
2124         node.get_property (X_("channels"), nchans);
2125
2126         if ((prop = node.property ("name")) == 0) {
2127                 cerr << "no name for this region\n";
2128                 abort ();
2129         }
2130
2131         if ((prop = node.property (X_("source-0"))) == 0) {
2132                 if ((prop = node.property ("source")) == 0) {
2133                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
2134                         return boost::shared_ptr<AudioRegion>();
2135                 }
2136         }
2137
2138         PBD::ID s_id (prop->value());
2139
2140         if ((source = source_by_id (s_id)) == 0) {
2141                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
2142                 return boost::shared_ptr<AudioRegion>();
2143         }
2144
2145         as = boost::dynamic_pointer_cast<AudioSource>(source);
2146         if (!as) {
2147                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
2148                 return boost::shared_ptr<AudioRegion>();
2149         }
2150
2151         sources.push_back (as);
2152
2153         /* pickup other channels */
2154
2155         for (uint32_t n=1; n < nchans; ++n) {
2156                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
2157                 if ((prop = node.property (buf)) != 0) {
2158
2159                         PBD::ID id2 (prop->value());
2160
2161                         if ((source = source_by_id (id2)) == 0) {
2162                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
2163                                 return boost::shared_ptr<AudioRegion>();
2164                         }
2165
2166                         as = boost::dynamic_pointer_cast<AudioSource>(source);
2167                         if (!as) {
2168                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
2169                                 return boost::shared_ptr<AudioRegion>();
2170                         }
2171                         sources.push_back (as);
2172                 }
2173         }
2174
2175         for (uint32_t n = 0; n < nchans; ++n) {
2176                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
2177                 if ((prop = node.property (buf)) != 0) {
2178
2179                         PBD::ID id2 (prop->value());
2180
2181                         if ((source = source_by_id (id2)) == 0) {
2182                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
2183                                 return boost::shared_ptr<AudioRegion>();
2184                         }
2185
2186                         as = boost::dynamic_pointer_cast<AudioSource>(source);
2187                         if (!as) {
2188                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
2189                                 return boost::shared_ptr<AudioRegion>();
2190                         }
2191                         master_sources.push_back (as);
2192                 }
2193         }
2194
2195         try {
2196                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
2197
2198                 /* a final detail: this is the one and only place that we know how long missing files are */
2199
2200                 if (region->whole_file()) {
2201                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
2202                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
2203                                 if (sfp) {
2204                                         sfp->set_length (region->length());
2205                                 }
2206                         }
2207                 }
2208
2209                 if (!master_sources.empty()) {
2210                         if (master_sources.size() != nchans) {
2211                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
2212                         } else {
2213                                 region->set_master_sources (master_sources);
2214                         }
2215                 }
2216
2217                 return region;
2218
2219         }
2220
2221         catch (failed_constructor& err) {
2222                 return boost::shared_ptr<AudioRegion>();
2223         }
2224 }
2225
2226 boost::shared_ptr<MidiRegion>
2227 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
2228 {
2229         XMLProperty const * prop;
2230         boost::shared_ptr<Source> source;
2231         boost::shared_ptr<MidiSource> ms;
2232         SourceList sources;
2233
2234         if (node.name() != X_("Region")) {
2235                 return boost::shared_ptr<MidiRegion>();
2236         }
2237
2238         if ((prop = node.property ("name")) == 0) {
2239                 cerr << "no name for this region\n";
2240                 abort ();
2241         }
2242
2243         if ((prop = node.property (X_("source-0"))) == 0) {
2244                 if ((prop = node.property ("source")) == 0) {
2245                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
2246                         return boost::shared_ptr<MidiRegion>();
2247                 }
2248         }
2249
2250         PBD::ID s_id (prop->value());
2251
2252         if ((source = source_by_id (s_id)) == 0) {
2253                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
2254                 return boost::shared_ptr<MidiRegion>();
2255         }
2256
2257         ms = boost::dynamic_pointer_cast<MidiSource>(source);
2258         if (!ms) {
2259                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
2260                 return boost::shared_ptr<MidiRegion>();
2261         }
2262
2263         sources.push_back (ms);
2264
2265         try {
2266                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
2267                 /* a final detail: this is the one and only place that we know how long missing files are */
2268
2269                 if (region->whole_file()) {
2270                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
2271                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
2272                                 if (sfp) {
2273                                         sfp->set_length (region->length());
2274                                 }
2275                         }
2276                 }
2277
2278                 return region;
2279         }
2280
2281         catch (failed_constructor& err) {
2282                 return boost::shared_ptr<MidiRegion>();
2283         }
2284 }
2285
2286 XMLNode&
2287 Session::get_sources_as_xml ()
2288
2289 {
2290         XMLNode* node = new XMLNode (X_("Sources"));
2291         Glib::Threads::Mutex::Lock lm (source_lock);
2292
2293         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2294                 node->add_child_nocopy (i->second->get_state());
2295         }
2296
2297         return *node;
2298 }
2299
2300 void
2301 Session::reset_write_sources (bool mark_write_complete, bool force)
2302 {
2303         boost::shared_ptr<RouteList> rl = routes.reader();
2304         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2305                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2306                 if (tr) {
2307                         _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
2308                         tr->reset_write_sources(mark_write_complete, force);
2309                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
2310                 }
2311         }
2312 }
2313
2314 int
2315 Session::load_sources (const XMLNode& node)
2316 {
2317         XMLNodeList nlist;
2318         XMLNodeConstIterator niter;
2319         /* don't need this but it stops some
2320          * versions of gcc complaining about
2321          * discarded return values.
2322          */
2323         boost::shared_ptr<Source> source;
2324
2325         nlist = node.children();
2326
2327         set_dirty();
2328         std::map<std::string, std::string> relocation;
2329
2330         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2331 #ifdef PLATFORM_WINDOWS
2332                 int old_mode = 0;
2333 #endif
2334
2335                 XMLNode srcnode (**niter);
2336                 bool try_replace_abspath = true;
2337
2338 retry:
2339                 try {
2340 #ifdef PLATFORM_WINDOWS
2341                         // do not show "insert media" popups (files embedded from removable media).
2342                         old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
2343 #endif
2344                         if ((source = XMLSourceFactory (srcnode)) == 0) {
2345                                 error << _("Session: cannot create Source from XML description.") << endmsg;
2346                         }
2347 #ifdef PLATFORM_WINDOWS
2348                         SetErrorMode(old_mode);
2349 #endif
2350
2351                 } catch (MissingSource& err) {
2352 #ifdef PLATFORM_WINDOWS
2353                         SetErrorMode(old_mode);
2354 #endif
2355
2356                         /* try previous abs path replacements first */
2357                         if (try_replace_abspath && Glib::path_is_absolute (err.path)) {
2358                                 std::string dir = Glib::path_get_dirname (err.path);
2359                                 std::map<std::string, std::string>::const_iterator rl = relocation.find (dir);
2360                                 if (rl != relocation.end ()) {
2361                                         std::string newpath = Glib::build_filename (rl->second, Glib::path_get_basename (err.path));
2362                                         if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2363                                                 srcnode.set_property ("origin", newpath);
2364                                                 try_replace_abspath = false;
2365                                                 goto retry;
2366                                         }
2367                                 }
2368                         }
2369
2370                         int user_choice;
2371                         _missing_file_replacement = "";
2372
2373                         if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
2374                                 error << string_compose (_("An external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
2375                                                 PROGRAM_NAME) << endmsg;
2376                                 return -1;
2377                         }
2378
2379                         if (!no_questions_about_missing_files) {
2380                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
2381                         } else {
2382                                 user_choice = -2;
2383                         }
2384
2385                         switch (user_choice) {
2386                                 case 0:
2387                                         /* user added a new search location
2388                                          * or selected a new absolute path,
2389                                          * so try again */
2390                                         if (Glib::path_is_absolute (err.path)) {
2391                                                 if (!_missing_file_replacement.empty ()) {
2392                                                         /* replace origin, in XML */
2393                                                         std::string newpath = Glib::build_filename (
2394                                                                         _missing_file_replacement, Glib::path_get_basename (err.path));
2395                                                         srcnode.set_property ("origin", newpath);
2396                                                         relocation[Glib::path_get_dirname (err.path)] = _missing_file_replacement;
2397                                                         _missing_file_replacement = "";
2398                                                 }
2399                                         }
2400                                         goto retry;
2401
2402
2403                                 case 1:
2404                                         /* user asked to quit the entire session load */
2405                                         return -1;
2406
2407                                 case 2:
2408                                         no_questions_about_missing_files = true;
2409                                         goto retry;
2410
2411                                 case 3:
2412                                         no_questions_about_missing_files = true;
2413                                         /* fallthru */
2414
2415                                 case -1:
2416                                 default:
2417                                         switch (err.type) {
2418
2419                                                 case DataType::AUDIO:
2420                                                         source = SourceFactory::createSilent (*this, **niter, max_samplecnt, _current_sample_rate);
2421                                                         break;
2422
2423                                                 case DataType::MIDI:
2424                                                         /* The MIDI file is actually missing so
2425                                                          * just create a new one in the same
2426                                                          * location. Do not announce its
2427                                                          */
2428                                                         string fullpath;
2429
2430                                                         if (!Glib::path_is_absolute (err.path)) {
2431                                                                 fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.path);
2432                                                         } else {
2433                                                                 /* this should be an unrecoverable error: we would be creating a MIDI file outside
2434                                                                  * the session tree.
2435                                                                  */
2436                                                                 return -1;
2437                                                         }
2438                                                         /* Note that we do not announce the source just yet - we need to reset its ID before we do that */
2439                                                         source = SourceFactory::createWritable (DataType::MIDI, *this, fullpath, false, _current_sample_rate, false, false);
2440                                                         /* reset ID to match the missing one */
2441                                                         source->set_id (**niter);
2442                                                         /* Now we can announce it */
2443                                                         SourceFactory::SourceCreated (source);
2444                                                         break;
2445                                         }
2446                                         break;
2447                         }
2448                 }
2449         }
2450
2451         return 0;
2452 }
2453
2454 boost::shared_ptr<Source>
2455 Session::XMLSourceFactory (const XMLNode& node)
2456 {
2457         if (node.name() != "Source") {
2458                 return boost::shared_ptr<Source>();
2459         }
2460
2461         try {
2462                 /* note: do peak building in another thread when loading session state */
2463                 return SourceFactory::create (*this, node, true);
2464         }
2465
2466         catch (failed_constructor& err) {
2467                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) << endmsg;
2468                 return boost::shared_ptr<Source>();
2469         }
2470 }
2471
2472 int
2473 Session::save_template (const string& template_name, const string& description, bool replace_existing)
2474 {
2475         if ((_state_of_the_state & CannotSave) || template_name.empty ()) {
2476                 return -1;
2477         }
2478
2479         bool absolute_path = Glib::path_is_absolute (template_name);
2480
2481         /* directory to put the template in */
2482         std::string template_dir_path;
2483
2484         if (!absolute_path) {
2485                 std::string user_template_dir(user_template_directory());
2486
2487                 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2488                         error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2489                                         user_template_dir, g_strerror (errno)) << endmsg;
2490                         return -1;
2491                 }
2492
2493                 template_dir_path = Glib::build_filename (user_template_dir, template_name);
2494         } else {
2495                 template_dir_path = template_name;
2496         }
2497
2498         if (!ARDOUR::Profile->get_trx()) {
2499                 if (!replace_existing && Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2500                         warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2501                                                                           template_dir_path) << endmsg;
2502                         return -2;
2503                 }
2504
2505                 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2506                         error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2507                                                                         template_dir_path, g_strerror (errno)) << endmsg;
2508                         return -1;
2509                 }
2510         }
2511
2512         /* file to write */
2513         std::string template_file_path;
2514
2515         if (ARDOUR::Profile->get_trx()) {
2516                 template_file_path = template_name;
2517         } else {
2518                 if (absolute_path) {
2519                         template_file_path = Glib::build_filename (template_dir_path, Glib::path_get_basename (template_dir_path) + template_suffix);
2520                 } else {
2521                         template_file_path = Glib::build_filename (template_dir_path, template_name + template_suffix);
2522                 }
2523         }
2524
2525         SessionSaveUnderway (); /* EMIT SIGNAL */
2526
2527         XMLTree tree;
2528         XMLNode* root;
2529         {
2530                 PBD::Unwinder<std::string> uw (_template_state_dir, template_dir_path);
2531                 root = &get_template ();
2532         }
2533
2534         root->remove_nodes_and_delete (X_("description"));
2535
2536         if (!description.empty()) {
2537                 XMLNode* desc = new XMLNode (X_("description"));
2538                 XMLNode* desc_cont = new XMLNode (X_("content"), description);
2539                 desc->add_child_nocopy (*desc_cont);
2540
2541                 root->add_child_nocopy (*desc);
2542         }
2543
2544         tree.set_root (root);
2545
2546         if (!tree.write (template_file_path)) {
2547                 error << _("template not saved") << endmsg;
2548                 return -1;
2549         }
2550
2551         store_recent_templates (template_file_path);
2552
2553         return 0;
2554 }
2555
2556 void
2557 Session::refresh_disk_space ()
2558 {
2559 #if __APPLE__ || __FreeBSD__ || __NetBSD__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2560
2561         Glib::Threads::Mutex::Lock lm (space_lock);
2562
2563         /* get freespace on every FS that is part of the session path */
2564
2565         _total_free_4k_blocks = 0;
2566         _total_free_4k_blocks_uncertain = false;
2567
2568         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2569 #if defined(__NetBSD__)
2570                 struct statvfs statfsbuf;
2571
2572                 statvfs (i->path.c_str(), &statfsbuf);
2573 #else
2574                 struct statfs statfsbuf;
2575
2576                 statfs (i->path.c_str(), &statfsbuf);
2577 #endif
2578                 double const scale = statfsbuf.f_bsize / 4096.0;
2579
2580                 /* See if this filesystem is read-only */
2581                 struct statvfs statvfsbuf;
2582                 statvfs (i->path.c_str(), &statvfsbuf);
2583
2584                 /* f_bavail can be 0 if it is undefined for whatever
2585                    filesystem we are looking at; Samba shares mounted
2586                    via GVFS are an example of this.
2587                 */
2588                 if (statfsbuf.f_bavail == 0) {
2589                         /* block count unknown */
2590                         i->blocks = 0;
2591                         i->blocks_unknown = true;
2592                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2593                         /* read-only filesystem */
2594                         i->blocks = 0;
2595                         i->blocks_unknown = false;
2596                 } else {
2597                         /* read/write filesystem with known space */
2598                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2599                         i->blocks_unknown = false;
2600                 }
2601
2602                 _total_free_4k_blocks += i->blocks;
2603                 if (i->blocks_unknown) {
2604                         _total_free_4k_blocks_uncertain = true;
2605                 }
2606         }
2607 #elif defined PLATFORM_WINDOWS
2608         vector<string> scanned_volumes;
2609         vector<string>::iterator j;
2610         vector<space_and_path>::iterator i;
2611         DWORD nSectorsPerCluster, nBytesPerSector,
2612               nFreeClusters, nTotalClusters;
2613         char disk_drive[4];
2614         bool volume_found;
2615
2616         _total_free_4k_blocks = 0;
2617
2618         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2619                 strncpy (disk_drive, (*i).path.c_str(), 3);
2620                 disk_drive[3] = 0;
2621                 strupr(disk_drive);
2622
2623                 volume_found = false;
2624                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2625                 {
2626                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2627                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2628                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2629
2630                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2631                                 if (0 == j->compare(disk_drive)) {
2632                                         volume_found = true;
2633                                         break;
2634                                 }
2635                         }
2636
2637                         if (!volume_found) {
2638                                 scanned_volumes.push_back(disk_drive);
2639                                 _total_free_4k_blocks += i->blocks;
2640                         }
2641                 }
2642         }
2643
2644         if (0 == _total_free_4k_blocks) {
2645                 strncpy (disk_drive, path().c_str(), 3);
2646                 disk_drive[3] = 0;
2647
2648                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2649                 {
2650                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2651                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2652                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2653                 }
2654         }
2655 #endif
2656 }
2657
2658 string
2659 Session::get_best_session_directory_for_new_audio ()
2660 {
2661         vector<space_and_path>::iterator i;
2662         string result = _session_dir->root_path();
2663
2664         /* handle common case without system calls */
2665
2666         if (session_dirs.size() == 1) {
2667                 return result;
2668         }
2669
2670         /* OK, here's the algorithm we're following here:
2671
2672         We want to select which directory to use for
2673         the next file source to be created. Ideally,
2674         we'd like to use a round-robin process so as to
2675         get maximum performance benefits from splitting
2676         the files across multiple disks.
2677
2678         However, in situations without much diskspace, an
2679         RR approach may end up filling up a filesystem
2680         with new files while others still have space.
2681         Its therefore important to pay some attention to
2682         the freespace in the filesystem holding each
2683         directory as well. However, if we did that by
2684         itself, we'd keep creating new files in the file
2685         system with the most space until it was as full
2686         as all others, thus negating any performance
2687         benefits of this RAID-1 like approach.
2688
2689         So, we use a user-configurable space threshold. If
2690         there are at least 2 filesystems with more than this
2691         much space available, we use RR selection between them.
2692         If not, then we pick the filesystem with the most space.
2693
2694         This gets a good balance between the two
2695         approaches.
2696         */
2697
2698         refresh_disk_space ();
2699
2700         int free_enough = 0;
2701
2702         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2703                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2704                         free_enough++;
2705                 }
2706         }
2707
2708         if (free_enough >= 2) {
2709                 /* use RR selection process, ensuring that the one
2710                    picked works OK.
2711                 */
2712
2713                 i = last_rr_session_dir;
2714
2715                 do {
2716                         if (++i == session_dirs.end()) {
2717                                 i = session_dirs.begin();
2718                         }
2719
2720                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2721                                 SessionDirectory sdir(i->path);
2722                                 if (sdir.create ()) {
2723                                         result = (*i).path;
2724                                         last_rr_session_dir = i;
2725                                         return result;
2726                                 }
2727                         }
2728
2729                 } while (i != last_rr_session_dir);
2730
2731         } else {
2732
2733                 /* pick FS with the most freespace (and that
2734                    seems to actually work ...)
2735                 */
2736
2737                 vector<space_and_path> sorted;
2738                 space_and_path_ascending_cmp cmp;
2739
2740                 sorted = session_dirs;
2741                 sort (sorted.begin(), sorted.end(), cmp);
2742
2743                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2744                         SessionDirectory sdir(i->path);
2745                         if (sdir.create ()) {
2746                                 result = (*i).path;
2747                                 last_rr_session_dir = i;
2748                                 return result;
2749                         }
2750                 }
2751         }
2752
2753         return result;
2754 }
2755
2756 string
2757 Session::automation_dir () const
2758 {
2759         return Glib::build_filename (_path, automation_dir_name);
2760 }
2761
2762 string
2763 Session::analysis_dir () const
2764 {
2765         return Glib::build_filename (_path, analysis_dir_name);
2766 }
2767
2768 string
2769 Session::plugins_dir () const
2770 {
2771         return Glib::build_filename (_path, plugins_dir_name);
2772 }
2773
2774 string
2775 Session::externals_dir () const
2776 {
2777         return Glib::build_filename (_path, externals_dir_name);
2778 }
2779
2780 int
2781 Session::load_bundles (XMLNode const & node)
2782 {
2783         XMLNodeList nlist = node.children();
2784         XMLNodeConstIterator niter;
2785
2786         set_dirty();
2787
2788         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2789                 if ((*niter)->name() == "InputBundle") {
2790                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2791                 } else if ((*niter)->name() == "OutputBundle") {
2792                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2793                 } else {
2794                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2795                         return -1;
2796                 }
2797         }
2798
2799         return 0;
2800 }
2801
2802 int
2803 Session::load_route_groups (const XMLNode& node, int version)
2804 {
2805         XMLNodeList nlist = node.children();
2806         XMLNodeConstIterator niter;
2807
2808         set_dirty ();
2809
2810         if (version >= 3000) {
2811
2812                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2813                         if ((*niter)->name() == "RouteGroup") {
2814                                 RouteGroup* rg = new RouteGroup (*this, "");
2815                                 add_route_group (rg);
2816                                 rg->set_state (**niter, version);
2817                         }
2818                 }
2819
2820         } else if (version < 3000) {
2821
2822                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2823                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2824                                 RouteGroup* rg = new RouteGroup (*this, "");
2825                                 add_route_group (rg);
2826                                 rg->set_state (**niter, version);
2827                         }
2828                 }
2829         }
2830
2831         return 0;
2832 }
2833
2834 static bool
2835 state_file_filter (const string &str, void* /*arg*/)
2836 {
2837         return (str.length() > strlen(statefile_suffix) &&
2838                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2839 }
2840
2841 static string
2842 remove_end(string state)
2843 {
2844         string statename(state);
2845
2846         string::size_type start,end;
2847         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2848                 statename = statename.substr (start+1);
2849         }
2850
2851         if ((end = statename.rfind(statefile_suffix)) == string::npos) {
2852                 end = statename.length();
2853         }
2854
2855         return string(statename.substr (0, end));
2856 }
2857
2858 vector<string>
2859 Session::possible_states (string path)
2860 {
2861         vector<string> states;
2862         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2863
2864         transform(states.begin(), states.end(), states.begin(), remove_end);
2865
2866         sort (states.begin(), states.end());
2867
2868         return states;
2869 }
2870
2871 vector<string>
2872 Session::possible_states () const
2873 {
2874         return possible_states(_path);
2875 }
2876
2877 RouteGroup*
2878 Session::new_route_group (const std::string& name)
2879 {
2880         RouteGroup* rg = NULL;
2881
2882         for (std::list<RouteGroup*>::const_iterator i = _route_groups.begin (); i != _route_groups.end (); ++i) {
2883                 if ((*i)->name () == name) {
2884                         rg = *i;
2885                         break;
2886                 }
2887         }
2888
2889         if (!rg) {
2890                 rg = new RouteGroup (*this, name);
2891                 add_route_group (rg);
2892         }
2893         return (rg);
2894 }
2895
2896 void
2897 Session::add_route_group (RouteGroup* g)
2898 {
2899         _route_groups.push_back (g);
2900         route_group_added (g); /* EMIT SIGNAL */
2901
2902         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2903         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2904         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2905
2906         set_dirty ();
2907 }
2908
2909 void
2910 Session::remove_route_group (RouteGroup& rg)
2911 {
2912         list<RouteGroup*>::iterator i;
2913
2914         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2915                 _route_groups.erase (i);
2916                 delete &rg;
2917
2918                 route_group_removed (); /* EMIT SIGNAL */
2919         }
2920 }
2921
2922 /** Set a new order for our route groups, without adding or removing any.
2923  *  @param groups Route group list in the new order.
2924  */
2925 void
2926 Session::reorder_route_groups (list<RouteGroup*> groups)
2927 {
2928         _route_groups = groups;
2929
2930         route_groups_reordered (); /* EMIT SIGNAL */
2931         set_dirty ();
2932 }
2933
2934
2935 RouteGroup *
2936 Session::route_group_by_name (string name)
2937 {
2938         list<RouteGroup *>::iterator i;
2939
2940         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2941                 if ((*i)->name() == name) {
2942                         return* i;
2943                 }
2944         }
2945         return 0;
2946 }
2947
2948 RouteGroup&
2949 Session::all_route_group() const
2950 {
2951         return *_all_route_group;
2952 }
2953
2954 void
2955 Session::add_commands (vector<Command*> const & cmds)
2956 {
2957         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2958                 add_command (*i);
2959         }
2960 }
2961
2962 void
2963 Session::add_command (Command* const cmd)
2964 {
2965         assert (_current_trans);
2966         DEBUG_UNDO_HISTORY (
2967             string_compose ("Current Undo Transaction %1, adding command: %2",
2968                             _current_trans->name (),
2969                             cmd->name ()));
2970         _current_trans->add_command (cmd);
2971 }
2972
2973 PBD::StatefulDiffCommand*
2974 Session::add_stateful_diff_command (boost::shared_ptr<PBD::StatefulDestructible> sfd)
2975 {
2976         PBD::StatefulDiffCommand* cmd = new PBD::StatefulDiffCommand (sfd);
2977         add_command (cmd);
2978         return cmd;
2979 }
2980
2981 void
2982 Session::begin_reversible_command (const string& name)
2983 {
2984         begin_reversible_command (g_quark_from_string (name.c_str ()));
2985 }
2986
2987 /** Begin a reversible command using a GQuark to identify it.
2988  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2989  *  but there must be as many begin...()s as there are commit...()s.
2990  */
2991 void
2992 Session::begin_reversible_command (GQuark q)
2993 {
2994         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2995            to hold all the commands that are committed.  This keeps the order of
2996            commands correct in the history.
2997         */
2998
2999         if (_current_trans == 0) {
3000                 DEBUG_UNDO_HISTORY (string_compose (
3001                     "Begin Reversible Command, new transaction: %1", g_quark_to_string (q)));
3002
3003                 /* start a new transaction */
3004                 assert (_current_trans_quarks.empty ());
3005                 _current_trans = new UndoTransaction();
3006                 _current_trans->set_name (g_quark_to_string (q));
3007         } else {
3008                 DEBUG_UNDO_HISTORY (
3009                     string_compose ("Begin Reversible Command, current transaction: %1",
3010                                     _current_trans->name ()));
3011         }
3012
3013         _current_trans_quarks.push_front (q);
3014 }
3015
3016 void
3017 Session::abort_reversible_command ()
3018 {
3019         if (_current_trans != 0) {
3020                 DEBUG_UNDO_HISTORY (
3021                     string_compose ("Abort Reversible Command: %1", _current_trans->name ()));
3022                 _current_trans->clear();
3023                 delete _current_trans;
3024                 _current_trans = 0;
3025                 _current_trans_quarks.clear();
3026         }
3027 }
3028
3029 void
3030 Session::commit_reversible_command (Command *cmd)
3031 {
3032         assert (_current_trans);
3033         assert (!_current_trans_quarks.empty ());
3034
3035         struct timeval now;
3036
3037         if (cmd) {
3038                 DEBUG_UNDO_HISTORY (
3039                     string_compose ("Current Undo Transaction %1, adding command: %2",
3040                                     _current_trans->name (),
3041                                     cmd->name ()));
3042                 _current_trans->add_command (cmd);
3043         }
3044
3045         DEBUG_UNDO_HISTORY (
3046             string_compose ("Commit Reversible Command, current transaction: %1",
3047                             _current_trans->name ()));
3048
3049         _current_trans_quarks.pop_front ();
3050
3051         if (!_current_trans_quarks.empty ()) {
3052                 DEBUG_UNDO_HISTORY (
3053                     string_compose ("Commit Reversible Command, transaction is not "
3054                                     "top-level, current transaction: %1",
3055                                     _current_trans->name ()));
3056                 /* the transaction we're committing is not the top-level one */
3057                 return;
3058         }
3059
3060         if (_current_trans->empty()) {
3061                 /* no commands were added to the transaction, so just get rid of it */
3062                 DEBUG_UNDO_HISTORY (
3063                     string_compose ("Commit Reversible Command, No commands were "
3064                                     "added to current transaction: %1",
3065                                     _current_trans->name ()));
3066                 delete _current_trans;
3067                 _current_trans = 0;
3068                 return;
3069         }
3070
3071         gettimeofday (&now, 0);
3072         _current_trans->set_timestamp (now);
3073
3074         _history.add (_current_trans);
3075         _current_trans = 0;
3076 }
3077
3078 static bool
3079 accept_all_audio_files (const string& path, void* /*arg*/)
3080 {
3081         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
3082                 return false;
3083         }
3084
3085         if (!AudioFileSource::safe_audio_file_extension (path)) {
3086                 return false;
3087         }
3088
3089         return true;
3090 }
3091
3092 static bool
3093 accept_all_midi_files (const string& path, void* /*arg*/)
3094 {
3095         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
3096                 return false;
3097         }
3098
3099         return (   (path.length() > 4 && path.find (".mid") != (path.length() - 4))
3100                 || (path.length() > 4 && path.find (".smf") != (path.length() - 4))
3101                 || (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
3102 }
3103
3104 static bool
3105 accept_all_state_files (const string& path, void* /*arg*/)
3106 {
3107         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
3108                 return false;
3109         }
3110
3111         std::string const statefile_ext (statefile_suffix);
3112         if (path.length() >= statefile_ext.length()) {
3113                 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
3114         } else {
3115                 return false;
3116         }
3117 }
3118
3119 int
3120 Session::find_all_sources (string path, set<string>& result)
3121 {
3122         XMLTree tree;
3123         XMLNode* node;
3124
3125         if (!tree.read (path)) {
3126                 return -1;
3127         }
3128
3129         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
3130                 return -2;
3131         }
3132
3133         XMLNodeList nlist;
3134         XMLNodeConstIterator niter;
3135
3136         nlist = node->children();
3137
3138         set_dirty();
3139
3140         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
3141
3142                 XMLProperty const * prop;
3143
3144                 if ((prop = (*niter)->property (X_("type"))) == 0) {
3145                         continue;
3146                 }
3147
3148                 DataType type (prop->value());
3149
3150                 if ((prop = (*niter)->property (X_("name"))) == 0) {
3151                         continue;
3152                 }
3153
3154                 if (Glib::path_is_absolute (prop->value())) {
3155                         /* external file, ignore */
3156                         continue;
3157                 }
3158
3159                 string found_path;
3160                 bool is_new;
3161                 uint16_t chan;
3162
3163                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
3164                         result.insert (found_path);
3165                 }
3166         }
3167
3168         return 0;
3169 }
3170
3171 int
3172 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
3173 {
3174         vector<string> state_files;
3175         string ripped;
3176         string this_snapshot_path;
3177
3178         result.clear ();
3179
3180         ripped = _path;
3181
3182         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
3183                 ripped = ripped.substr (0, ripped.length() - 1);
3184         }
3185
3186         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
3187
3188         if (state_files.empty()) {
3189                 /* impossible! */
3190                 return 0;
3191         }
3192
3193         this_snapshot_path = Glib::build_filename (_path, legalize_for_path (_current_snapshot_name));
3194         this_snapshot_path += statefile_suffix;
3195
3196         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
3197
3198                 cerr << "Looking at snapshot " << (*i) << " ( with this = [" << this_snapshot_path << "])\n";
3199
3200                 if (exclude_this_snapshot && *i == this_snapshot_path) {
3201                         cerr << "\texcluded\n";
3202                         continue;
3203
3204                 }
3205
3206                 if (find_all_sources (*i, result) < 0) {
3207                         return -1;
3208                 }
3209         }
3210
3211         return 0;
3212 }
3213
3214 struct RegionCounter {
3215         typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
3216         AudioSourceList::iterator iter;
3217         boost::shared_ptr<Region> region;
3218         uint32_t count;
3219
3220         RegionCounter() : count (0) {}
3221 };
3222
3223 int
3224 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
3225 {
3226         boost::optional<int> r = AskAboutPlaylistDeletion (p);
3227         return r.get_value_or (1);
3228 }
3229
3230 void
3231 Session::cleanup_regions ()
3232 {
3233         bool removed = false;
3234         const RegionFactory::RegionMap& regions (RegionFactory::regions());
3235
3236         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
3237
3238                 uint32_t used = playlists->region_use_count (i->second);
3239
3240                 if (used == 0 && !i->second->automatic ()) {
3241                         boost::weak_ptr<Region> w = i->second;
3242                         ++i;
3243                         removed = true;
3244                         RegionFactory::map_remove (w);
3245                 } else {
3246                         ++i;
3247                 }
3248         }
3249
3250         if (removed) {
3251                 // re-check to remove parent references of compound regions
3252                 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
3253                         if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
3254                                 ++i;
3255                                 continue;
3256                         }
3257                         assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
3258                         if (0 == playlists->region_use_count (i->second)) {
3259                                 boost::weak_ptr<Region> w = i->second;
3260                                 ++i;
3261                                 RegionFactory::map_remove (w);
3262                         } else {
3263                                 ++i;
3264                         }
3265                 }
3266         }
3267
3268         /* dump the history list */
3269         _history.clear ();
3270
3271         save_state ("");
3272 }
3273
3274 bool
3275 Session::can_cleanup_peakfiles () const
3276 {
3277         if (deletion_in_progress()) {
3278                 return false;
3279         }
3280         if (!_writable || (_state_of_the_state & CannotSave)) {
3281                 warning << _("Cannot cleanup peak-files for read-only session.") << endmsg;
3282                 return false;
3283         }
3284         if (record_status() == Recording) {
3285                 error << _("Cannot cleanup peak-files while recording") << endmsg;
3286                 return false;
3287         }
3288         return true;
3289 }
3290
3291 int
3292 Session::cleanup_peakfiles ()
3293 {
3294         Glib::Threads::Mutex::Lock lm (peak_cleanup_lock, Glib::Threads::TRY_LOCK);
3295         if (!lm.locked()) {
3296                 return -1;
3297         }
3298
3299         assert (can_cleanup_peakfiles ());
3300         assert (!peaks_cleanup_in_progres());
3301
3302         _state_of_the_state = StateOfTheState (_state_of_the_state | PeakCleanup);
3303
3304         int timeout = 5000; // 5 seconds
3305         while (!SourceFactory::files_with_peaks.empty()) {
3306                 Glib::usleep (1000);
3307                 if (--timeout < 0) {
3308                         warning << _("Timeout waiting for peak-file creation to terminate before cleanup, please try again later.") << endmsg;
3309                         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
3310                         return -1;
3311                 }
3312         }
3313
3314         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3315                 boost::shared_ptr<AudioSource> as;
3316                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
3317                         as->close_peakfile();
3318                 }
3319         }
3320
3321         PBD::clear_directory (session_directory().peak_path());
3322
3323         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
3324
3325         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3326                 boost::shared_ptr<AudioSource> as;
3327                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
3328                         SourceFactory::setup_peakfile(as, true);
3329                 }
3330         }
3331         return 0;
3332 }
3333
3334 int
3335 Session::cleanup_sources (CleanupReport& rep)
3336 {
3337         // FIXME: needs adaptation to midi
3338
3339         vector<boost::shared_ptr<Source> > dead_sources;
3340         string audio_path;
3341         string midi_path;
3342         vector<string> candidates;
3343         vector<string> unused;
3344         set<string> sources_used_by_all_snapshots;
3345         string spath;
3346         int ret = -1;
3347         string tmppath1;
3348         string tmppath2;
3349         Searchpath asp;
3350         Searchpath msp;
3351         set<boost::shared_ptr<Source> > sources_used_by_this_snapshot;
3352
3353         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
3354
3355         /* this is mostly for windows which doesn't allow file
3356          * renaming if the file is in use. But we don't special
3357          * case it because we need to know if this causes
3358          * problems, and the easiest way to notice that is to
3359          * keep it in place for all platforms.
3360          */
3361
3362         request_stop (false);
3363         _butler->summon ();
3364         _butler->wait_until_finished ();
3365
3366         /* consider deleting all unused playlists */
3367
3368         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
3369                 ret = 0;
3370                 goto out;
3371         }
3372
3373         /* sync the "all regions" property of each playlist with its current state */
3374
3375         playlists->sync_all_regions_with_regions ();
3376
3377         /* find all un-used sources */
3378
3379         rep.paths.clear ();
3380         rep.space = 0;
3381
3382         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3383
3384                 SourceMap::iterator tmp;
3385
3386                 tmp = i;
3387                 ++tmp;
3388
3389                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
3390                  * capture files.
3391                  */
3392
3393                 if (!i->second->used() && (i->second->length(i->second->timeline_position()) > 0)) {
3394                         dead_sources.push_back (i->second);
3395                         i->second->drop_references ();
3396                 }
3397
3398                 i = tmp;
3399         }
3400
3401         /* build a list of all the possible audio directories for the session */
3402
3403         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3404                 SessionDirectory sdir ((*i).path);
3405                 asp += sdir.sound_path();
3406         }
3407         audio_path += asp.to_string();
3408
3409
3410         /* build a list of all the possible midi directories for the session */
3411
3412         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3413                 SessionDirectory sdir ((*i).path);
3414                 msp += sdir.midi_path();
3415         }
3416         midi_path += msp.to_string();
3417
3418         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
3419         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
3420
3421         /* add sources from all other snapshots as "used", but don't use this
3422                  snapshot because the state file on disk still references sources we
3423                  may have already dropped.
3424                  */
3425
3426         find_all_sources_across_snapshots (sources_used_by_all_snapshots, true);
3427
3428         /* Although the region factory has a list of all regions ever created
3429          * for this session, we're only interested in regions actually in
3430          * playlists right now. So merge all playlist regions lists together.
3431          *
3432          * This will include the playlists used within compound regions.
3433          */
3434
3435         playlists->foreach (boost::bind (merge_all_sources, _1, &sources_used_by_this_snapshot));
3436
3437         /*  add our current source list
3438         */
3439
3440         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3441                 boost::shared_ptr<FileSource> fs;
3442                 SourceMap::iterator tmp = i;
3443                 ++tmp;
3444
3445                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) == 0) {
3446                         /* not a file */
3447                         i = tmp;
3448                         continue;
3449                 }
3450
3451                 /* this is mostly for windows which doesn't allow file
3452                  * renaming if the file is in use. But we do not special
3453                  * case it because we need to know if this causes
3454                  * problems, and the easiest way to notice that is to
3455                  * keep it in place for all platforms.
3456                  */
3457
3458                 fs->close ();
3459
3460                 if (!fs->is_stub()) {
3461
3462                         /* Note that we're checking a list of all
3463                          * sources across all snapshots with the list
3464                          * of sources used by this snapshot.
3465                          */
3466
3467                         if (sources_used_by_this_snapshot.find (i->second) != sources_used_by_this_snapshot.end()) {
3468                                 /* this source is in use by this snapshot */
3469                                 sources_used_by_all_snapshots.insert (fs->path());
3470                                 cerr << "Source from source list found in used_by_this_snapshot (" << fs->path() << ")\n";
3471                         } else {
3472                                 cerr << "Source from source list NOT found in used_by_this_snapshot (" << fs->path() << ")\n";
3473                                 /* this source is NOT in use by this snapshot */
3474
3475                                 /* remove all related regions from RegionFactory master list */
3476
3477                                 RegionFactory::remove_regions_using_source (i->second);
3478
3479                                 /* remove from our current source list
3480                                  * also. We may not remove it from
3481                                  * disk, because it may be used by
3482                                  * other snapshots, but it isn't used inside this
3483                                  * snapshot anymore, so we don't need a
3484                                  * reference to it.
3485                                  */
3486
3487                                 sources.erase (i);
3488                         }
3489                 }
3490
3491                 i = tmp;
3492         }
3493
3494         /* now check each candidate source to see if it exists in the list of
3495          * sources_used_by_all_snapshots. If it doesn't, put it into "unused".
3496          */
3497
3498         cerr << "Candidates: " << candidates.size() << endl;
3499         cerr << "Used by others: " << sources_used_by_all_snapshots.size() << endl;
3500
3501         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
3502
3503                 bool used = false;
3504                 spath = *x;
3505
3506                 for (set<string>::iterator i = sources_used_by_all_snapshots.begin(); i != sources_used_by_all_snapshots.end(); ++i) {
3507
3508                         tmppath1 = canonical_path (spath);
3509                         tmppath2 = canonical_path ((*i));
3510
3511                         cerr << "\t => " << tmppath2 << endl;
3512
3513                         if (tmppath1 == tmppath2) {
3514                                 used = true;
3515                                 break;
3516                         }
3517                 }
3518
3519                 if (!used) {
3520                         unused.push_back (spath);
3521                 }
3522         }
3523
3524         cerr << "Actually unused: " << unused.size() << endl;
3525
3526         if (unused.empty()) {
3527                 /* Nothing to do */
3528                 ret = 0;
3529                 goto out;
3530         }
3531
3532         /* now try to move all unused files into the "dead" directory(ies) */
3533
3534         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3535                 GStatBuf statbuf;
3536
3537                 string newpath;
3538
3539                 /* don't move the file across filesystems, just
3540                  * stick it in the `dead_dir_name' directory
3541                  * on whichever filesystem it was already on.
3542                  */
3543
3544                 if ((*x).find ("/sounds/") != string::npos) {
3545
3546                         /* old school, go up 1 level */
3547
3548                         newpath = Glib::path_get_dirname (*x);      // "sounds"
3549                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3550
3551                 } else {
3552
3553                         /* new school, go up 4 levels */
3554
3555                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
3556                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3557                         newpath = Glib::path_get_dirname (newpath); // "interchange"
3558                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
3559                 }
3560
3561                 newpath = Glib::build_filename (newpath, dead_dir_name);
3562
3563                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
3564                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
3565                         return -1;
3566                 }
3567
3568                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
3569
3570                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3571
3572                         /* the new path already exists, try versioning */
3573
3574                         char buf[PATH_MAX+1];
3575                         int version = 1;
3576                         string newpath_v;
3577
3578                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3579                         newpath_v = buf;
3580
3581                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
3582                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3583                                 newpath_v = buf;
3584                         }
3585
3586                         if (version == 999) {
3587                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3588                                                 newpath)
3589                                         << endmsg;
3590                         } else {
3591                                 newpath = newpath_v;
3592                         }
3593
3594                 }
3595
3596                 if ((g_stat ((*x).c_str(), &statbuf) != 0) || (::g_rename ((*x).c_str(), newpath.c_str()) != 0)) {
3597                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"), (*x),
3598                                         newpath, g_strerror (errno)) << endmsg;
3599                         continue;
3600                 }
3601
3602                 /* see if there an easy to find peakfile for this file, and remove it.  */
3603
3604                 string base = Glib::path_get_basename (*x);
3605                 base += "%A"; /* this is what we add for the channel suffix of all native files,
3606                                                                          * or for the first channel of embedded files. it will miss
3607                                                                          * some peakfiles for other channels
3608                                                                          */
3609                 string peakpath = construct_peak_filepath (base);
3610
3611                 if (Glib::file_test (peakpath.c_str (), Glib::FILE_TEST_EXISTS)) {
3612                         if (::g_unlink (peakpath.c_str ()) != 0) {
3613                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), peakpath, _path,
3614                                                 g_strerror (errno)) << endmsg;
3615                                 /* try to back out */
3616                                 ::g_rename (newpath.c_str (), _path.c_str ());
3617                                 goto out;
3618                         }
3619                 }
3620
3621                 rep.paths.push_back (*x);
3622                 rep.space += statbuf.st_size;
3623         }
3624
3625         /* dump the history list */
3626
3627         _history.clear ();
3628
3629         /* save state so we don't end up a session file
3630          * referring to non-existent sources.
3631          */
3632
3633         save_state ("");
3634         ret = 0;
3635
3636 out:
3637         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3638
3639         return ret;
3640 }
3641
3642 int
3643 Session::cleanup_trash_sources (CleanupReport& rep)
3644 {
3645         // FIXME: needs adaptation for MIDI
3646
3647         vector<space_and_path>::iterator i;
3648         string dead_dir;
3649
3650         rep.paths.clear ();
3651         rep.space = 0;
3652
3653         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3654
3655                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3656
3657                 clear_directory (dead_dir, &rep.space, &rep.paths);
3658         }
3659
3660         return 0;
3661 }
3662
3663 void
3664 Session::set_dirty ()
3665 {
3666         /* return early if there's nothing to do */
3667         if (dirty ()) {
3668                 return;
3669         }
3670
3671         /* never mark session dirty during loading */
3672         if (_state_of_the_state & (Loading | Deletion)) {
3673                 return;
3674         }
3675
3676         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3677         DirtyChanged(); /* EMIT SIGNAL */
3678 }
3679
3680 void
3681 Session::set_clean ()
3682 {
3683         bool was_dirty = dirty();
3684
3685         _state_of_the_state = Clean;
3686
3687         if (was_dirty) {
3688                 DirtyChanged(); /* EMIT SIGNAL */
3689         }
3690 }
3691
3692 void
3693 Session::set_deletion_in_progress ()
3694 {
3695         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3696 }
3697
3698 void
3699 Session::clear_deletion_in_progress ()
3700 {
3701         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3702 }
3703
3704 void
3705 Session::add_controllable (boost::shared_ptr<Controllable> c)
3706 {
3707         /* this adds a controllable to the list managed by the Session.
3708            this is a subset of those managed by the Controllable class
3709            itself, and represents the only ones whose state will be saved
3710            as part of the session.
3711         */
3712
3713         Glib::Threads::Mutex::Lock lm (controllables_lock);
3714         controllables.insert (c);
3715 }
3716
3717 struct null_deleter { void operator()(void const *) const {} };
3718
3719 void
3720 Session::remove_controllable (Controllable* c)
3721 {
3722         if (_state_of_the_state & Deletion) {
3723                 return;
3724         }
3725
3726         Glib::Threads::Mutex::Lock lm (controllables_lock);
3727
3728         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3729
3730         if (x != controllables.end()) {
3731                 controllables.erase (x);
3732         }
3733 }
3734
3735 boost::shared_ptr<Controllable>
3736 Session::controllable_by_id (const PBD::ID& id)
3737 {
3738         Glib::Threads::Mutex::Lock lm (controllables_lock);
3739
3740         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3741                 if ((*i)->id() == id) {
3742                         return *i;
3743                 }
3744         }
3745
3746         return boost::shared_ptr<Controllable>();
3747 }
3748
3749 boost::shared_ptr<AutomationControl>
3750 Session::automation_control_by_id (const PBD::ID& id)
3751 {
3752         return boost::dynamic_pointer_cast<AutomationControl> (controllable_by_id (id));
3753 }
3754
3755 void
3756 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3757 {
3758         if (_writable) {
3759                 Stateful::add_instant_xml (node, _path);
3760         }
3761
3762         if (write_to_config) {
3763                 Config->add_instant_xml (node);
3764         }
3765 }
3766
3767 XMLNode*
3768 Session::instant_xml (const string& node_name)
3769 {
3770 #ifdef MIXBUS // "Safe Mode" (shift + click open) -> also ignore instant.xml
3771         if (get_disable_all_loaded_plugins ()) {
3772                 return NULL;
3773         }
3774 #endif
3775         return Stateful::instant_xml (node_name, _path);
3776 }
3777
3778 int
3779 Session::save_history (string snapshot_name)
3780 {
3781         XMLTree tree;
3782
3783         if (!_writable) {
3784                 return 0;
3785         }
3786
3787         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 ||
3788             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3789                 return 0;
3790         }
3791
3792         if (snapshot_name.empty()) {
3793                 snapshot_name = _current_snapshot_name;
3794         }
3795
3796         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3797         const string backup_filename = history_filename + backup_suffix;
3798         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3799         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3800
3801         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3802                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3803                         error << _("could not backup old history file, current history not saved") << endmsg;
3804                         return -1;
3805                 }
3806         }
3807
3808         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3809
3810         if (!tree.write (xml_path))
3811         {
3812                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3813
3814                 if (g_remove (xml_path.c_str()) != 0) {
3815                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3816                                         xml_path, g_strerror (errno)) << endmsg;
3817                 }
3818                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3819                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3820                                         backup_path, g_strerror (errno)) << endmsg;
3821                 }
3822
3823                 return -1;
3824         }
3825
3826         return 0;
3827 }
3828
3829 int
3830 Session::restore_history (string snapshot_name)
3831 {
3832         XMLTree tree;
3833
3834         if (snapshot_name.empty()) {
3835                 snapshot_name = _current_snapshot_name;
3836         }
3837
3838         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3839         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3840
3841         info << "Loading history from " << xml_path << endmsg;
3842
3843         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3844                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3845                                 _name, xml_path) << endmsg;
3846                 return 1;
3847         }
3848
3849         if (!tree.read (xml_path)) {
3850                 error << string_compose (_("Could not understand session history file \"%1\""),
3851                                 xml_path) << endmsg;
3852                 return -1;
3853         }
3854
3855         // replace history
3856         _history.clear();
3857
3858         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); ++it) {
3859
3860                 XMLNode *t = *it;
3861
3862                 std::string name;
3863                 int64_t tv_sec;
3864                 int64_t tv_usec;
3865
3866                 if (!t->get_property ("name", name) || !t->get_property ("tv-sec", tv_sec) ||
3867                     !t->get_property ("tv-usec", tv_usec)) {
3868                         continue;
3869                 }
3870
3871                 UndoTransaction* ut = new UndoTransaction ();
3872                 ut->set_name (name);
3873
3874                 struct timeval tv;
3875                 tv.tv_sec = tv_sec;
3876                 tv.tv_usec = tv_usec;
3877                 ut->set_timestamp(tv);
3878
3879                 for (XMLNodeConstIterator child_it  = t->children().begin();
3880                                 child_it != t->children().end(); child_it++)
3881                 {
3882                         XMLNode *n = *child_it;
3883                         Command *c;
3884
3885                         if (n->name() == "MementoCommand" ||
3886                                         n->name() == "MementoUndoCommand" ||
3887                                         n->name() == "MementoRedoCommand") {
3888
3889                                 if ((c = memento_command_factory(n))) {
3890                                         ut->add_command(c);
3891                                 }
3892
3893                         } else if (n->name() == "NoteDiffCommand") {
3894                                 PBD::ID id (n->property("midi-source")->value());
3895                                 boost::shared_ptr<MidiSource> midi_source =
3896                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3897                                 if (midi_source) {
3898                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3899                                 } else {
3900                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3901                                 }
3902
3903                         } else if (n->name() == "SysExDiffCommand") {
3904
3905                                 PBD::ID id (n->property("midi-source")->value());
3906                                 boost::shared_ptr<MidiSource> midi_source =
3907                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3908                                 if (midi_source) {
3909                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3910                                 } else {
3911                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3912                                 }
3913
3914                         } else if (n->name() == "PatchChangeDiffCommand") {
3915
3916                                 PBD::ID id (n->property("midi-source")->value());
3917                                 boost::shared_ptr<MidiSource> midi_source =
3918                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3919                                 if (midi_source) {
3920                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3921                                 } else {
3922                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3923                                 }
3924
3925                         } else if (n->name() == "StatefulDiffCommand") {
3926                                 if ((c = stateful_diff_command_factory (n))) {
3927                                         ut->add_command (c);
3928                                 }
3929                         } else {
3930                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3931                         }
3932                 }
3933
3934                 _history.add (ut);
3935         }
3936
3937         return 0;
3938 }
3939
3940 void
3941 Session::config_changed (std::string p, bool ours)
3942 {
3943         if (ours) {
3944                 set_dirty ();
3945         }
3946
3947         if (p == "auto-loop") {
3948
3949         } else if (p == "session-monitoring") {
3950
3951         } else if (p == "auto-input") {
3952
3953                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3954                         /* auto-input only makes a difference if we're rolling */
3955                         set_track_monitor_input_status (!config.get_auto_input());
3956                 }
3957
3958         } else if (p == "punch-in") {
3959
3960                 Location* location;
3961
3962                 if ((location = _locations->auto_punch_location()) != 0) {
3963
3964                         if (config.get_punch_in ()) {
3965                                 auto_punch_start_changed (location);
3966                         } else {
3967                                 clear_events (SessionEvent::PunchIn);
3968                         }
3969                 }
3970
3971         } else if (p == "punch-out") {
3972
3973                 Location* location;
3974
3975                 if ((location = _locations->auto_punch_location()) != 0) {
3976
3977                         if (config.get_punch_out()) {
3978                                 auto_punch_end_changed (location);
3979                         } else {
3980                                 clear_events (SessionEvent::PunchOut);
3981                         }
3982                 }
3983
3984         } else if (p == "edit-mode") {
3985
3986                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3987
3988                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3989                         (*i)->set_edit_mode (Config->get_edit_mode ());
3990                 }
3991
3992         } else if (p == "use-video-sync") {
3993
3994                 waiting_for_sync_offset = config.get_use_video_sync();
3995
3996         } else if (p == "mmc-control") {
3997
3998                 //poke_midi_thread ();
3999
4000         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
4001
4002                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
4003
4004         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
4005
4006                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
4007
4008         } else if (p == "midi-control") {
4009
4010                 //poke_midi_thread ();
4011
4012         } else if (p == "raid-path") {
4013
4014                 setup_raid_path (config.get_raid_path());
4015
4016         } else if (p == "timecode-format") {
4017
4018                 sync_time_vars ();
4019
4020         } else if (p == "video-pullup") {
4021
4022                 sync_time_vars ();
4023
4024         } else if (p == "seamless-loop") {
4025
4026                 if (play_loop && transport_rolling()) {
4027                         // to reset diskstreams etc
4028                         request_play_loop (true);
4029                 }
4030
4031         } else if (p == "rf-speed") {
4032
4033                 cumulative_rf_motion = 0;
4034                 reset_rf_scale (0);
4035
4036         } else if (p == "click-sound") {
4037
4038                 setup_click_sounds (1);
4039
4040         } else if (p == "click-emphasis-sound") {
4041
4042                 setup_click_sounds (-1);
4043
4044         } else if (p == "clicking") {
4045
4046                 if (Config->get_clicking()) {
4047                         if (_click_io && click_data) { // don't require emphasis data
4048                                 _clicking = true;
4049                         }
4050                 } else {
4051                         _clicking = false;
4052                 }
4053
4054         } else if (p == "click-record-only") {
4055
4056                         _click_rec_only = Config->get_click_record_only();
4057
4058         } else if (p == "click-gain") {
4059
4060                 if (_click_gain) {
4061                         _click_gain->gain_control()->set_value (Config->get_click_gain(), Controllable::NoGroup);
4062                 }
4063
4064         } else if (p == "send-mtc") {
4065
4066                 if (Config->get_send_mtc ()) {
4067                         /* mark us ready to send */
4068                         next_quarter_frame_to_send = 0;
4069                 }
4070
4071         } else if (p == "send-mmc") {
4072
4073                 _mmc->enable_send (Config->get_send_mmc ());
4074                 if (Config->get_send_mmc ()) {
4075                         /* re-initialize MMC */
4076                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
4077                         send_immediate_mmc (MIDI::MachineControlCommand (Timecode::Time ()));
4078                 }
4079
4080         } else if (p == "jack-time-master") {
4081
4082                 engine().reset_timebase ();
4083
4084         } else if (p == "native-file-header-format") {
4085
4086                 if (!first_file_header_format_reset) {
4087                         reset_native_file_format ();
4088                 }
4089
4090                 first_file_header_format_reset = false;
4091
4092         } else if (p == "native-file-data-format") {
4093
4094                 if (!first_file_data_format_reset) {
4095                         reset_native_file_format ();
4096                 }
4097
4098                 first_file_data_format_reset = false;
4099
4100         } else if (p == "external-sync") {
4101                 request_sync_source (TransportMasterManager::instance().current());
4102         }  else if (p == "denormal-model") {
4103                 setup_fpu ();
4104         } else if (p == "history-depth") {
4105                 set_history_depth (Config->get_history_depth());
4106         } else if (p == "remote-model") {
4107                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
4108                    TO SET REMOTE ID'S
4109                 */
4110         } else if (p == "initial-program-change") {
4111
4112                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
4113                         MIDI::byte buf[2];
4114
4115                         buf[0] = MIDI::program; // channel zero by default
4116                         buf[1] = (Config->get_initial_program_change() & 0x7f);
4117
4118                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
4119                 }
4120         } else if (p == "solo-mute-override") {
4121                 // catch_up_on_solo_mute_override ();
4122         } else if (p == "listen-position" || p == "pfl-position") {
4123                 listen_position_changed ();
4124         } else if (p == "solo-control-is-listen-control") {
4125                 solo_control_mode_changed ();
4126         } else if (p == "solo-mute-gain") {
4127                 _solo_cut_control->Changed (true, Controllable::NoGroup);
4128         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
4129                 last_timecode_valid = false;
4130         } else if (p == "playback-buffer-seconds") {
4131                 AudioSource::allocate_working_buffers (sample_rate());
4132         } else if (p == "ltc-sink-port") {
4133                 reconnect_ltc_output ();
4134         } else if (p == "timecode-generator-offset") {
4135                 ltc_tx_parse_offset();
4136         } else if (p == "auto-return-target-list") {
4137                 follow_playhead_priority ();
4138         }
4139
4140         set_dirty ();
4141 }
4142
4143 void
4144 Session::set_history_depth (uint32_t d)
4145 {
4146         _history.set_depth (d);
4147 }
4148
4149 /** Connect things to the MMC object */
4150 void
4151 Session::setup_midi_machine_control ()
4152 {
4153         _mmc = new MIDI::MachineControl;
4154
4155         boost::shared_ptr<AsyncMIDIPort> async_in = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_input_port());
4156         boost::shared_ptr<AsyncMIDIPort> async_out = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_output_port());
4157
4158         if (!async_out || !async_out) {
4159                 return;
4160         }
4161
4162         /* XXXX argh, passing raw pointers back into libmidi++ */
4163
4164         MIDI::Port* mmc_in = async_in.get();
4165         MIDI::Port* mmc_out = async_out.get();
4166
4167         _mmc->set_ports (mmc_in, mmc_out);
4168
4169         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
4170         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
4171         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
4172         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
4173         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
4174         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
4175         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
4176         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
4177         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
4178         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
4179         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
4180         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
4181         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
4182
4183         /* also handle MIDI SPP because its so common */
4184
4185         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
4186         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
4187         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
4188 }
4189
4190 boost::shared_ptr<Controllable>
4191 Session::solo_cut_control() const
4192 {
4193         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
4194          * controls in Ardour that currently get presented to the user in the GUI that require
4195          * access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
4196          *
4197          * its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
4198          * it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
4199          * parameter.
4200          */
4201         return _solo_cut_control;
4202 }
4203
4204 void
4205 Session::save_snapshot_name (const std::string & n)
4206 {
4207         /* assure Stateful::_instant_xml is loaded
4208          * add_instant_xml() only adds to existing data and defaults
4209          * to use an empty Tree otherwise
4210          */
4211         instant_xml ("LastUsedSnapshot");
4212
4213         XMLNode last_used_snapshot ("LastUsedSnapshot");
4214         last_used_snapshot.set_property ("name", n);
4215         add_instant_xml (last_used_snapshot, false);
4216 }
4217
4218 void
4219 Session::set_snapshot_name (const std::string & n)
4220 {
4221         _current_snapshot_name = n;
4222         save_snapshot_name (n);
4223 }
4224
4225 int
4226 Session::rename (const std::string& new_name)
4227 {
4228         string legal_name = legalize_for_path (new_name);
4229         string new_path;
4230         string oldstr;
4231         string newstr;
4232         bool first = true;
4233
4234         string const old_sources_root = _session_dir->sources_root();
4235
4236         if (!_writable || (_state_of_the_state & CannotSave)) {
4237                 error << _("Cannot rename read-only session.") << endmsg;
4238                 return 0; // don't show "messed up" warning
4239         }
4240         if (record_status() == Recording) {
4241                 error << _("Cannot rename session while recording") << endmsg;
4242                 return 0; // don't show "messed up" warning
4243         }
4244
4245         StateProtector stp (this);
4246
4247         /* Rename:
4248
4249          * session directory
4250          * interchange subdirectory
4251          * session file
4252          * session history
4253
4254          * Backup files are left unchanged and not renamed.
4255          */
4256
4257         /* Windows requires that we close all files before attempting the
4258          * rename. This works on other platforms, but isn't necessary there.
4259          * Leave it in place for all platforms though, since it may help
4260          * catch issues that could arise if the way Source files work ever
4261          * change (since most developers are not using Windows).
4262          */
4263
4264         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4265                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4266                 if (fs) {
4267                         fs->close ();
4268                 }
4269         }
4270
4271         /* pass one: not 100% safe check that the new directory names don't
4272          * already exist ...
4273          */
4274
4275         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4276
4277                 oldstr = (*i).path;
4278
4279                 /* this is a stupid hack because Glib::path_get_dirname() is
4280                  * lexical-only, and so passing it /a/b/c/ gives a different
4281                  * result than passing it /a/b/c ...
4282                  */
4283
4284                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4285                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4286                 }
4287
4288                 string base = Glib::path_get_dirname (oldstr);
4289
4290                 newstr = Glib::build_filename (base, legal_name);
4291
4292                 cerr << "Looking for " << newstr << endl;
4293
4294                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
4295                         cerr << " exists\n";
4296                         return -1;
4297                 }
4298         }
4299
4300         /* Session dirs */
4301
4302         first = true;
4303
4304         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4305
4306                 vector<string> v;
4307
4308                 oldstr = (*i).path;
4309
4310                 /* this is a stupid hack because Glib::path_get_dirname() is
4311                  * lexical-only, and so passing it /a/b/c/ gives a different
4312                  * result than passing it /a/b/c ...
4313                  */
4314
4315                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4316                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4317                 }
4318
4319                 string base = Glib::path_get_dirname (oldstr);
4320                 newstr = Glib::build_filename (base, legal_name);
4321
4322                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
4323
4324                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4325                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4326                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4327                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4328                         return 1;
4329                 }
4330
4331                 /* Reset path in "session dirs" */
4332
4333                 (*i).path = newstr;
4334                 (*i).blocks = 0;
4335
4336                 /* reset primary SessionDirectory object */
4337
4338                 if (first) {
4339                         (*_session_dir) = newstr;
4340                         new_path = newstr;
4341                         first = false;
4342                 }
4343
4344                 /* now rename directory below session_dir/interchange */
4345
4346                 string old_interchange_dir;
4347                 string new_interchange_dir;
4348
4349                 /* use newstr here because we renamed the path
4350                  * (folder/directory) that used to be oldstr to newstr above
4351                  */
4352
4353                 v.push_back (newstr);
4354                 v.push_back (interchange_dir_name);
4355                 v.push_back (Glib::path_get_basename (oldstr));
4356
4357                 old_interchange_dir = Glib::build_filename (v);
4358
4359                 v.clear ();
4360                 v.push_back (newstr);
4361                 v.push_back (interchange_dir_name);
4362                 v.push_back (legal_name);
4363
4364                 new_interchange_dir = Glib::build_filename (v);
4365
4366                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
4367
4368                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
4369                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
4370                                                 old_interchange_dir, new_interchange_dir,
4371                                                 g_strerror (errno))
4372                              << endl;
4373                         error << string_compose (_("renaming %s as %2 failed (%3)"),
4374                                                  old_interchange_dir, new_interchange_dir,
4375                                                  g_strerror (errno))
4376                               << endmsg;
4377                         return 1;
4378                 }
4379         }
4380
4381         /* state file */
4382
4383         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
4384         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
4385
4386         cerr << "Rename " << oldstr << " => " << newstr << endl;
4387
4388         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4389                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4390                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4391                 return 1;
4392         }
4393
4394         /* history file */
4395
4396         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
4397
4398         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
4399                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
4400
4401                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4402
4403                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4404                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4405                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4406                         return 1;
4407                 }
4408         }
4409
4410         /* remove old name from recent sessions */
4411         remove_recent_sessions (_path);
4412         _path = new_path;
4413
4414         /* update file source paths */
4415
4416         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
4417                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4418                 if (fs) {
4419                         string p = fs->path ();
4420                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
4421                         fs->set_path (p);
4422                         SourceFactory::setup_peakfile(i->second, true);
4423                 }
4424         }
4425
4426         set_snapshot_name (new_name);
4427         _name = new_name;
4428
4429         set_dirty ();
4430
4431         /* save state again to get everything just right */
4432
4433         save_state (_current_snapshot_name);
4434
4435         /* add to recent sessions */
4436
4437         store_recent_sessions (new_name, _path);
4438
4439         return 0;
4440 }
4441
4442 int
4443 Session::parse_stateful_loading_version (const std::string& version)
4444 {
4445         if (version.empty ()) {
4446                 /* no version implies very old version of Ardour */
4447                 return 1000;
4448         }
4449
4450         if (version.find ('.') != string::npos) {
4451                 /* old school version format */
4452                 if (version[0] == '2') {
4453                         return 2000;
4454                 } else {
4455                         return 3000;
4456                 }
4457         } else {
4458                 return string_to<int32_t>(version);
4459         }
4460 }
4461
4462 int
4463 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format, std::string& program_version)
4464 {
4465         bool found_sr = false;
4466         bool found_data_format = false;
4467         std::string version;
4468         program_version = "";
4469
4470         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
4471                 return -1;
4472         }
4473
4474         xmlParserCtxtPtr ctxt = xmlNewParserCtxt();
4475         if (ctxt == NULL) {
4476                 return -1;
4477         }
4478         xmlDocPtr doc = xmlCtxtReadFile (ctxt, xmlpath.c_str(), NULL, XML_PARSE_HUGE);
4479
4480         if (doc == NULL) {
4481                 xmlFreeParserCtxt(ctxt);
4482                 return -1;
4483         }
4484
4485         xmlNodePtr node = xmlDocGetRootElement(doc);
4486
4487         if (node == NULL) {
4488                 xmlFreeParserCtxt(ctxt);
4489                 xmlFreeDoc (doc);
4490                 return -1;
4491         }
4492
4493         /* sample rate & version*/
4494
4495         xmlAttrPtr attr;
4496         for (attr = node->properties; attr; attr = attr->next) {
4497                 if (!strcmp ((const char*)attr->name, "version") && attr->children) {
4498                         version = std::string ((char*)attr->children->content);
4499                 }
4500                 if (!strcmp ((const char*)attr->name, "sample-rate") && attr->children) {
4501                         sample_rate = atoi ((char*)attr->children->content);
4502                         found_sr = true;
4503                 }
4504         }
4505
4506         if ((parse_stateful_loading_version(version) / 1000L) > (CURRENT_SESSION_FILE_VERSION / 1000L)) {
4507                 return -1;
4508         }
4509
4510         node = node->children;
4511         while (node != NULL) {
4512                  if (!strcmp((const char*) node->name, "ProgramVersion")) {
4513                          xmlChar* val = xmlGetProp (node, (const xmlChar*)"modified-with");
4514                          if (val) {
4515                                  program_version = string ((const char*)val);
4516                                  size_t sep = program_version.find_first_of("-");
4517                                  if (sep != string::npos) {
4518                                          program_version = program_version.substr (0, sep);
4519                                  }
4520                          }
4521                          xmlFree (val);
4522                  }
4523                  if (strcmp((const char*) node->name, "Config")) {
4524                          node = node->next;
4525                          continue;
4526                  }
4527                  for (node = node->children; node; node = node->next) {
4528                          xmlChar* pv = xmlGetProp (node, (const xmlChar*)"name");
4529                          if (pv && !strcmp ((const char*)pv, "native-file-data-format")) {
4530                                  xmlFree (pv);
4531                                  xmlChar* val = xmlGetProp (node, (const xmlChar*)"value");
4532                                  if (val) {
4533                                          try {
4534                                                  SampleFormat fmt = (SampleFormat) string_2_enum (string ((const char*)val), fmt);
4535                                                  data_format = fmt;
4536                                                  found_data_format = true;
4537                                          } catch (PBD::unknown_enumeration& e) {}
4538                                  }
4539                                  xmlFree (val);
4540                                  break;
4541                          }
4542                          xmlFree (pv);
4543                  }
4544                  break;
4545         }
4546
4547         xmlFreeParserCtxt(ctxt);
4548         xmlFreeDoc (doc);
4549
4550         return (found_sr && found_data_format) ? 0 : 1;
4551 }
4552
4553 std::string
4554 Session::get_snapshot_from_instant (const std::string& session_dir)
4555 {
4556         std::string instant_xml_path = Glib::build_filename (session_dir, "instant.xml");
4557
4558         if (!Glib::file_test (instant_xml_path, Glib::FILE_TEST_EXISTS)) {
4559                 return "";
4560         }
4561
4562         XMLTree tree;
4563         if (!tree.read (instant_xml_path)) {
4564                 return "";
4565         }
4566
4567         XMLProperty const * prop;
4568         XMLNode *last_used_snapshot = tree.root()->child("LastUsedSnapshot");
4569         if (last_used_snapshot && (prop = last_used_snapshot->property ("name")) != 0) {
4570                 return prop->value();
4571         }
4572
4573         return "";
4574 }
4575
4576 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
4577 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
4578
4579 int
4580 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
4581 {
4582         uint32_t total = 0;
4583         uint32_t n = 0;
4584         SourcePathMap source_path_map;
4585         string new_path;
4586         boost::shared_ptr<AudioFileSource> afs;
4587         int ret = 0;
4588
4589         {
4590
4591                 Glib::Threads::Mutex::Lock lm (source_lock);
4592
4593                 cerr << " total sources = " << sources.size();
4594
4595                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4596                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4597
4598                         if (!fs) {
4599                                 continue;
4600                         }
4601
4602                         if (fs->within_session()) {
4603                                 continue;
4604                         }
4605
4606                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
4607                                 source_path_map[fs->path()].push_back (fs);
4608                         } else {
4609                                 SeveralFileSources v;
4610                                 v.push_back (fs);
4611                                 source_path_map.insert (make_pair (fs->path(), v));
4612                         }
4613
4614                         total++;
4615                 }
4616
4617                 cerr << " fsources = " << total << endl;
4618
4619                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
4620
4621                         /* tell caller where we are */
4622
4623                         string old_path = i->first;
4624
4625                         callback (n, total, old_path);
4626
4627                         cerr << old_path << endl;
4628
4629                         new_path.clear ();
4630
4631                         switch (i->second.front()->type()) {
4632                         case DataType::AUDIO:
4633                                 new_path = new_audio_source_path_for_embedded (old_path);
4634                                 break;
4635
4636                         case DataType::MIDI:
4637                                 /* XXX not implemented yet */
4638                                 break;
4639                         }
4640
4641                         if (new_path.empty()) {
4642                                 continue;
4643                         }
4644
4645                         cerr << "Move " << old_path << " => " << new_path << endl;
4646
4647                         if (!copy_file (old_path, new_path)) {
4648                                 cerr << "failed !\n";
4649                                 ret = -1;
4650                         }
4651
4652                         /* make sure we stop looking in the external
4653                            dir/folder. Remember, this is an all-or-nothing
4654                            operations, it doesn't merge just some files.
4655                         */
4656                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4657
4658                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4659                                 (*f)->set_path (new_path);
4660                         }
4661                 }
4662         }
4663
4664         save_state ("", false, false);
4665
4666         return ret;
4667 }
4668
4669 static
4670 bool accept_all_files (string const &, void *)
4671 {
4672         return true;
4673 }
4674
4675 void
4676 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4677 {
4678         /* It would be good if this did something useful vis-a-vis save-as, but the arguments doesn't provide the correct information right now to do this.
4679         */
4680 }
4681
4682 static string
4683 make_new_media_path (string old_path, string new_session_folder, string new_session_name)
4684 {
4685         // old_path must be in within_session ()
4686         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4687         vector<string> v;
4688         v.push_back (new_session_folder); /* full path */
4689         v.push_back (interchange_dir_name);
4690         v.push_back (new_session_name);   /* just one directory/folder */
4691         v.push_back (typedir);
4692         v.push_back (Glib::path_get_basename (old_path));
4693
4694         return Glib::build_filename (v);
4695 }
4696
4697 static string
4698 make_new_audio_path (string filename, string new_session_folder, string new_session_name)
4699 {
4700         vector<string> v;
4701         v.push_back (new_session_folder); /* full path */
4702         v.push_back (interchange_dir_name);
4703         v.push_back (new_session_name);
4704         v.push_back (ARDOUR::sound_dir_name);
4705         v.push_back (filename);
4706
4707         return Glib::build_filename (v);
4708 }
4709
4710 int
4711 Session::save_as (SaveAs& saveas)
4712 {
4713         vector<string> files;
4714         string current_folder = Glib::path_get_dirname (_path);
4715         string new_folder = legalize_for_path (saveas.new_name);
4716         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4717         int64_t total_bytes = 0;
4718         int64_t copied = 0;
4719         int64_t cnt = 0;
4720         int64_t all = 0;
4721         int32_t internal_file_cnt = 0;
4722
4723         vector<string> do_not_copy_extensions;
4724         do_not_copy_extensions.push_back (statefile_suffix);
4725         do_not_copy_extensions.push_back (pending_suffix);
4726         do_not_copy_extensions.push_back (backup_suffix);
4727         do_not_copy_extensions.push_back (temp_suffix);
4728         do_not_copy_extensions.push_back (history_suffix);
4729
4730         /* get total size */
4731
4732         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4733
4734                 /* need to clear this because
4735                  * find_files_matching_filter() is cumulative
4736                  */
4737
4738                 files.clear ();
4739
4740                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4741
4742                 all += files.size();
4743
4744                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4745                         GStatBuf gsb;
4746                         g_stat ((*i).c_str(), &gsb);
4747                         total_bytes += gsb.st_size;
4748                 }
4749         }
4750
4751         /* save old values so we can switch back if we are not switching to the new session */
4752
4753         string old_path = _path;
4754         string old_name = _name;
4755         string old_snapshot = _current_snapshot_name;
4756         string old_sd = _session_dir->root_path();
4757         vector<string> old_search_path[DataType::num_types];
4758         string old_config_search_path[DataType::num_types];
4759
4760         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4761         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4762         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();
4763         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();
4764
4765         /* switch session directory */
4766
4767         (*_session_dir) = to_dir;
4768
4769         /* create new tree */
4770
4771         if (!_session_dir->create()) {
4772                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4773                 return -1;
4774         }
4775
4776         try {
4777                 /* copy all relevant files. Find each location in session_dirs,
4778                  * and copy files from there to target.
4779                  */
4780
4781                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4782
4783                         /* need to clear this because
4784                          * find_files_matching_filter() is cumulative
4785                          */
4786
4787                         files.clear ();
4788
4789                         const size_t prefix_len = (*sd).path.size();
4790
4791                         /* Work just on the files within this session dir */
4792
4793                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4794
4795                         /* add dir separator to protect against collisions with
4796                          * track names (e.g. track named "audiofiles" or
4797                          * "analysis".
4798                          */
4799
4800                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4801                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4802                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4803
4804                         /* copy all the files. Handling is different for media files
4805                            than others because of the *silly* subtree we have below the interchange
4806                            folder. That really was a bad idea, but I'm not fixing it as part of
4807                            implementing ::save_as().
4808                         */
4809
4810                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4811
4812                                 std::string from = *i;
4813
4814 #ifdef __APPLE__
4815                                 string filename = Glib::path_get_basename (from);
4816                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4817                                 if (filename == ".DS_STORE") {
4818                                         continue;
4819                                 }
4820 #endif
4821
4822                                 if (from.find (audiofile_dir_string) != string::npos) {
4823
4824                                         /* audio file: only copy if asked */
4825
4826                                         if (saveas.include_media && saveas.copy_media) {
4827
4828                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4829
4830                                                 info << "media file copying from " << from << " to " << to << endmsg;
4831
4832                                                 if (!copy_file (from, to)) {
4833                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4834                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4835                                                 }
4836                                         }
4837
4838                                         /* we found media files inside the session folder */
4839
4840                                         internal_file_cnt++;
4841
4842                                 } else if (from.find (midifile_dir_string) != string::npos) {
4843
4844                                         /* midi file: always copy unless
4845                                          * creating an empty new session
4846                                          */
4847
4848                                         if (saveas.include_media) {
4849
4850                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4851
4852                                                 info << "media file copying from " << from << " to " << to << endmsg;
4853
4854                                                 if (!copy_file (from, to)) {
4855                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4856                                                 }
4857                                         }
4858
4859                                         /* we found media files inside the session folder */
4860
4861                                         internal_file_cnt++;
4862
4863                                 } else if (from.find (analysis_dir_string) != string::npos) {
4864
4865                                         /*  make sure analysis dir exists in
4866                                          *  new session folder, but we're not
4867                                          *  copying analysis files here, see
4868                                          *  below
4869                                          */
4870
4871                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4872                                         continue;
4873
4874                                 } else {
4875
4876                                         /* normal non-media file. Don't copy state, history, etc.
4877                                          */
4878
4879                                         bool do_copy = true;
4880
4881                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4882                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4883                                                         /* end of filename matches extension, do not copy file */
4884                                                         do_copy = false;
4885                                                         break;
4886                                                 }
4887                                         }
4888
4889                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4890                                                 /* don't copy peakfiles if
4891                                                  * we're not copying media
4892                                                  */
4893                                                 do_copy = false;
4894                                         }
4895
4896                                         if (do_copy) {
4897                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4898
4899                                                 info << "attempting to make directory/folder " << to << endmsg;
4900
4901                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4902                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4903                                                 }
4904
4905                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4906
4907                                                 if (!copy_file (from, to)) {
4908                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4909                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4910                                                 }
4911                                         }
4912                                 }
4913
4914                                 /* measure file size even if we're not going to copy so that our Progress
4915                                    signals are correct, since we included these do-not-copy files
4916                                    in the computation of the total size and file count.
4917                                 */
4918
4919                                 GStatBuf gsb;
4920                                 g_stat (from.c_str(), &gsb);
4921                                 copied += gsb.st_size;
4922                                 cnt++;
4923
4924                                 double fraction = (double) copied / total_bytes;
4925
4926                                 bool keep_going = true;
4927
4928                                 if (saveas.copy_media) {
4929
4930                                         /* no need or expectation of this if
4931                                          * media is not being copied, because
4932                                          * it will be fast(ish).
4933                                          */
4934
4935                                         /* tell someone "X percent, file M of N"; M is one-based */
4936
4937                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4938
4939                                         if (res) {
4940                                                 keep_going = *res;
4941                                         }
4942                                 }
4943
4944                                 if (!keep_going) {
4945                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4946                                 }
4947                         }
4948
4949                 }
4950
4951                 /* copy optional folders, if any */
4952
4953                 string old = plugins_dir ();
4954                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4955                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4956                         copy_files (old, newdir);
4957                 }
4958
4959                 old = externals_dir ();
4960                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4961                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4962                         copy_files (old, newdir);
4963                 }
4964
4965                 old = automation_dir ();
4966                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4967                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4968                         copy_files (old, newdir);
4969                 }
4970
4971                 if (saveas.include_media) {
4972
4973                         if (saveas.copy_media) {
4974 #ifndef PLATFORM_WINDOWS
4975                                 /* There are problems with analysis files on
4976                                  * Windows, because they used a colon in their
4977                                  * names as late as 4.0. Colons are not legal
4978                                  * under Windows even if NTFS allows them.
4979                                  *
4980                                  * This is a tricky problem to solve so for
4981                                  * just don't copy these files. They will be
4982                                  * regenerated as-needed anyway, subject to the
4983                                  * existing issue that the filenames will be
4984                                  * rejected by Windows, which is a separate
4985                                  * problem (though related).
4986                                  */
4987
4988                                 /* only needed if we are copying media, since the
4989                                  * analysis data refers to media data
4990                                  */
4991
4992                                 old = analysis_dir ();
4993                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4994                                         string newdir = Glib::build_filename (to_dir, "analysis");
4995                                         copy_files (old, newdir);
4996                                 }
4997 #endif /* PLATFORM_WINDOWS */
4998                         }
4999                 }
5000
5001                 _path = to_dir;
5002                 set_snapshot_name (saveas.new_name);
5003                 _name = saveas.new_name;
5004
5005                 if (saveas.include_media && !saveas.copy_media) {
5006
5007                         /* reset search paths of the new session (which we're pretending to be right now) to
5008                            include the original session search path, so we can still find all audio.
5009                         */
5010
5011                         if (internal_file_cnt) {
5012                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
5013                                         ensure_search_path_includes (*s, DataType::AUDIO);
5014                                         cerr << "be sure to include " << *s << "  for audio" << endl;
5015                                 }
5016
5017                                 /* we do not do this for MIDI because we copy
5018                                    all MIDI files if saveas.include_media is
5019                                    true
5020                                 */
5021                         }
5022                 }
5023
5024                 bool was_dirty = dirty ();
5025
5026                 save_default_options ();
5027
5028                 if (saveas.copy_media && saveas.copy_external) {
5029                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
5030                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
5031                         }
5032                 }
5033
5034                 saveas.final_session_folder_name = _path;
5035
5036                 store_recent_sessions (_name, _path);
5037
5038                 if (!saveas.switch_to) {
5039
5040                         /* save the new state */
5041
5042                         save_state ("", false, false, !saveas.include_media);
5043
5044                         /* switch back to the way things were */
5045
5046                         _path = old_path;
5047                         _name = old_name;
5048                         set_snapshot_name (old_snapshot);
5049
5050                         (*_session_dir) = old_sd;
5051
5052                         if (was_dirty) {
5053                                 set_dirty ();
5054                         }
5055
5056                         if (internal_file_cnt) {
5057                                 /* reset these to their original values */
5058                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
5059                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
5060                         }
5061
5062                 } else {
5063
5064                         /* prune session dirs, and update disk space statistics
5065                          */
5066
5067                         space_and_path sp;
5068                         sp.path = _path;
5069                         session_dirs.clear ();
5070                         session_dirs.push_back (sp);
5071                         refresh_disk_space ();
5072
5073                         _writable = exists_and_writable (_path);
5074
5075                         /* ensure that all existing tracks reset their current capture source paths
5076                          */
5077                         reset_write_sources (true, true);
5078
5079                         /* creating new write sources marks the session as
5080                            dirty. If the new session is empty, then
5081                            save_state() thinks we're saving a template and will
5082                            not mark the session as clean. So do that here,
5083                            before we save state.
5084                         */
5085
5086                         if (!saveas.include_media) {
5087                                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
5088                         }
5089
5090                         save_state ("", false, false, !saveas.include_media);
5091
5092                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
5093                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
5094                         */
5095
5096                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5097                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
5098
5099                                 if (!fs) {
5100                                         continue;
5101                                 }
5102
5103                                 if (fs->within_session()) {
5104                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
5105                                         fs->set_path (newpath);
5106                                 }
5107                         }
5108                 }
5109
5110         } catch (Glib::FileError& e) {
5111
5112                 saveas.failure_message = e.what();
5113
5114                 /* recursively remove all the directories */
5115
5116                 remove_directory (to_dir);
5117
5118                 /* return error */
5119
5120                 return -1;
5121
5122         } catch (...) {
5123
5124                 saveas.failure_message = _("unknown reason");
5125
5126                 /* recursively remove all the directories */
5127
5128                 remove_directory (to_dir);
5129
5130                 /* return error */
5131
5132                 return -1;
5133         }
5134
5135         return 0;
5136 }
5137
5138 static void set_progress (Progress* p, size_t n, size_t t)
5139 {
5140         p->set_progress (float (n) / float(t));
5141 }
5142
5143 int
5144 Session::archive_session (const std::string& dest,
5145                           const std::string& name,
5146                           ArchiveEncode compress_audio,
5147                           FileArchive::CompressionLevel compression_level,
5148                           bool only_used_sources,
5149                           Progress* progress)
5150 {
5151         if (dest.empty () || name.empty ()) {
5152                 return -1;
5153         }
5154
5155         /* We are going to temporarily change some source properties,
5156          * don't allow any concurrent saves (periodic or otherwise */
5157         Glib::Threads::Mutex::Lock lm (save_source_lock);
5158
5159         disable_record (false);
5160
5161         /* save current values */
5162         string old_path = _path;
5163         string old_name = _name;
5164         string old_snapshot = _current_snapshot_name;
5165         string old_sd = _session_dir->root_path();
5166         string old_config_search_path[DataType::num_types];
5167         old_config_search_path[DataType::AUDIO] = config.get_audio_search_path ();
5168         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();
5169
5170         /* ensure that session-path is included in search-path */
5171         bool ok = false;
5172         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
5173                 if ((*sd).path == old_path) {
5174                         ok = true;
5175                 }
5176         }
5177         if (!ok) {
5178                 return -1;
5179         }
5180
5181         /* create temporary dir to save session to */
5182 #ifdef PLATFORM_WINDOWS
5183         char tmp[256] = "C:\\TEMP\\";
5184         GetTempPath (sizeof (tmp), tmp);
5185 #else
5186         char const* tmp = getenv("TMPDIR");
5187         if (!tmp) {
5188                 tmp = "/tmp/";
5189         }
5190 #endif
5191         if ((strlen (tmp) + 21) > 1024) {
5192                 return -1;
5193         }
5194
5195         char tmptpl[1024];
5196         strcpy (tmptpl, tmp);
5197         strcat (tmptpl, "ardourarchive-XXXXXX");
5198         char*  tmpdir = g_mkdtemp (tmptpl);
5199
5200         if (!tmpdir) {
5201                 return -1;
5202         }
5203
5204         std::string to_dir = std::string (tmpdir);
5205
5206         /* switch session directory temporarily */
5207         (*_session_dir) = to_dir;
5208
5209         if (!_session_dir->create()) {
5210                 (*_session_dir) = old_sd;
5211                 remove_directory (to_dir);
5212                 return -1;
5213         }
5214
5215         /* prepare archive */
5216         string archive = Glib::build_filename (dest, name + session_archive_suffix);
5217
5218         PBD::ScopedConnectionList progress_connection;
5219         PBD::FileArchive ar (archive);
5220         if (progress) {
5221                 ar.progress.connect_same_thread (progress_connection, boost::bind (&set_progress, progress, _1, _2));
5222         }
5223
5224         /* collect files to archive */
5225         std::map<string,string> filemap;
5226
5227         vector<string> do_not_copy_extensions;
5228         do_not_copy_extensions.push_back (statefile_suffix);
5229         do_not_copy_extensions.push_back (pending_suffix);
5230         do_not_copy_extensions.push_back (backup_suffix);
5231         do_not_copy_extensions.push_back (temp_suffix);
5232         do_not_copy_extensions.push_back (history_suffix);
5233
5234         vector<string> blacklist_dirs;
5235         blacklist_dirs.push_back (string (peak_dir_name) + G_DIR_SEPARATOR);
5236         blacklist_dirs.push_back (string (analysis_dir_name) + G_DIR_SEPARATOR);
5237         blacklist_dirs.push_back (string (dead_dir_name) + G_DIR_SEPARATOR);
5238         blacklist_dirs.push_back (string (export_dir_name) + G_DIR_SEPARATOR);
5239         blacklist_dirs.push_back (string (externals_dir_name) + G_DIR_SEPARATOR);
5240         blacklist_dirs.push_back (string (plugins_dir_name) + G_DIR_SEPARATOR);
5241
5242         std::map<boost::shared_ptr<AudioFileSource>, std::string> orig_sources;
5243         std::map<boost::shared_ptr<AudioFileSource>, std::string> orig_origin;
5244         std::map<boost::shared_ptr<AudioFileSource>, float> orig_gain;
5245
5246         set<boost::shared_ptr<Source> > sources_used_by_this_snapshot;
5247         if (only_used_sources) {
5248                 playlists->sync_all_regions_with_regions ();
5249                 playlists->foreach (boost::bind (merge_all_sources, _1, &sources_used_by_this_snapshot), false);
5250         }
5251
5252         /* collect audio sources for this session, calc total size for encoding
5253          * add option to only include *used* sources (see Session::cleanup_sources)
5254          */
5255         size_t total_size = 0;
5256         {
5257                 Glib::Threads::Mutex::Lock lm (source_lock);
5258
5259                 /* build a list of used names */
5260                 std::set<std::string> audio_file_names;
5261                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5262                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (i->second);
5263                         if (!afs || afs->readable_length () == 0) {
5264                                 continue;
5265                         }
5266                         if (only_used_sources) {
5267                                 if (!afs->used()) {
5268                                         continue;
5269                                 }
5270                                 if (sources_used_by_this_snapshot.find (afs) == sources_used_by_this_snapshot.end ()) {
5271                                         continue;
5272                                 }
5273                         }
5274                         audio_file_names.insert (Glib::path_get_basename (afs->path()));
5275                 }
5276
5277                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5278                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (i->second);
5279                         if (!afs || afs->readable_length () == 0) {
5280                                 continue;
5281                         }
5282
5283                         if (only_used_sources) {
5284                                 if (!afs->used()) {
5285                                         continue;
5286                                 }
5287                                 if (sources_used_by_this_snapshot.find (afs) == sources_used_by_this_snapshot.end ()) {
5288                                         continue;
5289                                 }
5290                         }
5291
5292                         std::string from = afs->path();
5293
5294                         if (compress_audio != NO_ENCODE) {
5295                                 total_size += afs->readable_length ();
5296                         } else {
5297                                 /* copy files as-is */
5298                                 if (!afs->within_session()) {
5299                                         string to = Glib::path_get_basename (from);
5300
5301                                         /* avoid name collitions, see also new_audio_source_path_for_embedded ()
5302                                          * - avoid conflict with files existing in interchange
5303                                          * - avoid conflict with other embedded sources
5304                                          */
5305                                         if (audio_file_names.find (to) == audio_file_names.end ()) {
5306                                                 // we need a new name, add a '-<num>' before the '.<ext>'
5307                                                 string bn   = to.substr (0, to.find_last_of ('.'));
5308                                                 string ext  = to.find_last_of ('.') == string::npos ? "" : to.substr (to.find_last_of ('.'));
5309                                                 to = bn + "-1" + ext;
5310                                         }
5311                                         while (audio_file_names.find (to) == audio_file_names.end ()) {
5312                                                 to = bump_name_once (to, '-');
5313                                         }
5314
5315                                         audio_file_names.insert (to);
5316                                         filemap[from] = make_new_audio_path (to, name, name);
5317
5318                                         remove_dir_from_search_path (Glib::path_get_dirname (from), DataType::AUDIO);
5319
5320                                         orig_origin[afs] = afs->origin ();
5321                                         afs->set_origin ("");
5322
5323                                 } else {
5324                                         filemap[from] = make_new_media_path (from, name, name);
5325                                 }
5326                         }
5327                 }
5328         }
5329
5330         /* encode audio */
5331         if (compress_audio != NO_ENCODE) {
5332                 if (progress) {
5333                         progress->set_progress (2); // set to "encoding"
5334                         progress->set_progress (0);
5335                 }
5336
5337                 Glib::Threads::Mutex::Lock lm (source_lock);
5338                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
5339                         boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (i->second);
5340                         if (!afs || afs->readable_length () == 0) {
5341                                 continue;
5342                         }
5343
5344                         if (only_used_sources) {
5345                                 if (!afs->used()) {
5346                                         continue;
5347                                 }
5348                                 if (sources_used_by_this_snapshot.find (afs) == sources_used_by_this_snapshot.end ()) {
5349                                         continue;
5350                                 }
5351                         }
5352
5353                         orig_sources[afs] = afs->path();
5354                         orig_gain[afs]    = afs->gain();
5355
5356                         std::string new_path = make_new_media_path (afs->path (), to_dir, name);
5357
5358                         std::string channelsuffix = "";
5359                         if (afs->channel() > 0) {  /* n_channels() is /wrongly/ 1. */
5360                                 /* embedded external multi-channel files are converted to multiple-mono */
5361                                 channelsuffix = string_compose ("-c%1", afs->channel ());
5362                         }
5363                         new_path = Glib::build_filename (Glib::path_get_dirname (new_path), PBD::basename_nosuffix (new_path) + channelsuffix + ".flac");
5364                         g_mkdir_with_parents (Glib::path_get_dirname (new_path).c_str (), 0755);
5365
5366                         /* avoid name collisions of external files with same name */
5367                         if (Glib::file_test (new_path, Glib::FILE_TEST_EXISTS)) {
5368                                 new_path = Glib::build_filename (Glib::path_get_dirname (new_path), PBD::basename_nosuffix (new_path) + channelsuffix + "-1.flac");
5369                         }
5370                         while (Glib::file_test (new_path, Glib::FILE_TEST_EXISTS)) {
5371                                 new_path = bump_name_once (new_path, '-');
5372                         }
5373
5374                         if (progress) {
5375                                 progress->descend ((float)afs->readable_length () / total_size);
5376                         }
5377
5378                         try {
5379                                 SndFileSource* ns = new SndFileSource (*this, *(afs.get()), new_path, compress_audio == FLAC_16BIT, progress);
5380                                 afs->replace_file (new_path);
5381                                 afs->set_gain (ns->gain(), true);
5382                                 delete ns;
5383                         } catch (...) {
5384                                 cerr << "failed to encode " << afs->path() << " to " << new_path << "\n";
5385                         }
5386
5387                         if (progress) {
5388                                 progress->ascend ();
5389                         }
5390                 }
5391         }
5392
5393         if (progress) {
5394                 progress->set_progress (-1); // set to "archiving"
5395                 progress->set_progress (0);
5396         }
5397
5398         /* index files relevant for this session */
5399         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
5400                 vector<string> files;
5401
5402                 size_t prefix_len = (*sd).path.size();
5403                 if (prefix_len > 0 && (*sd).path.at (prefix_len - 1) != G_DIR_SEPARATOR) {
5404                         ++prefix_len;
5405                 }
5406
5407                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
5408
5409                 static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
5410                 static const std::string videofile_dir_string = string (video_dir_name) + G_DIR_SEPARATOR;
5411                 static const std::string midifile_dir_string  = string (midi_dir_name)  + G_DIR_SEPARATOR;
5412
5413                 for (vector<string>::const_iterator i = files.begin (); i != files.end (); ++i) {
5414                         std::string from = *i;
5415
5416 #ifdef __APPLE__
5417                         string filename = Glib::path_get_basename (from);
5418                         std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
5419                         if (filename == ".DS_STORE") {
5420                                 continue;
5421                         }
5422 #endif
5423
5424                         if (from.find (audiofile_dir_string) != string::npos) {
5425                                 ; // handled above
5426                         } else if (from.find (midifile_dir_string) != string::npos) {
5427                                 filemap[from] = make_new_media_path (from, name, name);
5428                         } else if (from.find (videofile_dir_string) != string::npos) {
5429                                 filemap[from] = make_new_media_path (from, name, name);
5430                         } else {
5431                                 bool do_copy = true;
5432                                 for (vector<string>::iterator v = blacklist_dirs.begin(); v != blacklist_dirs.end(); ++v) {
5433                                         if (from.find (*v) != string::npos) {
5434                                                 do_copy = false;
5435                                                 break;
5436                                         }
5437                                 }
5438                                 for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
5439                                         if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
5440                                                 do_copy = false;
5441                                                 break;
5442                                         }
5443                                 }
5444
5445                                 if (do_copy) {
5446                                         filemap[from] = name + G_DIR_SEPARATOR + from.substr (prefix_len);
5447                                 }
5448                         }
5449                 }
5450         }
5451
5452         /* write session file */
5453         _path = to_dir;
5454         g_mkdir_with_parents (externals_dir ().c_str (), 0755);
5455
5456         save_state (name, false, false, false, true, only_used_sources);
5457
5458         save_default_options ();
5459
5460         size_t prefix_len = _path.size();
5461         if (prefix_len > 0 && _path.at (prefix_len - 1) != G_DIR_SEPARATOR) {
5462                 ++prefix_len;
5463         }
5464
5465         /* collect session-state files */
5466         vector<string> files;
5467         do_not_copy_extensions.clear ();
5468         do_not_copy_extensions.push_back (history_suffix);
5469
5470         blacklist_dirs.clear ();
5471         blacklist_dirs.push_back (string (externals_dir_name) + G_DIR_SEPARATOR);
5472
5473         find_files_matching_filter (files, to_dir, accept_all_files, 0, false, true, true);
5474         for (vector<string>::const_iterator i = files.begin (); i != files.end (); ++i) {
5475                 std::string from = *i;
5476                 bool do_copy = true;
5477                 for (vector<string>::iterator v = blacklist_dirs.begin(); v != blacklist_dirs.end(); ++v) {
5478                         if (from.find (*v) != string::npos) {
5479                                 do_copy = false;
5480                                 break;
5481                         }
5482                 }
5483                 for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
5484                         if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
5485                                 do_copy = false;
5486                                 break;
5487                         }
5488                 }
5489                 if (do_copy) {
5490                         filemap[from] = name + G_DIR_SEPARATOR + from.substr (prefix_len);
5491                 }
5492         }
5493
5494         /* restore original values */
5495         _path = old_path;
5496         _name = old_name;
5497         set_snapshot_name (old_snapshot);
5498         (*_session_dir) = old_sd;
5499         config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
5500         config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
5501
5502         for (std::map<boost::shared_ptr<AudioFileSource>, std::string>::iterator i = orig_origin.begin (); i != orig_origin.end (); ++i) {
5503                 i->first->set_origin (i->second);
5504         }
5505         for (std::map<boost::shared_ptr<AudioFileSource>, std::string>::iterator i = orig_sources.begin (); i != orig_sources.end (); ++i) {
5506                 i->first->replace_file (i->second);
5507         }
5508         for (std::map<boost::shared_ptr<AudioFileSource>, float>::iterator i = orig_gain.begin (); i != orig_gain.end (); ++i) {
5509                 i->first->set_gain (i->second, true);
5510         }
5511
5512         int rv = ar.create (filemap, compression_level);
5513         remove_directory (to_dir);
5514
5515         return rv;
5516 }
5517
5518 void
5519 Session::undo (uint32_t n)
5520 {
5521         if (actively_recording()) {
5522                 return;
5523         }
5524
5525         _history.undo (n);
5526 }
5527
5528 void
5529 Session::redo (uint32_t n)
5530 {
5531         if (actively_recording()) {
5532                 return;
5533         }
5534
5535         _history.redo (n);
5536 }