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