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