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