first vaguely working version using PresentationInfo
[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 Monitor 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"), PresentationInfo::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, PresentationInfo::max_order);
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, PresentationInfo::max_order);
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                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1646                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1647
1648                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1649                         BOOST_MARK_ROUTE (r);
1650                         ret = r;
1651                 }
1652         }
1653
1654         return ret;
1655 }
1656
1657 boost::shared_ptr<Route>
1658 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1659 {
1660         boost::shared_ptr<Route> ret;
1661
1662         if (node.name() != "Route") {
1663                 return ret;
1664         }
1665
1666         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1667         if (!ds_prop) {
1668                 ds_prop = node.property (X_("diskstream"));
1669         }
1670
1671         DataType type = DataType::AUDIO;
1672         XMLProperty const * prop = node.property("default-type");
1673
1674         if (prop) {
1675                 type = DataType (prop->value());
1676         }
1677
1678         assert (type != DataType::NIL);
1679
1680         if (ds_prop) {
1681
1682                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1683                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1684                         ++i;
1685                 }
1686
1687                 if (i == _diskstreams_2X.end()) {
1688                         error << _("Could not find diskstream for route") << endmsg;
1689                         return boost::shared_ptr<Route> ();
1690                 }
1691
1692                 boost::shared_ptr<Track> track;
1693
1694                 if (type == DataType::AUDIO) {
1695                         track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1696                 } else {
1697                         track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1698                 }
1699
1700                 if (track->init()) {
1701                         return ret;
1702                 }
1703
1704                 if (track->set_state (node, version)) {
1705                         return ret;
1706                 }
1707
1708                 track->set_diskstream (*i);
1709
1710                 BOOST_MARK_TRACK (track);
1711                 ret = track;
1712
1713         } else {
1714                 PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
1715                 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
1716
1717                 if (r->init () == 0 && r->set_state (node, version) == 0) {
1718                         BOOST_MARK_ROUTE (r);
1719                         ret = r;
1720                 }
1721         }
1722
1723         return ret;
1724 }
1725
1726 int
1727 Session::load_regions (const XMLNode& node)
1728 {
1729         XMLNodeList nlist;
1730         XMLNodeConstIterator niter;
1731         boost::shared_ptr<Region> region;
1732
1733         nlist = node.children();
1734
1735         set_dirty();
1736
1737         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1738                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1739                         error << _("Session: cannot create Region from XML description.");
1740                         XMLProperty const * name = (**niter).property("name");
1741
1742                         if (name) {
1743                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1744                         }
1745
1746                         error << endmsg;
1747                 }
1748         }
1749
1750         return 0;
1751 }
1752
1753 int
1754 Session::load_compounds (const XMLNode& node)
1755 {
1756         XMLNodeList calist = node.children();
1757         XMLNodeConstIterator caiter;
1758         XMLProperty const * caprop;
1759
1760         for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1761                 XMLNode* ca = *caiter;
1762                 ID orig_id;
1763                 ID copy_id;
1764
1765                 if ((caprop = ca->property (X_("original"))) == 0) {
1766                         continue;
1767                 }
1768                 orig_id = caprop->value();
1769
1770                 if ((caprop = ca->property (X_("copy"))) == 0) {
1771                         continue;
1772                 }
1773                 copy_id = caprop->value();
1774
1775                 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1776                 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1777
1778                 if (!orig || !copy) {
1779                         warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1780                                                    orig_id, copy_id)
1781                                 << endmsg;
1782                         continue;
1783                 }
1784
1785                 RegionFactory::add_compound_association (orig, copy);
1786         }
1787
1788         return 0;
1789 }
1790
1791 void
1792 Session::load_nested_sources (const XMLNode& node)
1793 {
1794         XMLNodeList nlist;
1795         XMLNodeConstIterator niter;
1796
1797         nlist = node.children();
1798
1799         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1800                 if ((*niter)->name() == "Source") {
1801
1802                         /* it may already exist, so don't recreate it unnecessarily
1803                          */
1804
1805                         XMLProperty const * prop = (*niter)->property (X_("id"));
1806                         if (!prop) {
1807                                 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1808                                 continue;
1809                         }
1810
1811                         ID source_id (prop->value());
1812
1813                         if (!source_by_id (source_id)) {
1814
1815                                 try {
1816                                         SourceFactory::create (*this, **niter, true);
1817                                 }
1818                                 catch (failed_constructor& err) {
1819                                         error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1820                                 }
1821                         }
1822                 }
1823         }
1824 }
1825
1826 boost::shared_ptr<Region>
1827 Session::XMLRegionFactory (const XMLNode& node, bool full)
1828 {
1829         XMLProperty const * type = node.property("type");
1830
1831         try {
1832
1833                 const XMLNodeList& nlist = node.children();
1834
1835                 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1836                         XMLNode *child = (*niter);
1837                         if (child->name() == "NestedSource") {
1838                                 load_nested_sources (*child);
1839                         }
1840                 }
1841
1842                 if (!type || type->value() == "audio") {
1843                         return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1844                 } else if (type->value() == "midi") {
1845                         return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1846                 }
1847
1848         } catch (failed_constructor& err) {
1849                 return boost::shared_ptr<Region> ();
1850         }
1851
1852         return boost::shared_ptr<Region> ();
1853 }
1854
1855 boost::shared_ptr<AudioRegion>
1856 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1857 {
1858         XMLProperty const * prop;
1859         boost::shared_ptr<Source> source;
1860         boost::shared_ptr<AudioSource> as;
1861         SourceList sources;
1862         SourceList master_sources;
1863         uint32_t nchans = 1;
1864         char buf[128];
1865
1866         if (node.name() != X_("Region")) {
1867                 return boost::shared_ptr<AudioRegion>();
1868         }
1869
1870         if ((prop = node.property (X_("channels"))) != 0) {
1871                 nchans = atoi (prop->value().c_str());
1872         }
1873
1874         if ((prop = node.property ("name")) == 0) {
1875                 cerr << "no name for this region\n";
1876                 abort ();
1877         }
1878
1879         if ((prop = node.property (X_("source-0"))) == 0) {
1880                 if ((prop = node.property ("source")) == 0) {
1881                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1882                         return boost::shared_ptr<AudioRegion>();
1883                 }
1884         }
1885
1886         PBD::ID s_id (prop->value());
1887
1888         if ((source = source_by_id (s_id)) == 0) {
1889                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1890                 return boost::shared_ptr<AudioRegion>();
1891         }
1892
1893         as = boost::dynamic_pointer_cast<AudioSource>(source);
1894         if (!as) {
1895                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1896                 return boost::shared_ptr<AudioRegion>();
1897         }
1898
1899         sources.push_back (as);
1900
1901         /* pickup other channels */
1902
1903         for (uint32_t n=1; n < nchans; ++n) {
1904                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1905                 if ((prop = node.property (buf)) != 0) {
1906
1907                         PBD::ID id2 (prop->value());
1908
1909                         if ((source = source_by_id (id2)) == 0) {
1910                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1911                                 return boost::shared_ptr<AudioRegion>();
1912                         }
1913
1914                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1915                         if (!as) {
1916                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1917                                 return boost::shared_ptr<AudioRegion>();
1918                         }
1919                         sources.push_back (as);
1920                 }
1921         }
1922
1923         for (uint32_t n = 0; n < nchans; ++n) {
1924                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1925                 if ((prop = node.property (buf)) != 0) {
1926
1927                         PBD::ID id2 (prop->value());
1928
1929                         if ((source = source_by_id (id2)) == 0) {
1930                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1931                                 return boost::shared_ptr<AudioRegion>();
1932                         }
1933
1934                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1935                         if (!as) {
1936                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1937                                 return boost::shared_ptr<AudioRegion>();
1938                         }
1939                         master_sources.push_back (as);
1940                 }
1941         }
1942
1943         try {
1944                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1945
1946                 /* a final detail: this is the one and only place that we know how long missing files are */
1947
1948                 if (region->whole_file()) {
1949                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1950                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1951                                 if (sfp) {
1952                                         sfp->set_length (region->length());
1953                                 }
1954                         }
1955                 }
1956
1957                 if (!master_sources.empty()) {
1958                         if (master_sources.size() != nchans) {
1959                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1960                         } else {
1961                                 region->set_master_sources (master_sources);
1962                         }
1963                 }
1964
1965                 return region;
1966
1967         }
1968
1969         catch (failed_constructor& err) {
1970                 return boost::shared_ptr<AudioRegion>();
1971         }
1972 }
1973
1974 boost::shared_ptr<MidiRegion>
1975 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1976 {
1977         XMLProperty const * prop;
1978         boost::shared_ptr<Source> source;
1979         boost::shared_ptr<MidiSource> ms;
1980         SourceList sources;
1981
1982         if (node.name() != X_("Region")) {
1983                 return boost::shared_ptr<MidiRegion>();
1984         }
1985
1986         if ((prop = node.property ("name")) == 0) {
1987                 cerr << "no name for this region\n";
1988                 abort ();
1989         }
1990
1991         if ((prop = node.property (X_("source-0"))) == 0) {
1992                 if ((prop = node.property ("source")) == 0) {
1993                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1994                         return boost::shared_ptr<MidiRegion>();
1995                 }
1996         }
1997
1998         PBD::ID s_id (prop->value());
1999
2000         if ((source = source_by_id (s_id)) == 0) {
2001                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
2002                 return boost::shared_ptr<MidiRegion>();
2003         }
2004
2005         ms = boost::dynamic_pointer_cast<MidiSource>(source);
2006         if (!ms) {
2007                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
2008                 return boost::shared_ptr<MidiRegion>();
2009         }
2010
2011         sources.push_back (ms);
2012
2013         try {
2014                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
2015                 /* a final detail: this is the one and only place that we know how long missing files are */
2016
2017                 if (region->whole_file()) {
2018                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
2019                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
2020                                 if (sfp) {
2021                                         sfp->set_length (region->length());
2022                                 }
2023                         }
2024                 }
2025
2026                 return region;
2027         }
2028
2029         catch (failed_constructor& err) {
2030                 return boost::shared_ptr<MidiRegion>();
2031         }
2032 }
2033
2034 XMLNode&
2035 Session::get_sources_as_xml ()
2036
2037 {
2038         XMLNode* node = new XMLNode (X_("Sources"));
2039         Glib::Threads::Mutex::Lock lm (source_lock);
2040
2041         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2042                 node->add_child_nocopy (i->second->get_state());
2043         }
2044
2045         return *node;
2046 }
2047
2048 void
2049 Session::reset_write_sources (bool mark_write_complete, bool force)
2050 {
2051         boost::shared_ptr<RouteList> rl = routes.reader();
2052         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
2053                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
2054                 if (tr) {
2055                         _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
2056                         tr->reset_write_sources(mark_write_complete, force);
2057                         _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
2058                 }
2059         }
2060 }
2061
2062 int
2063 Session::load_sources (const XMLNode& node)
2064 {
2065         XMLNodeList nlist;
2066         XMLNodeConstIterator niter;
2067         boost::shared_ptr<Source> source; /* don't need this but it stops some
2068                                            * versions of gcc complaining about
2069                                            * discarded return values.
2070                                            */
2071
2072         nlist = node.children();
2073
2074         set_dirty();
2075
2076         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2077           retry:
2078                 try {
2079                         if ((source = XMLSourceFactory (**niter)) == 0) {
2080                                 error << _("Session: cannot create Source from XML description.") << endmsg;
2081                         }
2082
2083                 } catch (MissingSource& err) {
2084
2085                         int user_choice;
2086
2087                         if (err.type == DataType::MIDI && Glib::path_is_absolute (err.path)) {
2088                                 error << string_compose (_("A external MIDI file is missing. %1 cannot currently recover from missing external MIDI files"),
2089                                                          PROGRAM_NAME) << endmsg;
2090                                 return -1;
2091                         }
2092
2093                         if (!no_questions_about_missing_files) {
2094                                 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
2095                         } else {
2096                                 user_choice = -2;
2097                         }
2098
2099                         switch (user_choice) {
2100                         case 0:
2101                                 /* user added a new search location, so try again */
2102                                 goto retry;
2103
2104
2105                         case 1:
2106                                 /* user asked to quit the entire session load
2107                                  */
2108                                 return -1;
2109
2110                         case 2:
2111                                 no_questions_about_missing_files = true;
2112                                 goto retry;
2113
2114                         case 3:
2115                                 no_questions_about_missing_files = true;
2116                                 /* fallthru */
2117
2118                         case -1:
2119                         default:
2120                                 switch (err.type) {
2121
2122                                 case DataType::AUDIO:
2123                                         source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2124                                         break;
2125
2126                                 case DataType::MIDI:
2127                                         /* The MIDI file is actually missing so
2128                                          * just create a new one in the same
2129                                          * location. Do not announce its
2130                                          */
2131                                         string fullpath;
2132
2133                                         if (!Glib::path_is_absolute (err.path)) {
2134                                                 fullpath = Glib::build_filename (source_search_path (DataType::MIDI).front(), err.path);
2135                                         } else {
2136                                                 /* this should be an unrecoverable error: we would be creating a MIDI file outside
2137                                                    the session tree.
2138                                                 */
2139                                                 return -1;
2140                                         }
2141                                         /* Note that we do not announce the source just yet - we need to reset its ID before we do that */
2142                                         source = SourceFactory::createWritable (DataType::MIDI, *this, fullpath, false, _current_frame_rate, false, false);
2143                                         /* reset ID to match the missing one */
2144                                         source->set_id (**niter);
2145                                         /* Now we can announce it */
2146                                         SourceFactory::SourceCreated (source);
2147                                         break;
2148                                 }
2149                                 break;
2150                         }
2151                 }
2152         }
2153
2154         return 0;
2155 }
2156
2157 boost::shared_ptr<Source>
2158 Session::XMLSourceFactory (const XMLNode& node)
2159 {
2160         if (node.name() != "Source") {
2161                 return boost::shared_ptr<Source>();
2162         }
2163
2164         try {
2165                 /* note: do peak building in another thread when loading session state */
2166                 return SourceFactory::create (*this, node, true);
2167         }
2168
2169         catch (failed_constructor& err) {
2170                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the programmers."), PROGRAM_NAME) << endmsg;
2171                 return boost::shared_ptr<Source>();
2172         }
2173 }
2174
2175 int
2176 Session::save_template (string template_name, bool replace_existing)
2177 {
2178         if ((_state_of_the_state & CannotSave) || template_name.empty ()) {
2179                 return -1;
2180         }
2181
2182         bool absolute_path = Glib::path_is_absolute (template_name);
2183
2184         /* directory to put the template in */
2185         std::string template_dir_path;
2186
2187         if (!absolute_path) {
2188                 std::string user_template_dir(user_template_directory());
2189
2190                 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2191                         error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2192                                         user_template_dir, g_strerror (errno)) << endmsg;
2193                         return -1;
2194                 }
2195
2196                 template_dir_path = Glib::build_filename (user_template_dir, template_name);
2197         } else {
2198                 template_dir_path = template_name;
2199         }
2200
2201         if (!ARDOUR::Profile->get_trx()) {
2202                 if (!replace_existing && Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2203                         warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2204                                                                           template_dir_path) << endmsg;
2205                         return -2;
2206                 }
2207
2208                 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2209                         error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2210                                                                         template_dir_path, g_strerror (errno)) << endmsg;
2211                         return -1;
2212                 }
2213         }
2214
2215         /* file to write */
2216         std::string template_file_path;
2217
2218         if (ARDOUR::Profile->get_trx()) {
2219                 template_file_path = template_name;
2220         } else {
2221                 if (absolute_path) {
2222                         template_file_path = Glib::build_filename (template_dir_path, Glib::path_get_basename (template_dir_path) + template_suffix);
2223                 } else {
2224                         template_file_path = Glib::build_filename (template_dir_path, template_name + template_suffix);
2225                 }
2226         }
2227
2228         SessionSaveUnderway (); /* EMIT SIGNAL */
2229
2230         XMLTree tree;
2231
2232         {
2233                 PBD::Unwinder<std::string> uw (_template_state_dir, template_dir_path);
2234                 tree.set_root (&get_template());
2235         }
2236
2237         if (!tree.write (template_file_path)) {
2238                 error << _("template not saved") << endmsg;
2239                 return -1;
2240         }
2241
2242         store_recent_templates (template_file_path);
2243
2244         return 0;
2245 }
2246
2247 void
2248 Session::refresh_disk_space ()
2249 {
2250 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2251
2252         Glib::Threads::Mutex::Lock lm (space_lock);
2253
2254         /* get freespace on every FS that is part of the session path */
2255
2256         _total_free_4k_blocks = 0;
2257         _total_free_4k_blocks_uncertain = false;
2258
2259         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2260
2261                 struct statfs statfsbuf;
2262                 statfs (i->path.c_str(), &statfsbuf);
2263
2264                 double const scale = statfsbuf.f_bsize / 4096.0;
2265
2266                 /* See if this filesystem is read-only */
2267                 struct statvfs statvfsbuf;
2268                 statvfs (i->path.c_str(), &statvfsbuf);
2269
2270                 /* f_bavail can be 0 if it is undefined for whatever
2271                    filesystem we are looking at; Samba shares mounted
2272                    via GVFS are an example of this.
2273                 */
2274                 if (statfsbuf.f_bavail == 0) {
2275                         /* block count unknown */
2276                         i->blocks = 0;
2277                         i->blocks_unknown = true;
2278                 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2279                         /* read-only filesystem */
2280                         i->blocks = 0;
2281                         i->blocks_unknown = false;
2282                 } else {
2283                         /* read/write filesystem with known space */
2284                         i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2285                         i->blocks_unknown = false;
2286                 }
2287
2288                 _total_free_4k_blocks += i->blocks;
2289                 if (i->blocks_unknown) {
2290                         _total_free_4k_blocks_uncertain = true;
2291                 }
2292         }
2293 #elif defined PLATFORM_WINDOWS
2294         vector<string> scanned_volumes;
2295         vector<string>::iterator j;
2296         vector<space_and_path>::iterator i;
2297     DWORD nSectorsPerCluster, nBytesPerSector,
2298           nFreeClusters, nTotalClusters;
2299     char disk_drive[4];
2300         bool volume_found;
2301
2302         _total_free_4k_blocks = 0;
2303
2304         for (i = session_dirs.begin(); i != session_dirs.end(); i++) {
2305                 strncpy (disk_drive, (*i).path.c_str(), 3);
2306                 disk_drive[3] = 0;
2307                 strupr(disk_drive);
2308
2309                 volume_found = false;
2310                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2311                 {
2312                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2313                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2314                         i->blocks = (uint32_t)(nFreeBytes / 4096);
2315
2316                         for (j = scanned_volumes.begin(); j != scanned_volumes.end(); j++) {
2317                                 if (0 == j->compare(disk_drive)) {
2318                                         volume_found = true;
2319                                         break;
2320                                 }
2321                         }
2322
2323                         if (!volume_found) {
2324                                 scanned_volumes.push_back(disk_drive);
2325                                 _total_free_4k_blocks += i->blocks;
2326                         }
2327                 }
2328         }
2329
2330         if (0 == _total_free_4k_blocks) {
2331                 strncpy (disk_drive, path().c_str(), 3);
2332                 disk_drive[3] = 0;
2333
2334                 if (0 != (GetDiskFreeSpace(disk_drive, &nSectorsPerCluster, &nBytesPerSector, &nFreeClusters, &nTotalClusters)))
2335                 {
2336                         int64_t nBytesPerCluster = nBytesPerSector * nSectorsPerCluster;
2337                         int64_t nFreeBytes = nBytesPerCluster * (int64_t)nFreeClusters;
2338                         _total_free_4k_blocks = (uint32_t)(nFreeBytes / 4096);
2339                 }
2340         }
2341 #endif
2342 }
2343
2344 string
2345 Session::get_best_session_directory_for_new_audio ()
2346 {
2347         vector<space_and_path>::iterator i;
2348         string result = _session_dir->root_path();
2349
2350         /* handle common case without system calls */
2351
2352         if (session_dirs.size() == 1) {
2353                 return result;
2354         }
2355
2356         /* OK, here's the algorithm we're following here:
2357
2358         We want to select which directory to use for
2359         the next file source to be created. Ideally,
2360         we'd like to use a round-robin process so as to
2361         get maximum performance benefits from splitting
2362         the files across multiple disks.
2363
2364         However, in situations without much diskspace, an
2365         RR approach may end up filling up a filesystem
2366         with new files while others still have space.
2367         Its therefore important to pay some attention to
2368         the freespace in the filesystem holding each
2369         directory as well. However, if we did that by
2370         itself, we'd keep creating new files in the file
2371         system with the most space until it was as full
2372         as all others, thus negating any performance
2373         benefits of this RAID-1 like approach.
2374
2375         So, we use a user-configurable space threshold. If
2376         there are at least 2 filesystems with more than this
2377         much space available, we use RR selection between them.
2378         If not, then we pick the filesystem with the most space.
2379
2380         This gets a good balance between the two
2381         approaches.
2382         */
2383
2384         refresh_disk_space ();
2385
2386         int free_enough = 0;
2387
2388         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2389                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2390                         free_enough++;
2391                 }
2392         }
2393
2394         if (free_enough >= 2) {
2395                 /* use RR selection process, ensuring that the one
2396                    picked works OK.
2397                 */
2398
2399                 i = last_rr_session_dir;
2400
2401                 do {
2402                         if (++i == session_dirs.end()) {
2403                                 i = session_dirs.begin();
2404                         }
2405
2406                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2407                                 SessionDirectory sdir(i->path);
2408                                 if (sdir.create ()) {
2409                                         result = (*i).path;
2410                                         last_rr_session_dir = i;
2411                                         return result;
2412                                 }
2413                         }
2414
2415                 } while (i != last_rr_session_dir);
2416
2417         } else {
2418
2419                 /* pick FS with the most freespace (and that
2420                    seems to actually work ...)
2421                 */
2422
2423                 vector<space_and_path> sorted;
2424                 space_and_path_ascending_cmp cmp;
2425
2426                 sorted = session_dirs;
2427                 sort (sorted.begin(), sorted.end(), cmp);
2428
2429                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2430                         SessionDirectory sdir(i->path);
2431                         if (sdir.create ()) {
2432                                 result = (*i).path;
2433                                 last_rr_session_dir = i;
2434                                 return result;
2435                         }
2436                 }
2437         }
2438
2439         return result;
2440 }
2441
2442 string
2443 Session::automation_dir () const
2444 {
2445         return Glib::build_filename (_path, automation_dir_name);
2446 }
2447
2448 string
2449 Session::analysis_dir () const
2450 {
2451         return Glib::build_filename (_path, analysis_dir_name);
2452 }
2453
2454 string
2455 Session::plugins_dir () const
2456 {
2457         return Glib::build_filename (_path, plugins_dir_name);
2458 }
2459
2460 string
2461 Session::externals_dir () const
2462 {
2463         return Glib::build_filename (_path, externals_dir_name);
2464 }
2465
2466 int
2467 Session::load_bundles (XMLNode const & node)
2468 {
2469         XMLNodeList nlist = node.children();
2470         XMLNodeConstIterator niter;
2471
2472         set_dirty();
2473
2474         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2475                 if ((*niter)->name() == "InputBundle") {
2476                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2477                 } else if ((*niter)->name() == "OutputBundle") {
2478                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2479                 } else {
2480                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2481                         return -1;
2482                 }
2483         }
2484
2485         return 0;
2486 }
2487
2488 int
2489 Session::load_route_groups (const XMLNode& node, int version)
2490 {
2491         XMLNodeList nlist = node.children();
2492         XMLNodeConstIterator niter;
2493
2494         set_dirty ();
2495
2496         if (version >= 3000) {
2497
2498                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2499                         if ((*niter)->name() == "RouteGroup") {
2500                                 RouteGroup* rg = new RouteGroup (*this, "");
2501                                 add_route_group (rg);
2502                                 rg->set_state (**niter, version);
2503                         }
2504                 }
2505
2506         } else if (version < 3000) {
2507
2508                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2509                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2510                                 RouteGroup* rg = new RouteGroup (*this, "");
2511                                 add_route_group (rg);
2512                                 rg->set_state (**niter, version);
2513                         }
2514                 }
2515         }
2516
2517         return 0;
2518 }
2519
2520 static bool
2521 state_file_filter (const string &str, void* /*arg*/)
2522 {
2523         return (str.length() > strlen(statefile_suffix) &&
2524                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2525 }
2526
2527 static string
2528 remove_end(string state)
2529 {
2530         string statename(state);
2531
2532         string::size_type start,end;
2533         if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2534                 statename = statename.substr (start+1);
2535         }
2536
2537         if ((end = statename.rfind(statefile_suffix)) == string::npos) {
2538                 end = statename.length();
2539         }
2540
2541         return string(statename.substr (0, end));
2542 }
2543
2544 vector<string>
2545 Session::possible_states (string path)
2546 {
2547         vector<string> states;
2548         find_files_matching_filter (states, path, state_file_filter, 0, false, false);
2549
2550         transform(states.begin(), states.end(), states.begin(), remove_end);
2551
2552         sort (states.begin(), states.end());
2553
2554         return states;
2555 }
2556
2557 vector<string>
2558 Session::possible_states () const
2559 {
2560         return possible_states(_path);
2561 }
2562
2563 void
2564 Session::add_route_group (RouteGroup* g)
2565 {
2566         _route_groups.push_back (g);
2567         route_group_added (g); /* EMIT SIGNAL */
2568
2569         g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2570         g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2571         g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2572
2573         set_dirty ();
2574 }
2575
2576 void
2577 Session::remove_route_group (RouteGroup& rg)
2578 {
2579         list<RouteGroup*>::iterator i;
2580
2581         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2582                 _route_groups.erase (i);
2583                 delete &rg;
2584
2585                 route_group_removed (); /* EMIT SIGNAL */
2586         }
2587 }
2588
2589 /** Set a new order for our route groups, without adding or removing any.
2590  *  @param groups Route group list in the new order.
2591  */
2592 void
2593 Session::reorder_route_groups (list<RouteGroup*> groups)
2594 {
2595         _route_groups = groups;
2596
2597         route_groups_reordered (); /* EMIT SIGNAL */
2598         set_dirty ();
2599 }
2600
2601
2602 RouteGroup *
2603 Session::route_group_by_name (string name)
2604 {
2605         list<RouteGroup *>::iterator i;
2606
2607         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2608                 if ((*i)->name() == name) {
2609                         return* i;
2610                 }
2611         }
2612         return 0;
2613 }
2614
2615 RouteGroup&
2616 Session::all_route_group() const
2617 {
2618         return *_all_route_group;
2619 }
2620
2621 void
2622 Session::add_commands (vector<Command*> const & cmds)
2623 {
2624         for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2625                 add_command (*i);
2626         }
2627 }
2628
2629 void
2630 Session::add_command (Command* const cmd)
2631 {
2632         assert (_current_trans);
2633         DEBUG_UNDO_HISTORY (
2634             string_compose ("Current Undo Transaction %1, adding command: %2",
2635                             _current_trans->name (),
2636                             cmd->name ()));
2637         _current_trans->add_command (cmd);
2638 }
2639
2640 PBD::StatefulDiffCommand*
2641 Session::add_stateful_diff_command (boost::shared_ptr<PBD::StatefulDestructible> sfd)
2642 {
2643         PBD::StatefulDiffCommand* cmd = new PBD::StatefulDiffCommand (sfd);
2644         add_command (cmd);
2645         return cmd;
2646 }
2647
2648 void
2649 Session::begin_reversible_command (const string& name)
2650 {
2651         begin_reversible_command (g_quark_from_string (name.c_str ()));
2652 }
2653
2654 /** Begin a reversible command using a GQuark to identify it.
2655  *  begin_reversible_command() and commit_reversible_command() calls may be nested,
2656  *  but there must be as many begin...()s as there are commit...()s.
2657  */
2658 void
2659 Session::begin_reversible_command (GQuark q)
2660 {
2661         /* If nested begin/commit pairs are used, we create just one UndoTransaction
2662            to hold all the commands that are committed.  This keeps the order of
2663            commands correct in the history.
2664         */
2665
2666         if (_current_trans == 0) {
2667                 DEBUG_UNDO_HISTORY (string_compose (
2668                     "Begin Reversible Command, new transaction: %1", g_quark_to_string (q)));
2669
2670                 /* start a new transaction */
2671                 assert (_current_trans_quarks.empty ());
2672                 _current_trans = new UndoTransaction();
2673                 _current_trans->set_name (g_quark_to_string (q));
2674         } else {
2675                 DEBUG_UNDO_HISTORY (
2676                     string_compose ("Begin Reversible Command, current transaction: %1",
2677                                     _current_trans->name ()));
2678         }
2679
2680         _current_trans_quarks.push_front (q);
2681 }
2682
2683 void
2684 Session::abort_reversible_command ()
2685 {
2686         if (_current_trans != 0) {
2687                 DEBUG_UNDO_HISTORY (
2688                     string_compose ("Abort Reversible Command: %1", _current_trans->name ()));
2689                 _current_trans->clear();
2690                 delete _current_trans;
2691                 _current_trans = 0;
2692                 _current_trans_quarks.clear();
2693         }
2694 }
2695
2696 void
2697 Session::commit_reversible_command (Command *cmd)
2698 {
2699         assert (_current_trans);
2700         assert (!_current_trans_quarks.empty ());
2701
2702         struct timeval now;
2703
2704         if (cmd) {
2705                 DEBUG_UNDO_HISTORY (
2706                     string_compose ("Current Undo Transaction %1, adding command: %2",
2707                                     _current_trans->name (),
2708                                     cmd->name ()));
2709                 _current_trans->add_command (cmd);
2710         }
2711
2712         DEBUG_UNDO_HISTORY (
2713             string_compose ("Commit Reversible Command, current transaction: %1",
2714                             _current_trans->name ()));
2715
2716         _current_trans_quarks.pop_front ();
2717
2718         if (!_current_trans_quarks.empty ()) {
2719                 DEBUG_UNDO_HISTORY (
2720                     string_compose ("Commit Reversible Command, transaction is not "
2721                                     "top-level, current transaction: %1",
2722                                     _current_trans->name ()));
2723                 /* the transaction we're committing is not the top-level one */
2724                 return;
2725         }
2726
2727         if (_current_trans->empty()) {
2728                 /* no commands were added to the transaction, so just get rid of it */
2729                 DEBUG_UNDO_HISTORY (
2730                     string_compose ("Commit Reversible Command, No commands were "
2731                                     "added to current transaction: %1",
2732                                     _current_trans->name ()));
2733                 delete _current_trans;
2734                 _current_trans = 0;
2735                 return;
2736         }
2737
2738         gettimeofday (&now, 0);
2739         _current_trans->set_timestamp (now);
2740
2741         _history.add (_current_trans);
2742         _current_trans = 0;
2743 }
2744
2745 static bool
2746 accept_all_audio_files (const string& path, void* /*arg*/)
2747 {
2748         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2749                 return false;
2750         }
2751
2752         if (!AudioFileSource::safe_audio_file_extension (path)) {
2753                 return false;
2754         }
2755
2756         return true;
2757 }
2758
2759 static bool
2760 accept_all_midi_files (const string& path, void* /*arg*/)
2761 {
2762         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2763                 return false;
2764         }
2765
2766         return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2767                 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2768                 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2769 }
2770
2771 static bool
2772 accept_all_state_files (const string& path, void* /*arg*/)
2773 {
2774         if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2775                 return false;
2776         }
2777
2778         std::string const statefile_ext (statefile_suffix);
2779         if (path.length() >= statefile_ext.length()) {
2780                 return (0 == path.compare (path.length() - statefile_ext.length(), statefile_ext.length(), statefile_ext));
2781         } else {
2782                 return false;
2783         }
2784 }
2785
2786 int
2787 Session::find_all_sources (string path, set<string>& result)
2788 {
2789         XMLTree tree;
2790         XMLNode* node;
2791
2792         if (!tree.read (path)) {
2793                 return -1;
2794         }
2795
2796         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2797                 return -2;
2798         }
2799
2800         XMLNodeList nlist;
2801         XMLNodeConstIterator niter;
2802
2803         nlist = node->children();
2804
2805         set_dirty();
2806
2807         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2808
2809                 XMLProperty const * prop;
2810
2811                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2812                         continue;
2813                 }
2814
2815                 DataType type (prop->value());
2816
2817                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2818                         continue;
2819                 }
2820
2821                 if (Glib::path_is_absolute (prop->value())) {
2822                         /* external file, ignore */
2823                         continue;
2824                 }
2825
2826                 string found_path;
2827                 bool is_new;
2828                 uint16_t chan;
2829
2830                 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2831                         result.insert (found_path);
2832                 }
2833         }
2834
2835         return 0;
2836 }
2837
2838 int
2839 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2840 {
2841         vector<string> state_files;
2842         string ripped;
2843         string this_snapshot_path;
2844
2845         result.clear ();
2846
2847         ripped = _path;
2848
2849         if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2850                 ripped = ripped.substr (0, ripped.length() - 1);
2851         }
2852
2853         find_files_matching_filter (state_files, ripped, accept_all_state_files, (void *) 0, true, true);
2854
2855         if (state_files.empty()) {
2856                 /* impossible! */
2857                 return 0;
2858         }
2859
2860         this_snapshot_path = _path;
2861         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2862         this_snapshot_path += statefile_suffix;
2863
2864         for (vector<string>::iterator i = state_files.begin(); i != state_files.end(); ++i) {
2865
2866                 if (exclude_this_snapshot && *i == this_snapshot_path) {
2867                         continue;
2868                 }
2869
2870                 if (find_all_sources (*i, result) < 0) {
2871                         return -1;
2872                 }
2873         }
2874
2875         return 0;
2876 }
2877
2878 struct RegionCounter {
2879     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2880     AudioSourceList::iterator iter;
2881     boost::shared_ptr<Region> region;
2882     uint32_t count;
2883
2884     RegionCounter() : count (0) {}
2885 };
2886
2887 int
2888 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2889 {
2890         boost::optional<int> r = AskAboutPlaylistDeletion (p);
2891         return r.get_value_or (1);
2892 }
2893
2894 void
2895 Session::cleanup_regions ()
2896 {
2897         bool removed = false;
2898         const RegionFactory::RegionMap& regions (RegionFactory::regions());
2899
2900         for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
2901
2902                 uint32_t used = playlists->region_use_count (i->second);
2903
2904                 if (used == 0 && !i->second->automatic ()) {
2905                         boost::weak_ptr<Region> w = i->second;
2906                         ++i;
2907                         removed = true;
2908                         RegionFactory::map_remove (w);
2909                 } else {
2910                         ++i;
2911                 }
2912         }
2913
2914         if (removed) {
2915                 // re-check to remove parent references of compound regions
2916                 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end();) {
2917                         if (!(i->second->whole_file() && i->second->max_source_level() > 0)) {
2918                                 ++i;
2919                                 continue;
2920                         }
2921                         assert(boost::dynamic_pointer_cast<PlaylistSource>(i->second->source (0)) != 0);
2922                         if (0 == playlists->region_use_count (i->second)) {
2923                                 boost::weak_ptr<Region> w = i->second;
2924                                 ++i;
2925                                 RegionFactory::map_remove (w);
2926                         } else {
2927                                 ++i;
2928                         }
2929                 }
2930         }
2931
2932         /* dump the history list */
2933         _history.clear ();
2934
2935         save_state ("");
2936 }
2937
2938 bool
2939 Session::can_cleanup_peakfiles () const
2940 {
2941         if (deletion_in_progress()) {
2942                 return false;
2943         }
2944         if (!_writable || (_state_of_the_state & CannotSave)) {
2945                 warning << _("Cannot cleanup peak-files for read-only session.") << endmsg;
2946                 return false;
2947         }
2948         if (record_status() == Recording) {
2949                 error << _("Cannot cleanup peak-files while recording") << endmsg;
2950                 return false;
2951         }
2952         return true;
2953 }
2954
2955 int
2956 Session::cleanup_peakfiles ()
2957 {
2958         Glib::Threads::Mutex::Lock lm (peak_cleanup_lock, Glib::Threads::TRY_LOCK);
2959         if (!lm.locked()) {
2960                 return -1;
2961         }
2962
2963         assert (can_cleanup_peakfiles ());
2964         assert (!peaks_cleanup_in_progres());
2965
2966         _state_of_the_state = StateOfTheState (_state_of_the_state | PeakCleanup);
2967
2968         int timeout = 5000; // 5 seconds
2969         while (!SourceFactory::files_with_peaks.empty()) {
2970                 Glib::usleep (1000);
2971                 if (--timeout < 0) {
2972                         warning << _("Timeout waiting for peak-file creation to terminate before cleanup, please try again later.") << endmsg;
2973                         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
2974                         return -1;
2975                 }
2976         }
2977
2978         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2979                 boost::shared_ptr<AudioSource> as;
2980                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
2981                         as->close_peakfile();
2982                 }
2983         }
2984
2985         PBD::clear_directory (session_directory().peak_path());
2986
2987         _state_of_the_state = StateOfTheState (_state_of_the_state & (~PeakCleanup));
2988
2989         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2990                 boost::shared_ptr<AudioSource> as;
2991                 if ((as = boost::dynamic_pointer_cast<AudioSource> (i->second)) != 0) {
2992                         SourceFactory::setup_peakfile(as, true);
2993                 }
2994         }
2995         return 0;
2996 }
2997
2998 int
2999 Session::cleanup_sources (CleanupReport& rep)
3000 {
3001         // FIXME: needs adaptation to midi
3002
3003         vector<boost::shared_ptr<Source> > dead_sources;
3004         string audio_path;
3005         string midi_path;
3006         vector<string> candidates;
3007         vector<string> unused;
3008         set<string> all_sources;
3009         bool used;
3010         string spath;
3011         int ret = -1;
3012         string tmppath1;
3013         string tmppath2;
3014         Searchpath asp;
3015         Searchpath msp;
3016
3017         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
3018
3019         /* this is mostly for windows which doesn't allow file
3020          * renaming if the file is in use. But we don't special
3021          * case it because we need to know if this causes
3022          * problems, and the easiest way to notice that is to
3023          * keep it in place for all platforms.
3024          */
3025
3026         request_stop (false);
3027         _butler->summon ();
3028         _butler->wait_until_finished ();
3029
3030         /* consider deleting all unused playlists */
3031
3032         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
3033                 ret = 0;
3034                 goto out;
3035         }
3036
3037         /* sync the "all regions" property of each playlist with its current state
3038          */
3039
3040         playlists->sync_all_regions_with_regions ();
3041
3042         /* find all un-used sources */
3043
3044         rep.paths.clear ();
3045         rep.space = 0;
3046
3047         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3048
3049                 SourceMap::iterator tmp;
3050
3051                 tmp = i;
3052                 ++tmp;
3053
3054                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
3055                    capture files.
3056                 */
3057
3058                 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
3059                         dead_sources.push_back (i->second);
3060                         i->second->drop_references ();
3061                 }
3062
3063                 i = tmp;
3064         }
3065
3066         /* build a list of all the possible audio directories for the session */
3067
3068         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3069                 SessionDirectory sdir ((*i).path);
3070                 asp += sdir.sound_path();
3071         }
3072         audio_path += asp.to_string();
3073
3074
3075         /* build a list of all the possible midi directories for the session */
3076
3077         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3078                 SessionDirectory sdir ((*i).path);
3079                 msp += sdir.midi_path();
3080         }
3081         midi_path += msp.to_string();
3082
3083         find_files_matching_filter (candidates, audio_path, accept_all_audio_files, (void *) 0, true, true);
3084         find_files_matching_filter (candidates, midi_path, accept_all_midi_files, (void *) 0, true, true);
3085
3086         /* find all sources, but don't use this snapshot because the
3087            state file on disk still references sources we may have already
3088            dropped.
3089         */
3090
3091         find_all_sources_across_snapshots (all_sources, true);
3092
3093         /*  add our current source list
3094          */
3095
3096         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
3097                 boost::shared_ptr<FileSource> fs;
3098                 SourceMap::iterator tmp = i;
3099                 ++tmp;
3100
3101                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
3102
3103                         /* this is mostly for windows which doesn't allow file
3104                          * renaming if the file is in use. But we don't special
3105                          * case it because we need to know if this causes
3106                          * problems, and the easiest way to notice that is to
3107                          * keep it in place for all platforms.
3108                          */
3109
3110                         fs->close ();
3111
3112                         if (!fs->is_stub()) {
3113
3114                                 if (playlists->source_use_count (fs) != 0) {
3115                                         all_sources.insert (fs->path());
3116                                 } else {
3117
3118                                         /* we might not remove this source from disk, because it may be used
3119                                            by other snapshots, but its not being used in this version
3120                                            so lets get rid of it now, along with any representative regions
3121                                            in the region list.
3122                                         */
3123
3124                                         RegionFactory::remove_regions_using_source (i->second);
3125
3126                                         // also remove source from all_sources
3127
3128                                         for (set<string>::iterator j = all_sources.begin(); j != all_sources.end(); ++j) {
3129                                                 spath = Glib::path_get_basename (*j);
3130                                                 if (spath == i->second->name()) {
3131                                                         all_sources.erase (j);
3132                                                         break;
3133                                                 }
3134                                         }
3135
3136                                         sources.erase (i);
3137                                 }
3138                         }
3139                 }
3140
3141                 i = tmp;
3142         }
3143
3144         for (vector<string>::iterator x = candidates.begin(); x != candidates.end(); ++x) {
3145
3146                 used = false;
3147                 spath = *x;
3148
3149                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3150
3151                         tmppath1 = canonical_path (spath);
3152                         tmppath2 = canonical_path ((*i));
3153
3154                         if (tmppath1 == tmppath2) {
3155                                 used = true;
3156                                 break;
3157                         }
3158                 }
3159
3160                 if (!used) {
3161                         unused.push_back (spath);
3162                 }
3163         }
3164
3165         /* now try to move all unused files into the "dead" directory(ies) */
3166
3167         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3168                 GStatBuf statbuf;
3169
3170                 string newpath;
3171
3172                 /* don't move the file across filesystems, just
3173                    stick it in the `dead_dir_name' directory
3174                    on whichever filesystem it was already on.
3175                 */
3176
3177                 if ((*x).find ("/sounds/") != string::npos) {
3178
3179                         /* old school, go up 1 level */
3180
3181                         newpath = Glib::path_get_dirname (*x);      // "sounds"
3182                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3183
3184                 } else {
3185
3186                         /* new school, go up 4 levels */
3187
3188                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" or "midifiles"
3189                         newpath = Glib::path_get_dirname (newpath); // "session-name"
3190                         newpath = Glib::path_get_dirname (newpath); // "interchange"
3191                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
3192                 }
3193
3194                 newpath = Glib::build_filename (newpath, dead_dir_name);
3195
3196                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
3197                         error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
3198                         return -1;
3199                 }
3200
3201                 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
3202
3203                 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
3204
3205                         /* the new path already exists, try versioning */
3206
3207                         char buf[PATH_MAX+1];
3208                         int version = 1;
3209                         string newpath_v;
3210
3211                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3212                         newpath_v = buf;
3213
3214                         while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
3215                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3216                                 newpath_v = buf;
3217                         }
3218
3219                         if (version == 999) {
3220                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3221                                                   newpath)
3222                                       << endmsg;
3223                         } else {
3224                                 newpath = newpath_v;
3225                         }
3226
3227                 } else {
3228
3229                         /* it doesn't exist, or we can't read it or something */
3230
3231                 }
3232
3233                 g_stat ((*x).c_str(), &statbuf);
3234
3235                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3236                         error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
3237                                           (*x), newpath, strerror (errno))
3238                               << endmsg;
3239                         goto out;
3240                 }
3241
3242                 /* see if there an easy to find peakfile for this file, and remove it.
3243                  */
3244
3245                 string base = Glib::path_get_basename (*x);
3246                 base += "%A"; /* this is what we add for the channel suffix of all native files,
3247                                  or for the first channel of embedded files. it will miss
3248                                  some peakfiles for other channels
3249                               */
3250                 string peakpath = construct_peak_filepath (base);
3251
3252                 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
3253                         if (::g_unlink (peakpath.c_str()) != 0) {
3254                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3255                                                          peakpath, _path, strerror (errno))
3256                                       << endmsg;
3257                                 /* try to back out */
3258                                 ::rename (newpath.c_str(), _path.c_str());
3259                                 goto out;
3260                         }
3261                 }
3262
3263                 rep.paths.push_back (*x);
3264                 rep.space += statbuf.st_size;
3265         }
3266
3267         /* dump the history list */
3268
3269         _history.clear ();
3270
3271         /* save state so we don't end up a session file
3272            referring to non-existent sources.
3273         */
3274
3275         save_state ("");
3276         ret = 0;
3277
3278   out:
3279         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3280
3281         return ret;
3282 }
3283
3284 int
3285 Session::cleanup_trash_sources (CleanupReport& rep)
3286 {
3287         // FIXME: needs adaptation for MIDI
3288
3289         vector<space_and_path>::iterator i;
3290         string dead_dir;
3291
3292         rep.paths.clear ();
3293         rep.space = 0;
3294
3295         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3296
3297                 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3298
3299                 clear_directory (dead_dir, &rep.space, &rep.paths);
3300         }
3301
3302         return 0;
3303 }
3304
3305 void
3306 Session::set_dirty ()
3307 {
3308         /* never mark session dirty during loading */
3309
3310         if (_state_of_the_state & Loading) {
3311                 return;
3312         }
3313
3314         bool was_dirty = dirty();
3315
3316         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3317
3318
3319         if (!was_dirty) {
3320                 DirtyChanged(); /* EMIT SIGNAL */
3321         }
3322 }
3323
3324
3325 void
3326 Session::set_clean ()
3327 {
3328         bool was_dirty = dirty();
3329
3330         _state_of_the_state = Clean;
3331
3332
3333         if (was_dirty) {
3334                 DirtyChanged(); /* EMIT SIGNAL */
3335         }
3336 }
3337
3338 void
3339 Session::set_deletion_in_progress ()
3340 {
3341         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3342 }
3343
3344 void
3345 Session::clear_deletion_in_progress ()
3346 {
3347         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3348 }
3349
3350 void
3351 Session::add_controllable (boost::shared_ptr<Controllable> c)
3352 {
3353         /* this adds a controllable to the list managed by the Session.
3354            this is a subset of those managed by the Controllable class
3355            itself, and represents the only ones whose state will be saved
3356            as part of the session.
3357         */
3358
3359         Glib::Threads::Mutex::Lock lm (controllables_lock);
3360         controllables.insert (c);
3361 }
3362
3363 struct null_deleter { void operator()(void const *) const {} };
3364
3365 void
3366 Session::remove_controllable (Controllable* c)
3367 {
3368         if (_state_of_the_state & Deletion) {
3369                 return;
3370         }
3371
3372         Glib::Threads::Mutex::Lock lm (controllables_lock);
3373
3374         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3375
3376         if (x != controllables.end()) {
3377                 controllables.erase (x);
3378         }
3379 }
3380
3381 boost::shared_ptr<Controllable>
3382 Session::controllable_by_id (const PBD::ID& id)
3383 {
3384         Glib::Threads::Mutex::Lock lm (controllables_lock);
3385
3386         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3387                 if ((*i)->id() == id) {
3388                         return *i;
3389                 }
3390         }
3391
3392         return boost::shared_ptr<Controllable>();
3393 }
3394
3395 boost::shared_ptr<Controllable>
3396 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3397 {
3398         boost::shared_ptr<Controllable> c;
3399         boost::shared_ptr<Route> r;
3400
3401         switch (desc.top_level_type()) {
3402         case ControllableDescriptor::NamedRoute:
3403         {
3404                 std::string str = desc.top_level_name();
3405                 if (str == "Master" || str == "master") {
3406                         r = _master_out;
3407                 } else if (str == "control" || str == "listen") {
3408                         r = _monitor_out;
3409                 } else {
3410                         r = route_by_name (desc.top_level_name());
3411                 }
3412                 break;
3413         }
3414
3415         case ControllableDescriptor::RemoteControlID:
3416                 r = get_remote_nth_route (desc.rid());
3417                 break;
3418
3419         case ControllableDescriptor::SelectionCount:
3420                 r = route_by_selected_count (desc.selection_id());
3421                 break;
3422         }
3423
3424         if (!r) {
3425                 return c;
3426         }
3427
3428         switch (desc.subtype()) {
3429         case ControllableDescriptor::Gain:
3430                 c = r->gain_control ();
3431                 break;
3432
3433         case ControllableDescriptor::Trim:
3434                 c = r->trim()->gain_control ();
3435                 break;
3436
3437         case ControllableDescriptor::Solo:
3438                 c = r->solo_control();
3439                 break;
3440
3441         case ControllableDescriptor::Mute:
3442                 c = r->mute_control();
3443                 break;
3444
3445         case ControllableDescriptor::Recenable:
3446         {
3447                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3448
3449                 if (t) {
3450                         c = t->rec_enable_control ();
3451                 }
3452                 break;
3453         }
3454
3455         case ControllableDescriptor::PanDirection:
3456                 c = r->pan_azimuth_control();
3457                 break;
3458
3459         case ControllableDescriptor::PanWidth:
3460                 c = r->pan_width_control();
3461                 break;
3462
3463         case ControllableDescriptor::PanElevation:
3464                 c = r->pan_elevation_control();
3465                 break;
3466
3467         case ControllableDescriptor::Balance:
3468                 /* XXX simple pan control */
3469                 break;
3470
3471         case ControllableDescriptor::PluginParameter:
3472         {
3473                 uint32_t plugin = desc.target (0);
3474                 uint32_t parameter_index = desc.target (1);
3475
3476                 /* revert to zero based counting */
3477
3478                 if (plugin > 0) {
3479                         --plugin;
3480                 }
3481
3482                 if (parameter_index > 0) {
3483                         --parameter_index;
3484                 }
3485
3486                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3487
3488                 if (p) {
3489                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3490                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3491                 }
3492                 break;
3493         }
3494
3495         case ControllableDescriptor::SendGain: {
3496                 uint32_t send = desc.target (0);
3497                 if (send > 0) {
3498                         --send;
3499                 }
3500                 c = r->send_level_controllable (send);
3501                 break;
3502         }
3503
3504         default:
3505                 /* relax and return a null pointer */
3506                 break;
3507         }
3508
3509         return c;
3510 }
3511
3512 void
3513 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3514 {
3515         if (_writable) {
3516                 Stateful::add_instant_xml (node, _path);
3517         }
3518
3519         if (write_to_config) {
3520                 Config->add_instant_xml (node);
3521         }
3522 }
3523
3524 XMLNode*
3525 Session::instant_xml (const string& node_name)
3526 {
3527         return Stateful::instant_xml (node_name, _path);
3528 }
3529
3530 int
3531 Session::save_history (string snapshot_name)
3532 {
3533         XMLTree tree;
3534
3535         if (!_writable) {
3536                 return 0;
3537         }
3538
3539         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0 ||
3540             (_history.undo_depth() == 0 && _history.redo_depth() == 0)) {
3541                 return 0;
3542         }
3543
3544         if (snapshot_name.empty()) {
3545                 snapshot_name = _current_snapshot_name;
3546         }
3547
3548         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3549         const string backup_filename = history_filename + backup_suffix;
3550         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3551         const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3552
3553         if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3554                 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3555                         error << _("could not backup old history file, current history not saved") << endmsg;
3556                         return -1;
3557                 }
3558         }
3559
3560         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3561
3562         if (!tree.write (xml_path))
3563         {
3564                 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3565
3566                 if (g_remove (xml_path.c_str()) != 0) {
3567                         error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3568                                         xml_path, g_strerror (errno)) << endmsg;
3569                 }
3570                 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3571                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
3572                                         backup_path, g_strerror (errno)) << endmsg;
3573                 }
3574
3575                 return -1;
3576         }
3577
3578         return 0;
3579 }
3580
3581 int
3582 Session::restore_history (string snapshot_name)
3583 {
3584         XMLTree tree;
3585
3586         if (snapshot_name.empty()) {
3587                 snapshot_name = _current_snapshot_name;
3588         }
3589
3590         const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3591         const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3592
3593         info << "Loading history from " << xml_path << endmsg;
3594
3595         if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3596                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3597                                 _name, xml_path) << endmsg;
3598                 return 1;
3599         }
3600
3601         if (!tree.read (xml_path)) {
3602                 error << string_compose (_("Could not understand session history file \"%1\""),
3603                                 xml_path) << endmsg;
3604                 return -1;
3605         }
3606
3607         // replace history
3608         _history.clear();
3609
3610         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3611
3612                 XMLNode *t = *it;
3613                 UndoTransaction* ut = new UndoTransaction ();
3614                 struct timeval tv;
3615
3616                 ut->set_name(t->property("name")->value());
3617                 stringstream ss(t->property("tv-sec")->value());
3618                 ss >> tv.tv_sec;
3619                 ss.str(t->property("tv-usec")->value());
3620                 ss >> tv.tv_usec;
3621                 ut->set_timestamp(tv);
3622
3623                 for (XMLNodeConstIterator child_it  = t->children().begin();
3624                                 child_it != t->children().end(); child_it++)
3625                 {
3626                         XMLNode *n = *child_it;
3627                         Command *c;
3628
3629                         if (n->name() == "MementoCommand" ||
3630                                         n->name() == "MementoUndoCommand" ||
3631                                         n->name() == "MementoRedoCommand") {
3632
3633                                 if ((c = memento_command_factory(n))) {
3634                                         ut->add_command(c);
3635                                 }
3636
3637                         } else if (n->name() == "NoteDiffCommand") {
3638                                 PBD::ID id (n->property("midi-source")->value());
3639                                 boost::shared_ptr<MidiSource> midi_source =
3640                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3641                                 if (midi_source) {
3642                                         ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3643                                 } else {
3644                                         error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3645                                 }
3646
3647                         } else if (n->name() == "SysExDiffCommand") {
3648
3649                                 PBD::ID id (n->property("midi-source")->value());
3650                                 boost::shared_ptr<MidiSource> midi_source =
3651                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3652                                 if (midi_source) {
3653                                         ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3654                                 } else {
3655                                         error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3656                                 }
3657
3658                         } else if (n->name() == "PatchChangeDiffCommand") {
3659
3660                                 PBD::ID id (n->property("midi-source")->value());
3661                                 boost::shared_ptr<MidiSource> midi_source =
3662                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3663                                 if (midi_source) {
3664                                         ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3665                                 } else {
3666                                         error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3667                                 }
3668
3669                         } else if (n->name() == "StatefulDiffCommand") {
3670                                 if ((c = stateful_diff_command_factory (n))) {
3671                                         ut->add_command (c);
3672                                 }
3673                         } else {
3674                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3675                         }
3676                 }
3677
3678                 _history.add (ut);
3679         }
3680
3681         return 0;
3682 }
3683
3684 void
3685 Session::config_changed (std::string p, bool ours)
3686 {
3687         if (ours) {
3688                 set_dirty ();
3689         }
3690
3691         if (p == "seamless-loop") {
3692
3693         } else if (p == "rf-speed") {
3694
3695         } else if (p == "auto-loop") {
3696
3697         } else if (p == "auto-input") {
3698
3699                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3700                         /* auto-input only makes a difference if we're rolling */
3701                         set_track_monitor_input_status (!config.get_auto_input());
3702                 }
3703
3704         } else if (p == "punch-in") {
3705
3706                 Location* location;
3707
3708                 if ((location = _locations->auto_punch_location()) != 0) {
3709
3710                         if (config.get_punch_in ()) {
3711                                 replace_event (SessionEvent::PunchIn, location->start());
3712                         } else {
3713                                 remove_event (location->start(), SessionEvent::PunchIn);
3714                         }
3715                 }
3716
3717         } else if (p == "punch-out") {
3718
3719                 Location* location;
3720
3721                 if ((location = _locations->auto_punch_location()) != 0) {
3722
3723                         if (config.get_punch_out()) {
3724                                 replace_event (SessionEvent::PunchOut, location->end());
3725                         } else {
3726                                 clear_events (SessionEvent::PunchOut);
3727                         }
3728                 }
3729
3730         } else if (p == "edit-mode") {
3731
3732                 Glib::Threads::Mutex::Lock lm (playlists->lock);
3733
3734                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3735                         (*i)->set_edit_mode (Config->get_edit_mode ());
3736                 }
3737
3738         } else if (p == "use-video-sync") {
3739
3740                 waiting_for_sync_offset = config.get_use_video_sync();
3741
3742         } else if (p == "mmc-control") {
3743
3744                 //poke_midi_thread ();
3745
3746         } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3747
3748                 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3749
3750         } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3751
3752                 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3753
3754         } else if (p == "midi-control") {
3755
3756                 //poke_midi_thread ();
3757
3758         } else if (p == "raid-path") {
3759
3760                 setup_raid_path (config.get_raid_path());
3761
3762         } else if (p == "timecode-format") {
3763
3764                 sync_time_vars ();
3765
3766         } else if (p == "video-pullup") {
3767
3768                 sync_time_vars ();
3769
3770         } else if (p == "seamless-loop") {
3771
3772                 if (play_loop && transport_rolling()) {
3773                         // to reset diskstreams etc
3774                         request_play_loop (true);
3775                 }
3776
3777         } else if (p == "rf-speed") {
3778
3779                 cumulative_rf_motion = 0;
3780                 reset_rf_scale (0);
3781
3782         } else if (p == "click-sound") {
3783
3784                 setup_click_sounds (1);
3785
3786         } else if (p == "click-emphasis-sound") {
3787
3788                 setup_click_sounds (-1);
3789
3790         } else if (p == "clicking") {
3791
3792                 if (Config->get_clicking()) {
3793                         if (_click_io && click_data) { // don't require emphasis data
3794                                 _clicking = true;
3795                         }
3796                 } else {
3797                         _clicking = false;
3798                 }
3799
3800         } else if (p == "click-gain") {
3801
3802                 if (_click_gain) {
3803                         _click_gain->gain_control()->set_value (Config->get_click_gain(), Controllable::NoGroup);
3804                 }
3805
3806         } else if (p == "send-mtc") {
3807
3808                 if (Config->get_send_mtc ()) {
3809                         /* mark us ready to send */
3810                         next_quarter_frame_to_send = 0;
3811                 }
3812
3813         } else if (p == "send-mmc") {
3814
3815                 _mmc->enable_send (Config->get_send_mmc ());
3816
3817         } else if (p == "midi-feedback") {
3818
3819                 session_midi_feedback = Config->get_midi_feedback();
3820
3821         } else if (p == "jack-time-master") {
3822
3823                 engine().reset_timebase ();
3824
3825         } else if (p == "native-file-header-format") {
3826
3827                 if (!first_file_header_format_reset) {
3828                         reset_native_file_format ();
3829                 }
3830
3831                 first_file_header_format_reset = false;
3832
3833         } else if (p == "native-file-data-format") {
3834
3835                 if (!first_file_data_format_reset) {
3836                         reset_native_file_format ();
3837                 }
3838
3839                 first_file_data_format_reset = false;
3840
3841         } else if (p == "external-sync") {
3842                 if (!config.get_external_sync()) {
3843                         drop_sync_source ();
3844                 } else {
3845                         switch_to_sync_source (Config->get_sync_source());
3846                 }
3847         }  else if (p == "denormal-model") {
3848                 setup_fpu ();
3849         } else if (p == "history-depth") {
3850                 set_history_depth (Config->get_history_depth());
3851         } else if (p == "remote-model") {
3852                 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3853                    TO SET REMOTE ID'S
3854                 */
3855         } else if (p == "initial-program-change") {
3856
3857                 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3858                         MIDI::byte buf[2];
3859
3860                         buf[0] = MIDI::program; // channel zero by default
3861                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3862
3863                         _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3864                 }
3865         } else if (p == "solo-mute-override") {
3866                 // catch_up_on_solo_mute_override ();
3867         } else if (p == "listen-position" || p == "pfl-position") {
3868                 listen_position_changed ();
3869         } else if (p == "solo-control-is-listen-control") {
3870                 solo_control_mode_changed ();
3871         } else if (p == "solo-mute-gain") {
3872                 _solo_cut_control->Changed (true, Controllable::NoGroup);
3873         } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3874                 last_timecode_valid = false;
3875         } else if (p == "playback-buffer-seconds") {
3876                 AudioSource::allocate_working_buffers (frame_rate());
3877         } else if (p == "ltc-source-port") {
3878                 reconnect_ltc_input ();
3879         } else if (p == "ltc-sink-port") {
3880                 reconnect_ltc_output ();
3881         } else if (p == "timecode-generator-offset") {
3882                 ltc_tx_parse_offset();
3883         } else if (p == "auto-return-target-list") {
3884                 follow_playhead_priority ();
3885         }
3886
3887         set_dirty ();
3888 }
3889
3890 void
3891 Session::set_history_depth (uint32_t d)
3892 {
3893         _history.set_depth (d);
3894 }
3895
3896 int
3897 Session::load_diskstreams_2X (XMLNode const & node, int)
3898 {
3899         XMLNodeList          clist;
3900         XMLNodeConstIterator citer;
3901
3902         clist = node.children();
3903
3904         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3905
3906                 try {
3907                         /* diskstreams added automatically by DiskstreamCreated handler */
3908                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3909                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3910                                 _diskstreams_2X.push_back (dsp);
3911                         } else {
3912                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3913                         }
3914                 }
3915
3916                 catch (failed_constructor& err) {
3917                         error << _("Session: could not load diskstream via XML state") << endmsg;
3918                         return -1;
3919                 }
3920         }
3921
3922         return 0;
3923 }
3924
3925 /** Connect things to the MMC object */
3926 void
3927 Session::setup_midi_machine_control ()
3928 {
3929         _mmc = new MIDI::MachineControl;
3930
3931         boost::shared_ptr<AsyncMIDIPort> async_in = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_input_port());
3932         boost::shared_ptr<AsyncMIDIPort> async_out = boost::dynamic_pointer_cast<AsyncMIDIPort> (_midi_ports->mmc_output_port());
3933
3934         if (!async_out || !async_out) {
3935                 return;
3936         }
3937
3938         /* XXXX argh, passing raw pointers back into libmidi++ */
3939
3940         MIDI::Port* mmc_in = async_in.get();
3941         MIDI::Port* mmc_out = async_out.get();
3942
3943         _mmc->set_ports (mmc_in, mmc_out);
3944
3945         _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3946         _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3947         _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3948         _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3949         _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3950         _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3951         _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3952         _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3953         _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3954         _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3955         _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3956         _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3957         _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3958
3959         /* also handle MIDI SPP because its so common */
3960
3961         _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3962         _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3963         _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3964 }
3965
3966 boost::shared_ptr<Controllable>
3967 Session::solo_cut_control() const
3968 {
3969         /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3970            controls in Ardour that currently get presented to the user in the GUI that require
3971            access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3972
3973            its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3974            it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3975            parameter.
3976         */
3977
3978         return _solo_cut_control;
3979 }
3980
3981 void
3982 Session::save_snapshot_name (const std::string & n)
3983 {
3984         /* assure Stateful::_instant_xml is loaded
3985          * add_instant_xml() only adds to existing data and defaults
3986          * to use an empty Tree otherwise
3987          */
3988         instant_xml ("LastUsedSnapshot");
3989
3990         XMLNode* last_used_snapshot = new XMLNode ("LastUsedSnapshot");
3991         last_used_snapshot->add_property ("name", string(n));
3992         add_instant_xml (*last_used_snapshot, false);
3993 }
3994
3995 void
3996 Session::set_snapshot_name (const std::string & n)
3997 {
3998         _current_snapshot_name = n;
3999         save_snapshot_name (n);
4000 }
4001
4002 int
4003 Session::rename (const std::string& new_name)
4004 {
4005         string legal_name = legalize_for_path (new_name);
4006         string new_path;
4007         string oldstr;
4008         string newstr;
4009         bool first = true;
4010
4011         string const old_sources_root = _session_dir->sources_root();
4012
4013         if (!_writable || (_state_of_the_state & CannotSave)) {
4014                 error << _("Cannot rename read-only session.") << endmsg;
4015                 return 0; // don't show "messed up" warning
4016         }
4017         if (record_status() == Recording) {
4018                 error << _("Cannot rename session while recording") << endmsg;
4019                 return 0; // don't show "messed up" warning
4020         }
4021
4022         StateProtector stp (this);
4023
4024         /* Rename:
4025
4026          * session directory
4027          * interchange subdirectory
4028          * session file
4029          * session history
4030
4031          * Backup files are left unchanged and not renamed.
4032          */
4033
4034         /* Windows requires that we close all files before attempting the
4035          * rename. This works on other platforms, but isn't necessary there.
4036          * Leave it in place for all platforms though, since it may help
4037          * catch issues that could arise if the way Source files work ever
4038          * change (since most developers are not using Windows).
4039          */
4040
4041         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4042                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4043                 if (fs) {
4044                         fs->close ();
4045                 }
4046         }
4047
4048         /* pass one: not 100% safe check that the new directory names don't
4049          * already exist ...
4050          */
4051
4052         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4053
4054                 oldstr = (*i).path;
4055
4056                 /* this is a stupid hack because Glib::path_get_dirname() is
4057                  * lexical-only, and so passing it /a/b/c/ gives a different
4058                  * result than passing it /a/b/c ...
4059                  */
4060
4061                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4062                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4063                 }
4064
4065                 string base = Glib::path_get_dirname (oldstr);
4066
4067                 newstr = Glib::build_filename (base, legal_name);
4068
4069                 cerr << "Looking for " << newstr << endl;
4070
4071                 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
4072                         cerr << " exists\n";
4073                         return -1;
4074                 }
4075         }
4076
4077         /* Session dirs */
4078
4079         first = true;
4080
4081         for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
4082
4083                 vector<string> v;
4084
4085                 oldstr = (*i).path;
4086
4087                 /* this is a stupid hack because Glib::path_get_dirname() is
4088                  * lexical-only, and so passing it /a/b/c/ gives a different
4089                  * result than passing it /a/b/c ...
4090                  */
4091
4092                 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
4093                         oldstr = oldstr.substr (0, oldstr.length() - 1);
4094                 }
4095
4096                 string base = Glib::path_get_dirname (oldstr);
4097                 newstr = Glib::build_filename (base, legal_name);
4098
4099                 cerr << "for " << oldstr << " new dir = " << newstr << endl;
4100
4101                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4102                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4103                         cerr << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4104                         error << string_compose (_("renaming %s as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4105                         return 1;
4106                 }
4107
4108                 /* Reset path in "session dirs" */
4109
4110                 (*i).path = newstr;
4111                 (*i).blocks = 0;
4112
4113                 /* reset primary SessionDirectory object */
4114
4115                 if (first) {
4116                         (*_session_dir) = newstr;
4117                         new_path = newstr;
4118                         first = false;
4119                 }
4120
4121                 /* now rename directory below session_dir/interchange */
4122
4123                 string old_interchange_dir;
4124                 string new_interchange_dir;
4125
4126                 /* use newstr here because we renamed the path
4127                  * (folder/directory) that used to be oldstr to newstr above
4128                  */
4129
4130                 v.push_back (newstr);
4131                 v.push_back (interchange_dir_name);
4132                 v.push_back (Glib::path_get_basename (oldstr));
4133
4134                 old_interchange_dir = Glib::build_filename (v);
4135
4136                 v.clear ();
4137                 v.push_back (newstr);
4138                 v.push_back (interchange_dir_name);
4139                 v.push_back (legal_name);
4140
4141                 new_interchange_dir = Glib::build_filename (v);
4142
4143                 cerr << "Rename " << old_interchange_dir << " => " << new_interchange_dir << endl;
4144
4145                 if (::g_rename (old_interchange_dir.c_str(), new_interchange_dir.c_str()) != 0) {
4146                         cerr << string_compose (_("renaming %s as %2 failed (%3)"),
4147                                                  old_interchange_dir, new_interchange_dir,
4148                                                  g_strerror (errno))
4149                               << endl;
4150                         error << string_compose (_("renaming %s as %2 failed (%3)"),
4151                                                  old_interchange_dir, new_interchange_dir,
4152                                                  g_strerror (errno))
4153                               << endmsg;
4154                         return 1;
4155                 }
4156         }
4157
4158         /* state file */
4159
4160         oldstr = Glib::build_filename (new_path, _current_snapshot_name + statefile_suffix);
4161         newstr= Glib::build_filename (new_path, legal_name + statefile_suffix);
4162
4163         cerr << "Rename " << oldstr << " => " << newstr << endl;
4164
4165         if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4166                 cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4167                 error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4168                 return 1;
4169         }
4170
4171         /* history file */
4172
4173         oldstr = Glib::build_filename (new_path, _current_snapshot_name) + history_suffix;
4174
4175         if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS))  {
4176                 newstr = Glib::build_filename (new_path, legal_name) + history_suffix;
4177
4178                 cerr << "Rename " << oldstr << " => " << newstr << endl;
4179
4180                 if (::g_rename (oldstr.c_str(), newstr.c_str()) != 0) {
4181                         cerr << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endl;
4182                         error << string_compose (_("renaming %1 as %2 failed (%3)"), oldstr, newstr, g_strerror (errno)) << endmsg;
4183                         return 1;
4184                 }
4185         }
4186
4187         /* remove old name from recent sessions */
4188         remove_recent_sessions (_path);
4189         _path = new_path;
4190
4191         /* update file source paths */
4192
4193         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
4194                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4195                 if (fs) {
4196                         string p = fs->path ();
4197                         boost::replace_all (p, old_sources_root, _session_dir->sources_root());
4198                         fs->set_path (p);
4199                         SourceFactory::setup_peakfile(i->second, true);
4200                 }
4201         }
4202
4203         set_snapshot_name (new_name);
4204         _name = new_name;
4205
4206         set_dirty ();
4207
4208         /* save state again to get everything just right */
4209
4210         save_state (_current_snapshot_name);
4211
4212         /* add to recent sessions */
4213
4214         store_recent_sessions (new_name, _path);
4215
4216         return 0;
4217 }
4218
4219 int
4220 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
4221 {
4222         if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
4223                 return -1;
4224         }
4225
4226         if (!tree.read (xmlpath)) {
4227                 return -1;
4228         }
4229
4230         return 0;
4231 }
4232
4233 int
4234 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
4235 {
4236         XMLTree tree;
4237         bool found_sr = false;
4238         bool found_data_format = false;
4239
4240         if (get_session_info_from_path (tree, xmlpath)) {
4241                 return -1;
4242         }
4243
4244         /* sample rate */
4245
4246         XMLProperty const * prop;
4247         XMLNode const * root (tree.root());
4248
4249         if ((prop = root->property (X_("sample-rate"))) != 0) {
4250                 sample_rate = atoi (prop->value());
4251                 found_sr = true;
4252         }
4253
4254         const XMLNodeList& children (root->children());
4255         for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
4256                 const XMLNode* child = *c;
4257                 if (child->name() == "Config") {
4258                         const XMLNodeList& options (child->children());
4259                         for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
4260                                 XMLNode const * option = *oc;
4261                                 XMLProperty const * name = option->property("name");
4262
4263                                 if (!name) {
4264                                         continue;
4265                                 }
4266
4267                                 if (name->value() == "native-file-data-format") {
4268                                         XMLProperty const * value = option->property ("value");
4269                                         if (value) {
4270                                                 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
4271                                                 data_format = fmt;
4272                                                 found_data_format = true;
4273                                                 break;
4274                                         }
4275                                 }
4276                         }
4277                 }
4278                 if (found_data_format) {
4279                         break;
4280                 }
4281         }
4282
4283         return !(found_sr && found_data_format); // zero if they are both found
4284 }
4285
4286 std::string
4287 Session::get_snapshot_from_instant (const std::string& session_dir)
4288 {
4289         std::string instant_xml_path = Glib::build_filename (session_dir, "instant.xml");
4290
4291         if (!Glib::file_test (instant_xml_path, Glib::FILE_TEST_EXISTS)) {
4292                 return "";
4293         }
4294
4295         XMLTree tree;
4296         if (!tree.read (instant_xml_path)) {
4297                 return "";
4298         }
4299
4300         XMLProperty const * prop;
4301         XMLNode *last_used_snapshot = tree.root()->child("LastUsedSnapshot");
4302         if (last_used_snapshot && (prop = last_used_snapshot->property ("name")) != 0) {
4303                 return prop->value();
4304         }
4305
4306         return "";
4307 }
4308
4309 typedef std::vector<boost::shared_ptr<FileSource> > SeveralFileSources;
4310 typedef std::map<std::string,SeveralFileSources> SourcePathMap;
4311
4312 int
4313 Session::bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,string)> callback)
4314 {
4315         uint32_t total = 0;
4316         uint32_t n = 0;
4317         SourcePathMap source_path_map;
4318         string new_path;
4319         boost::shared_ptr<AudioFileSource> afs;
4320         int ret = 0;
4321
4322         {
4323
4324                 Glib::Threads::Mutex::Lock lm (source_lock);
4325
4326                 cerr << " total sources = " << sources.size();
4327
4328                 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4329                         boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4330
4331                         if (!fs) {
4332                                 continue;
4333                         }
4334
4335                         if (fs->within_session()) {
4336                                 continue;
4337                         }
4338
4339                         if (source_path_map.find (fs->path()) != source_path_map.end()) {
4340                                 source_path_map[fs->path()].push_back (fs);
4341                         } else {
4342                                 SeveralFileSources v;
4343                                 v.push_back (fs);
4344                                 source_path_map.insert (make_pair (fs->path(), v));
4345                         }
4346
4347                         total++;
4348                 }
4349
4350                 cerr << " fsources = " << total << endl;
4351
4352                 for (SourcePathMap::iterator i = source_path_map.begin(); i != source_path_map.end(); ++i) {
4353
4354                         /* tell caller where we are */
4355
4356                         string old_path = i->first;
4357
4358                         callback (n, total, old_path);
4359
4360                         cerr << old_path << endl;
4361
4362                         new_path.clear ();
4363
4364                         switch (i->second.front()->type()) {
4365                         case DataType::AUDIO:
4366                                 new_path = new_audio_source_path_for_embedded (old_path);
4367                                 break;
4368
4369                         case DataType::MIDI:
4370                                 /* XXX not implemented yet */
4371                                 break;
4372                         }
4373
4374                         if (new_path.empty()) {
4375                                 continue;
4376                         }
4377
4378                         cerr << "Move " << old_path << " => " << new_path << endl;
4379
4380                         if (!copy_file (old_path, new_path)) {
4381                                 cerr << "failed !\n";
4382                                 ret = -1;
4383                         }
4384
4385                         /* make sure we stop looking in the external
4386                            dir/folder. Remember, this is an all-or-nothing
4387                            operations, it doesn't merge just some files.
4388                         */
4389                         remove_dir_from_search_path (Glib::path_get_dirname (old_path), i->second.front()->type());
4390
4391                         for (SeveralFileSources::iterator f = i->second.begin(); f != i->second.end(); ++f) {
4392                                 (*f)->set_path (new_path);
4393                         }
4394                 }
4395         }
4396
4397         save_state ("", false, false);
4398
4399         return ret;
4400 }
4401
4402 static
4403 bool accept_all_files (string const &, void *)
4404 {
4405         return true;
4406 }
4407
4408 void
4409 Session::save_as_bring_callback (uint32_t,uint32_t,string)
4410 {
4411         /* 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.
4412         */
4413 }
4414
4415 static string
4416 make_new_media_path (string old_path, string new_session_folder, string new_session_path)
4417 {
4418         /* typedir is the "midifiles" or "audiofiles" etc. part of the path. */
4419
4420         string typedir = Glib::path_get_basename (Glib::path_get_dirname (old_path));
4421         vector<string> v;
4422         v.push_back (new_session_folder); /* full path */
4423         v.push_back (interchange_dir_name);
4424         v.push_back (new_session_path);   /* just one directory/folder */
4425         v.push_back (typedir);
4426         v.push_back (Glib::path_get_basename (old_path));
4427
4428         return Glib::build_filename (v);
4429 }
4430
4431 int
4432 Session::save_as (SaveAs& saveas)
4433 {
4434         vector<string> files;
4435         string current_folder = Glib::path_get_dirname (_path);
4436         string new_folder = legalize_for_path (saveas.new_name);
4437         string to_dir = Glib::build_filename (saveas.new_parent_folder, new_folder);
4438         int64_t total_bytes = 0;
4439         int64_t copied = 0;
4440         int64_t cnt = 0;
4441         int64_t all = 0;
4442         int32_t internal_file_cnt = 0;
4443
4444         vector<string> do_not_copy_extensions;
4445         do_not_copy_extensions.push_back (statefile_suffix);
4446         do_not_copy_extensions.push_back (pending_suffix);
4447         do_not_copy_extensions.push_back (backup_suffix);
4448         do_not_copy_extensions.push_back (temp_suffix);
4449         do_not_copy_extensions.push_back (history_suffix);
4450
4451         /* get total size */
4452
4453         for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4454
4455                 /* need to clear this because
4456                  * find_files_matching_filter() is cumulative
4457                  */
4458
4459                 files.clear ();
4460
4461                 find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4462
4463                 all += files.size();
4464
4465                 for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4466                         GStatBuf gsb;
4467                         g_stat ((*i).c_str(), &gsb);
4468                         total_bytes += gsb.st_size;
4469                 }
4470         }
4471
4472         /* save old values so we can switch back if we are not switching to the new session */
4473
4474         string old_path = _path;
4475         string old_name = _name;
4476         string old_snapshot = _current_snapshot_name;
4477         string old_sd = _session_dir->root_path();
4478         vector<string> old_search_path[DataType::num_types];
4479         string old_config_search_path[DataType::num_types];
4480
4481         old_search_path[DataType::AUDIO] = source_search_path (DataType::AUDIO);
4482         old_search_path[DataType::MIDI] = source_search_path (DataType::MIDI);
4483         old_config_search_path[DataType::AUDIO]  = config.get_audio_search_path ();
4484         old_config_search_path[DataType::MIDI]  = config.get_midi_search_path ();
4485
4486         /* switch session directory */
4487
4488         (*_session_dir) = to_dir;
4489
4490         /* create new tree */
4491
4492         if (!_session_dir->create()) {
4493                 saveas.failure_message = string_compose (_("Cannot create new session folder %1"), to_dir);
4494                 return -1;
4495         }
4496
4497         try {
4498                 /* copy all relevant files. Find each location in session_dirs,
4499                  * and copy files from there to target.
4500                  */
4501
4502                 for (vector<space_and_path>::const_iterator sd = session_dirs.begin(); sd != session_dirs.end(); ++sd) {
4503
4504                         /* need to clear this because
4505                          * find_files_matching_filter() is cumulative
4506                          */
4507
4508                         files.clear ();
4509
4510                         const size_t prefix_len = (*sd).path.size();
4511
4512                         /* Work just on the files within this session dir */
4513
4514                         find_files_matching_filter (files, (*sd).path, accept_all_files, 0, false, true, true);
4515
4516                         /* add dir separator to protect against collisions with
4517                          * track names (e.g. track named "audiofiles" or
4518                          * "analysis".
4519                          */
4520
4521                         static const std::string audiofile_dir_string = string (sound_dir_name) + G_DIR_SEPARATOR;
4522                         static const std::string midifile_dir_string = string (midi_dir_name) + G_DIR_SEPARATOR;
4523                         static const std::string analysis_dir_string = analysis_dir() + G_DIR_SEPARATOR;
4524
4525                         /* copy all the files. Handling is different for media files
4526                            than others because of the *silly* subtree we have below the interchange
4527                            folder. That really was a bad idea, but I'm not fixing it as part of
4528                            implementing ::save_as().
4529                         */
4530
4531                         for (vector<string>::iterator i = files.begin(); i != files.end(); ++i) {
4532
4533                                 std::string from = *i;
4534
4535 #ifdef __APPLE__
4536                                 string filename = Glib::path_get_basename (from);
4537                                 std::transform (filename.begin(), filename.end(), filename.begin(), ::toupper);
4538                                 if (filename == ".DS_STORE") {
4539                                         continue;
4540                                 }
4541 #endif
4542
4543                                 if (from.find (audiofile_dir_string) != string::npos) {
4544
4545                                         /* audio file: only copy if asked */
4546
4547                                         if (saveas.include_media && saveas.copy_media) {
4548
4549                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4550
4551                                                 info << "media file copying from " << from << " to " << to << endmsg;
4552
4553                                                 if (!copy_file (from, to)) {
4554                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4555                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4556                                                 }
4557                                         }
4558
4559                                         /* we found media files inside the session folder */
4560
4561                                         internal_file_cnt++;
4562
4563                                 } else if (from.find (midifile_dir_string) != string::npos) {
4564
4565                                         /* midi file: always copy unless
4566                                          * creating an empty new session
4567                                          */
4568
4569                                         if (saveas.include_media) {
4570
4571                                                 string to = make_new_media_path (*i, to_dir, new_folder);
4572
4573                                                 info << "media file copying from " << from << " to " << to << endmsg;
4574
4575                                                 if (!copy_file (from, to)) {
4576                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "copy failed");
4577                                                 }
4578                                         }
4579
4580                                         /* we found media files inside the session folder */
4581
4582                                         internal_file_cnt++;
4583
4584                                 } else if (from.find (analysis_dir_string) != string::npos) {
4585
4586                                         /*  make sure analysis dir exists in
4587                                          *  new session folder, but we're not
4588                                          *  copying analysis files here, see
4589                                          *  below
4590                                          */
4591
4592                                         (void) g_mkdir_with_parents (analysis_dir().c_str(), 775);
4593                                         continue;
4594
4595                                 } else {
4596
4597                                         /* normal non-media file. Don't copy state, history, etc.
4598                                          */
4599
4600                                         bool do_copy = true;
4601
4602                                         for (vector<string>::iterator v = do_not_copy_extensions.begin(); v != do_not_copy_extensions.end(); ++v) {
4603                                                 if ((from.length() > (*v).length()) && (from.find (*v) == from.length() - (*v).length())) {
4604                                                         /* end of filename matches extension, do not copy file */
4605                                                         do_copy = false;
4606                                                         break;
4607                                                 }
4608                                         }
4609
4610                                         if (!saveas.copy_media && from.find (peakfile_suffix) != string::npos) {
4611                                                 /* don't copy peakfiles if
4612                                                  * we're not copying media
4613                                                  */
4614                                                 do_copy = false;
4615                                         }
4616
4617                                         if (do_copy) {
4618                                                 string to = Glib::build_filename (to_dir, from.substr (prefix_len));
4619
4620                                                 info << "attempting to make directory/folder " << to << endmsg;
4621
4622                                                 if (g_mkdir_with_parents (Glib::path_get_dirname (to).c_str(), 0755)) {
4623                                                         throw Glib::FileError (Glib::FileError::IO_ERROR, "cannot create required directory");
4624                                                 }
4625
4626                                                 info << "attempting to copy " << from << " to " << to << endmsg;
4627
4628                                                 if (!copy_file (from, to)) {
4629                                                         throw Glib::FileError (Glib::FileError::IO_ERROR,
4630                                                                                                    string_compose(_("\ncopying \"%1\" failed !"), from));
4631                                                 }
4632                                         }
4633                                 }
4634
4635                                 /* measure file size even if we're not going to copy so that our Progress
4636                                    signals are correct, since we included these do-not-copy files
4637                                    in the computation of the total size and file count.
4638                                 */
4639
4640                                 GStatBuf gsb;
4641                                 g_stat (from.c_str(), &gsb);
4642                                 copied += gsb.st_size;
4643                                 cnt++;
4644
4645                                 double fraction = (double) copied / total_bytes;
4646
4647                                 bool keep_going = true;
4648
4649                                 if (saveas.copy_media) {
4650
4651                                         /* no need or expectation of this if
4652                                          * media is not being copied, because
4653                                          * it will be fast(ish).
4654                                          */
4655
4656                                         /* tell someone "X percent, file M of N"; M is one-based */
4657
4658                                         boost::optional<bool> res = saveas.Progress (fraction, cnt, all);
4659
4660                                         if (res) {
4661                                                 keep_going = *res;
4662                                         }
4663                                 }
4664
4665                                 if (!keep_going) {
4666                                         throw Glib::FileError (Glib::FileError::FAILED, "copy cancelled");
4667                                 }
4668                         }
4669
4670                 }
4671
4672                 /* copy optional folders, if any */
4673
4674                 string old = plugins_dir ();
4675                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4676                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4677                         copy_files (old, newdir);
4678                 }
4679
4680                 old = externals_dir ();
4681                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4682                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4683                         copy_files (old, newdir);
4684                 }
4685
4686                 old = automation_dir ();
4687                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4688                         string newdir = Glib::build_filename (to_dir, Glib::path_get_basename (old));
4689                         copy_files (old, newdir);
4690                 }
4691
4692                 if (saveas.include_media) {
4693
4694                         if (saveas.copy_media) {
4695 #ifndef PLATFORM_WINDOWS
4696                                 /* There are problems with analysis files on
4697                                  * Windows, because they used a colon in their
4698                                  * names as late as 4.0. Colons are not legal
4699                                  * under Windows even if NTFS allows them.
4700                                  *
4701                                  * This is a tricky problem to solve so for
4702                                  * just don't copy these files. They will be
4703                                  * regenerated as-needed anyway, subject to the
4704                                  * existing issue that the filenames will be
4705                                  * rejected by Windows, which is a separate
4706                                  * problem (though related).
4707                                  */
4708
4709                                 /* only needed if we are copying media, since the
4710                                  * analysis data refers to media data
4711                                  */
4712
4713                                 old = analysis_dir ();
4714                                 if (Glib::file_test (old, Glib::FILE_TEST_EXISTS)) {
4715                                         string newdir = Glib::build_filename (to_dir, "analysis");
4716                                         copy_files (old, newdir);
4717                                 }
4718 #endif /* PLATFORM_WINDOWS */
4719                         }
4720                 }
4721
4722
4723                 _path = to_dir;
4724                 set_snapshot_name (saveas.new_name);
4725                 _name = saveas.new_name;
4726
4727                 if (saveas.include_media && !saveas.copy_media) {
4728
4729                         /* reset search paths of the new session (which we're pretending to be right now) to
4730                            include the original session search path, so we can still find all audio.
4731                         */
4732
4733                         if (internal_file_cnt) {
4734                                 for (vector<string>::iterator s = old_search_path[DataType::AUDIO].begin(); s != old_search_path[DataType::AUDIO].end(); ++s) {
4735                                         ensure_search_path_includes (*s, DataType::AUDIO);
4736                                         cerr << "be sure to include " << *s << "  for audio" << endl;
4737                                 }
4738
4739                                 /* we do not do this for MIDI because we copy
4740                                    all MIDI files if saveas.include_media is
4741                                    true
4742                                 */
4743                         }
4744                 }
4745
4746                 bool was_dirty = dirty ();
4747
4748                 save_state ("", false, false, !saveas.include_media);
4749                 save_default_options ();
4750
4751                 if (saveas.copy_media && saveas.copy_external) {
4752                         if (bring_all_sources_into_session (boost::bind (&Session::save_as_bring_callback, this, _1, _2, _3))) {
4753                                 throw Glib::FileError (Glib::FileError::NO_SPACE_LEFT, "consolidate failed");
4754                         }
4755                 }
4756
4757                 saveas.final_session_folder_name = _path;
4758
4759                 store_recent_sessions (_name, _path);
4760
4761                 if (!saveas.switch_to) {
4762
4763                         /* switch back to the way things were */
4764
4765                         _path = old_path;
4766                         _name = old_name;
4767                         set_snapshot_name (old_snapshot);
4768
4769                         (*_session_dir) = old_sd;
4770
4771                         if (was_dirty) {
4772                                 set_dirty ();
4773                         }
4774
4775                         if (internal_file_cnt) {
4776                                 /* reset these to their original values */
4777                                 config.set_audio_search_path (old_config_search_path[DataType::AUDIO]);
4778                                 config.set_midi_search_path (old_config_search_path[DataType::MIDI]);
4779                         }
4780
4781                 } else {
4782
4783                         /* prune session dirs, and update disk space statistics
4784                          */
4785
4786                         space_and_path sp;
4787                         sp.path = _path;
4788                         session_dirs.clear ();
4789                         session_dirs.push_back (sp);
4790                         refresh_disk_space ();
4791
4792                         /* ensure that all existing tracks reset their current capture source paths
4793                          */
4794                         reset_write_sources (true, true);
4795
4796                         /* the copying above was based on actually discovering files, not just iterating over the sources list.
4797                            But if we're going to switch to the new (copied) session, we need to change the paths in the sources also.
4798                         */
4799
4800                         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
4801                                 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
4802
4803                                 if (!fs) {
4804                                         continue;
4805                                 }
4806
4807                                 if (fs->within_session()) {
4808                                         string newpath = make_new_media_path (fs->path(), to_dir, new_folder);
4809                                         fs->set_path (newpath);
4810                                 }
4811                         }
4812                 }
4813
4814         } catch (Glib::FileError& e) {
4815
4816                 saveas.failure_message = e.what();
4817
4818                 /* recursively remove all the directories */
4819
4820                 remove_directory (to_dir);
4821
4822                 /* return error */
4823
4824                 return -1;
4825
4826         } catch (...) {
4827
4828                 saveas.failure_message = _("unknown reason");
4829
4830                 /* recursively remove all the directories */
4831
4832                 remove_directory (to_dir);
4833
4834                 /* return error */
4835
4836                 return -1;
4837         }
4838
4839         return 0;
4840 }