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