2739302140ccc693643eaf5aa911dfd376369ef8
[ardour.git] / libs / ardour / session_state.cc
1 /*
2   Copyright (C) 1999-2002 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 #define __STDC_FORMAT_MACROS 1
26 #include <stdint.h>
27
28 #include <algorithm>
29 #include <fstream>
30 #include <string>
31 #include <cerrno>
32
33
34 #include <cstdio> /* snprintf(3) ... grrr */
35 #include <cmath>
36 #include <unistd.h>
37 #include <sys/stat.h>
38 #include <climits>
39 #include <fcntl.h>
40 #include <poll.h>
41 #include <signal.h>
42 #include <sys/mman.h>
43 #include <sys/time.h>
44 #include <dirent.h>
45
46 #ifdef HAVE_SYS_VFS_H
47 #include <sys/vfs.h>
48 #else
49 #include <sys/param.h>
50 #include <sys/mount.h>
51 #endif
52
53 #include <glibmm.h>
54 #include <glibmm/thread.h>
55
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
68
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
118
119 #include "control_protocol/control_protocol.h"
120
121 #include "i18n.h"
122 #include <locale.h>
123
124 using namespace std;
125 using namespace ARDOUR;
126 using namespace PBD;
127
128 void
129 Session::first_stage_init (string fullpath, string snapshot_name)
130 {
131         if (fullpath.length() == 0) {
132                 destroy ();
133                 throw failed_constructor();
134         }
135
136         char buf[PATH_MAX+1];
137         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
139                 destroy ();
140                 throw failed_constructor();
141         }
142
143         _path = string(buf);
144
145         if (_path[_path.length()-1] != '/') {
146                 _path += '/';
147         }
148
149         if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
150                 _writable = false;
151         } else {
152                 _writable = true;
153         }
154
155         /* these two are just provisional settings. set_state()
156            will likely override them.
157         */
158
159         _name = _current_snapshot_name = snapshot_name;
160
161         set_history_depth (Config->get_history_depth());
162
163         _current_frame_rate = _engine.frame_rate ();
164         _nominal_frame_rate = _current_frame_rate;
165         _base_frame_rate = _current_frame_rate;
166
167         _tempo_map = new TempoMap (_current_frame_rate);
168         _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
169
170
171         _non_soloed_outs_muted = false;
172         _listen_cnt = 0;
173         _solo_isolated_cnt = 0;
174         g_atomic_int_set (&processing_prohibited, 0);
175         _transport_speed = 0;
176         _last_transport_speed = 0;
177         _target_transport_speed = 0;
178         auto_play_legal = false;
179         transport_sub_state = 0;
180         _transport_frame = 0;
181         _requested_return_frame = -1;
182         _session_range_location = 0;
183         g_atomic_int_set (&_record_status, Disabled);
184         loop_changing = false;
185         play_loop = false;
186         have_looped = false;
187         _last_roll_location = 0;
188         _last_roll_or_reversal_location = 0;
189         _last_record_location = 0;
190         pending_locate_frame = 0;
191         pending_locate_roll = false;
192         pending_locate_flush = false;
193         state_was_pending = false;
194         set_next_event ();
195         outbound_mtc_timecode_frame = 0;
196         next_quarter_frame_to_send = -1;
197         current_block_size = 0;
198         solo_update_disabled = false;
199         _have_captured = false;
200         _worst_output_latency = 0;
201         _worst_input_latency = 0;
202         _worst_track_latency = 0;
203         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204         _was_seamless = Config->get_seamless_loop ();
205         _slave = 0;
206         session_send_mmc = false;
207         session_send_mtc = false;
208         g_atomic_int_set (&_playback_load, 100);
209         g_atomic_int_set (&_capture_load, 100);
210         _play_range = false;
211         _exporting = false;
212         pending_abort = false;
213         destructive_index = 0;
214         first_file_data_format_reset = true;
215         first_file_header_format_reset = true;
216         post_export_sync = false;
217         midi_control_ui = 0;
218
219         AudioDiskstream::allocate_working_buffers();
220
221         /* default short fade = 15ms */
222
223         Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
224         SndFileSource::setup_standard_crossfades (*this, frame_rate());
225
226         last_mmc_step.tv_sec = 0;
227         last_mmc_step.tv_usec = 0;
228         step_speed = 0.0;
229
230         /* click sounds are unset by default, which causes us to internal
231            waveforms for clicks.
232         */
233
234         click_length = 0;
235         click_emphasis_length = 0;
236         _clicking = false;
237
238         process_function = &Session::process_with_events;
239
240         if (config.get_use_video_sync()) {
241                 waiting_for_sync_offset = true;
242         } else {
243                 waiting_for_sync_offset = false;
244         }
245
246         last_timecode_when = 0;
247         _timecode_offset = 0;
248         _timecode_offset_negative = true;
249         last_timecode_valid = false;
250
251         sync_time_vars ();
252
253         last_rr_session_dir = session_dirs.begin();
254         refresh_disk_space ();
255
256         // set_default_fade (0.2, 5.0); /* steepness, millisecs */
257
258         /* slave stuff */
259
260         average_slave_delta = 1800; // !!! why 1800 ????
261         have_first_delta_accumulator = false;
262         delta_accumulator_cnt = 0;
263         _slave_state = Stopped;
264
265         _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
266
267         /* These are all static "per-class" signals */
268
269         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
270         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
271         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
272         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
273         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
274
275         /* stop IO objects from doing stuff until we're ready for them */
276
277         Delivery::disable_panners ();
278         IO::disable_connecting ();
279 }
280
281 int
282 Session::second_stage_init ()
283 {
284         AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
285
286         if (!_is_new) {
287                 if (load_state (_current_snapshot_name)) {
288                         return -1;
289                 }
290                 remove_empty_sounds ();
291         }
292
293         if (_butler->start_thread()) {
294                 return -1;
295         }
296
297         if (start_midi_thread ()) {
298                 return -1;
299         }
300
301         // set_state() will call setup_raid_path(), but if it's a new session we need
302         // to call setup_raid_path() here.
303
304         if (state_tree) {
305                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
306                         return -1;
307                 }
308         } else {
309                 setup_raid_path(_path);
310         }
311
312         /* we can't save till after ::when_engine_running() is called,
313            because otherwise we save state with no connections made.
314            therefore, we reset _state_of_the_state because ::set_state()
315            will have cleared it.
316
317            we also have to include Loading so that any events that get
318            generated between here and the end of ::when_engine_running()
319            will be processed directly rather than queued.
320         */
321
322         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
323
324
325         _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
326         _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
327         setup_click_sounds (0);
328         setup_midi_control ();
329
330         /* Pay attention ... */
331
332         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
333         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
334
335         try {
336                 when_engine_running ();
337         }
338
339         /* handle this one in a different way than all others, so that its clear what happened */
340
341         catch (AudioEngine::PortRegistrationFailure& err) {
342                 error << err.what() << endmsg;
343                 return -1;
344         }
345
346         catch (...) {
347                 return -1;
348         }
349
350         BootMessage (_("Reset Remote Controls"));
351
352         send_full_time_code (0);
353         _engine.transport_locate (0);
354         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
355         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
356
357         MidiClockTicker::instance().set_session (this);
358         MIDI::Name::MidiPatchManager::instance().set_session (this);
359
360         /* initial program change will be delivered later; see ::config_changed() */
361
362         BootMessage (_("Reset Control Protocols"));
363
364         ControlProtocolManager::instance().set_session (this);
365
366         _state_of_the_state = Clean;
367
368         DirtyChanged (); /* EMIT SIGNAL */
369
370         if (state_was_pending) {
371                 save_state (_current_snapshot_name);
372                 remove_pending_capture_state ();
373                 state_was_pending = false;
374         }
375
376         BootMessage (_("Session loading complete"));
377
378         return 0;
379 }
380
381 string
382 Session::raid_path () const
383 {
384         SearchPath raid_search_path;
385
386         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
387                 raid_search_path += sys::path((*i).path);
388         }
389
390         return raid_search_path.to_string ();
391 }
392
393 void
394 Session::setup_raid_path (string path)
395 {
396         if (path.empty()) {
397                 return;
398         }
399
400         space_and_path sp;
401         string fspath;
402
403         session_dirs.clear ();
404
405         SearchPath search_path(path);
406         SearchPath sound_search_path;
407         SearchPath midi_search_path;
408
409         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
410                 sp.path = (*i).to_string ();
411                 sp.blocks = 0; // not needed
412                 session_dirs.push_back (sp);
413
414                 SessionDirectory sdir(sp.path);
415
416                 sound_search_path += sdir.sound_path ();
417                 midi_search_path += sdir.midi_path ();
418         }
419
420         // set the search path for each data type
421         FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
422         SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
423
424         // reset the round-robin soundfile path thingie
425         last_rr_session_dir = session_dirs.begin();
426 }
427
428 bool
429 Session::path_is_within_session (const std::string& path)
430 {
431         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
432                 if (path.find ((*i).path) == 0) {
433                         return true;
434                 }
435         }
436         return false;
437 }
438
439 int
440 Session::ensure_subdirs ()
441 {
442         string dir;
443
444         dir = session_directory().peak_path().to_string();
445
446         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
448                 return -1;
449         }
450
451         dir = session_directory().sound_path().to_string();
452
453         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455                 return -1;
456         }
457
458         dir = session_directory().midi_path().to_string();
459
460         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462                 return -1;
463         }
464
465         dir = session_directory().dead_sound_path().to_string();
466
467         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469                 return -1;
470         }
471
472         dir = session_directory().export_path().to_string();
473
474         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476                 return -1;
477         }
478
479         dir = analysis_dir ();
480
481         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483                 return -1;
484         }
485
486         return 0;
487 }
488
489 int
490 Session::create (const string& mix_template, BusProfile* bus_profile)
491 {
492
493         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
494                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
495                 return -1;
496         }
497
498         if (ensure_subdirs ()) {
499                 return -1;
500         }
501
502         if (!mix_template.empty()) {
503                 std::string in_path = mix_template;
504
505                 ifstream in(in_path.c_str());
506
507                 if (in){
508                         string out_path = _path;
509                         out_path += _name;
510                         out_path += statefile_suffix;
511
512                         ofstream out(out_path.c_str());
513
514                         if (out){
515                                 out << in.rdbuf();
516                                 _is_new = false;
517                                 return 0;
518
519                         } else {
520                                 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
521                                         << endmsg;
522                                 return -1;
523                         }
524
525                 } else {
526                         error << string_compose (_("Could not open mix template %1 for reading"), in_path)
527                                 << endmsg;
528                         return -1;
529                 }
530
531         }
532
533         /* Instantiate metadata */
534
535         _metadata = new SessionMetadata ();
536
537         /* set initial start + end point */
538
539         _state_of_the_state = Clean;
540         
541         /* set up Master Out and Control Out if necessary */
542
543         if (bus_profile) {
544
545                 RouteList rl;
546                 int control_id = 1;
547                 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
548
549                 if (bus_profile->master_out_channels) {
550                         Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
551                         if (rt->init ()) {
552                                 delete rt;
553                                 return -1;
554                         }
555                         boost_debug_shared_ptr_mark_interesting (rt, "Route");
556                         boost::shared_ptr<Route> r (rt);
557                         r->input()->ensure_io (count, false, this);
558                         r->output()->ensure_io (count, false, this);
559                         r->set_remote_control_id (control_id++);
560
561                         rl.push_back (r);
562
563                         if (Config->get_use_monitor_bus()) {
564                                 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
565                                 if (rt->init ()) {
566                                         delete rt;
567                                         return -1;
568                                 }
569                                 boost_debug_shared_ptr_mark_interesting (rt, "Route");
570                                 boost::shared_ptr<Route> r (rt);
571                                 r->input()->ensure_io (count, false, this);
572                                 r->output()->ensure_io (count, false, this);
573                                 r->set_remote_control_id (control_id);
574                                 
575                                 rl.push_back (r);
576                         }
577
578                 } else {
579                         /* prohibit auto-connect to master, because there isn't one */
580                         bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
581                 }
582
583                 if (!rl.empty()) {
584                         add_routes (rl, false);
585                 }
586
587                 /* this allows the user to override settings with an environment variable.
588                  */
589
590                 if (no_auto_connect()) {
591                         bus_profile->input_ac = AutoConnectOption (0);
592                         bus_profile->output_ac = AutoConnectOption (0);
593                 }
594                 
595                 Config->set_input_auto_connect (bus_profile->input_ac);
596                 Config->set_output_auto_connect (bus_profile->output_ac);
597         }
598
599         save_state ("");
600
601         return 0;
602 }
603
604 void
605 Session::maybe_write_autosave()
606 {
607         if (dirty() && record_status() != Recording) {
608                 save_state("", true);
609         }
610 }
611
612 void
613 Session::remove_pending_capture_state ()
614 {
615         sys::path pending_state_file_path(_session_dir->root_path());
616
617         pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
618
619         try
620         {
621                 sys::remove (pending_state_file_path);
622         }
623         catch(sys::filesystem_error& ex)
624         {
625                 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
626                                 pending_state_file_path.to_string(), ex.what()) << endmsg;
627         }
628 }
629
630 /** Rename a state file.
631  * @param snapshot_name Snapshot name.
632  */
633 void
634 Session::rename_state (string old_name, string new_name)
635 {
636         if (old_name == _current_snapshot_name || old_name == _name) {
637                 /* refuse to rename the current snapshot or the "main" one */
638                 return;
639         }
640
641         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
642         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
643
644         const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
645         const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
646
647         try
648         {
649                 sys::rename (old_xml_path, new_xml_path);
650         }
651         catch (const sys::filesystem_error& err)
652         {
653                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
654                                 old_name, new_name, err.what()) << endmsg;
655         }
656 }
657
658 /** Remove a state file.
659  * @param snapshot_name Snapshot name.
660  */
661 void
662 Session::remove_state (string snapshot_name)
663 {
664         if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
665                 // refuse to remove the current snapshot or the "main" one
666                 return;
667         }
668
669         sys::path xml_path(_session_dir->root_path());
670
671         xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
672
673         if (!create_backup_file (xml_path)) {
674                 // don't remove it if a backup can't be made
675                 // create_backup_file will log the error.
676                 return;
677         }
678
679         // and delete it
680         sys::remove (xml_path);
681 }
682
683 #ifdef HAVE_JACK_SESSION
684 void
685 Session::jack_session_event (jack_session_event_t * event)
686 {
687         if (save_state ("jacksession_snap")) {
688                 event->flags = JackSessionSaveError; 
689         } else {
690                 sys::path xml_path (_session_dir->root_path());
691                 xml_path /= legalize_for_path ("jacksession_snap") + statefile_suffix;
692                 
693                 string cmd ("PROG_NAME -U ");
694                 cmd += event->client_uuid;
695                 cmd += " \"";
696                 cmd += xml_path.to_string();
697                 cmd += '\"';
698                 
699                 event->command_line = strdup (cmd.c_str());
700         }
701
702         jack_session_reply (_engine.jack(), event);
703
704         if (event->type == JackSessionSaveAndQuit) {
705                 // TODO: make ardour quit.
706         }
707
708         jack_session_event_free( event );
709 }
710 #endif
711
712 int
713 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
714 {
715         XMLTree tree;
716         sys::path xml_path(_session_dir->root_path());
717
718         if (!_writable || (_state_of_the_state & CannotSave)) {
719                 return 1;
720         }
721
722         if (!_engine.connected ()) {
723                 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
724                                          PROGRAM_NAME)
725                       << endmsg;
726                 return 1;
727         }
728
729         /* tell sources we're saving first, in case they write out to a new file
730          * which should be saved with the state rather than the old one */
731         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
732                 i->second->session_saved();
733
734         tree.set_root (&get_state());
735
736         if (snapshot_name.empty()) {
737                 snapshot_name = _current_snapshot_name;
738         } else if (switch_to_snapshot) {
739                 _current_snapshot_name = snapshot_name;
740         }
741
742         if (!pending) {
743
744                 /* proper save: use statefile_suffix (.ardour in English) */
745
746                 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
747
748                 /* make a backup copy of the old file */
749
750                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
751                         // create_backup_file will log the error
752                         return -1;
753                 }
754
755         } else {
756
757                 /* pending save: use pending_suffix (.pending in English) */
758                 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
759         }
760
761         sys::path tmp_path(_session_dir->root_path());
762
763         tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
764
765         // cerr << "actually writing state to " << xml_path.to_string() << endl;
766
767         if (!tree.write (tmp_path.to_string())) {
768                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
769                 sys::remove (tmp_path);
770                 return -1;
771
772         } else {
773
774                 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
775                         error << string_compose (_("could not rename temporary session file %1 to %2"),
776                                         tmp_path.to_string(), xml_path.to_string()) << endmsg;
777                         sys::remove (tmp_path);
778                         return -1;
779                 }
780         }
781
782         if (!pending) {
783
784                 save_history (snapshot_name);
785
786                 bool was_dirty = dirty();
787
788                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
789
790                 if (was_dirty) {
791                         DirtyChanged (); /* EMIT SIGNAL */
792                 }
793
794                 StateSaved (snapshot_name); /* EMIT SIGNAL */
795         }
796
797         return 0;
798 }
799
800 int
801 Session::restore_state (string snapshot_name)
802 {
803         if (load_state (snapshot_name) == 0) {
804                 set_state (*state_tree->root(), Stateful::loading_state_version);
805         }
806
807         return 0;
808 }
809
810 int
811 Session::load_state (string snapshot_name)
812 {
813         delete state_tree;
814         state_tree = 0;
815
816         state_was_pending = false;
817
818         /* check for leftover pending state from a crashed capture attempt */
819
820         sys::path xmlpath(_session_dir->root_path());
821         xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
822
823         if (sys::exists (xmlpath)) {
824
825                 /* there is pending state from a crashed capture attempt */
826
827                 if (*AskAboutPendingState()) {
828                         state_was_pending = true;
829                 }
830         }
831
832         if (!state_was_pending) {
833                 xmlpath = _session_dir->root_path();
834                 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
835         }
836
837         if (!sys::exists (xmlpath)) {
838                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
839                 return 1;
840         }
841
842         state_tree = new XMLTree;
843
844         set_dirty();
845
846         /* writable() really reflects the whole folder, but if for any
847            reason the session state file can't be written to, still
848            make us unwritable.
849         */
850
851         if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
852                 _writable = false;
853         }
854
855         if (!state_tree->read (xmlpath.to_string())) {
856                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
857                 delete state_tree;
858                 state_tree = 0;
859                 return -1;
860         }
861
862         XMLNode& root (*state_tree->root());
863
864         if (root.name() != X_("Session")) {
865                 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
866                 delete state_tree;
867                 state_tree = 0;
868                 return -1;
869         }
870
871         const XMLProperty* prop;
872
873         if ((prop = root.property ("version")) == 0) {
874                 /* no version implies very old version of Ardour */
875                 Stateful::loading_state_version = 1000;
876         } else {
877                 int major;
878                 int minor;
879                 int micro;
880
881                 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, &micro);
882                 Stateful::loading_state_version = (major * 1000) + minor;
883         }
884                 
885         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
886
887                 sys::path backup_path(_session_dir->root_path());
888
889                 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
890
891                 // only create a backup once
892                 if (sys::exists (backup_path)) {
893                         return 0;
894                 }
895
896                 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
897                                         xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
898                      << endmsg;
899
900                 try
901                 {
902                         sys::copy_file (xmlpath, backup_path);
903                 }
904                 catch(sys::filesystem_error& ex)
905                 {
906                         error << string_compose (_("Unable to make backup of state file %1 (%2)"),
907                                         xmlpath.to_string(), ex.what())
908                                 << endmsg;
909                         return -1;
910                 }
911         }
912
913         return 0;
914 }
915
916 int
917 Session::load_options (const XMLNode& node)
918 {
919         LocaleGuard lg (X_("POSIX"));
920         config.set_variables (node);
921         return 0;
922 }
923
924 XMLNode&
925 Session::get_state()
926 {
927         return state(true);
928 }
929
930 XMLNode&
931 Session::get_template()
932 {
933         /* if we don't disable rec-enable, diskstreams
934            will believe they need to store their capture
935            sources in their state node.
936         */
937
938         disable_record (false);
939
940         return state(false);
941 }
942
943 XMLNode&
944 Session::state(bool full_state)
945 {
946         XMLNode* node = new XMLNode("Session");
947         XMLNode* child;
948
949         // store libardour version, just in case
950         char buf[16];
951         snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
952         node->add_property("version", string(buf));
953
954         /* store configuration settings */
955
956         if (full_state) {
957
958                 node->add_property ("name", _name);
959                 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
960                 node->add_property ("sample-rate", buf);
961
962                 if (session_dirs.size() > 1) {
963
964                         string p;
965
966                         vector<space_and_path>::iterator i = session_dirs.begin();
967                         vector<space_and_path>::iterator next;
968
969                         ++i; /* skip the first one */
970                         next = i;
971                         ++next;
972
973                         while (i != session_dirs.end()) {
974
975                                 p += (*i).path;
976
977                                 if (next != session_dirs.end()) {
978                                         p += ':';
979                                 } else {
980                                         break;
981                                 }
982
983                                 ++next;
984                                 ++i;
985                         }
986
987                         child = node->add_child ("Path");
988                         child->add_content (p);
989                 }
990         }
991
992         /* save the ID counter */
993
994         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
995         node->add_property ("id-counter", buf);
996
997         /* various options */
998
999         node->add_child_nocopy (config.get_variables ());
1000
1001         node->add_child_nocopy (_metadata->get_state());
1002
1003         child = node->add_child ("Sources");
1004
1005         if (full_state) {
1006                 Glib::Mutex::Lock sl (source_lock);
1007
1008                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1009
1010                         /* Don't save information about non-destructive file sources that are empty */
1011                         /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1012
1013                         boost::shared_ptr<AudioFileSource> fs;
1014                         if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1015                                 if (!fs->destructive()) {
1016                                         if (fs->length(fs->timeline_position()) == 0) {
1017                                                 continue;
1018                                         }
1019                                 }
1020                         }
1021
1022                         child->add_child_nocopy (siter->second->get_state());
1023                 }
1024         }
1025
1026         child = node->add_child ("Regions");
1027
1028         if (full_state) {
1029                 Glib::Mutex::Lock rl (region_lock);
1030                 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1031                 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1032                         boost::shared_ptr<Region> r = i->second;
1033                         /* only store regions not attached to playlists */
1034                         if (r->playlist() == 0) {
1035                                 child->add_child_nocopy (r->state (true));
1036                         }
1037                 }
1038         }
1039
1040         if (full_state) {
1041                 node->add_child_nocopy (_locations.get_state());
1042         } else {
1043                 // for a template, just create a new Locations, populate it
1044                 // with the default start and end, and get the state for that.
1045                 Locations loc;
1046                 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1047                 range->set (max_frames, 0);
1048                 loc.add (range);
1049                 node->add_child_nocopy (loc.get_state());
1050         }
1051
1052         child = node->add_child ("Bundles");
1053         {
1054                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1055                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1056                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1057                         if (b) {
1058                                 child->add_child_nocopy (b->get_state());
1059                         }
1060                 }
1061         }
1062
1063         child = node->add_child ("Routes");
1064         {
1065                 boost::shared_ptr<RouteList> r = routes.reader ();
1066
1067                 RoutePublicOrderSorter cmp;
1068                 RouteList public_order (*r);
1069                 public_order.sort (cmp);
1070
1071                 /* the sort should have put control outs first */
1072
1073                 if (_monitor_out) {
1074                         assert (_monitor_out == public_order.front());
1075                 }
1076
1077                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1078                         if (!(*i)->is_hidden()) {
1079                                 if (full_state) {
1080                                         child->add_child_nocopy ((*i)->get_state());
1081                                 } else {
1082                                         child->add_child_nocopy ((*i)->get_template());
1083                                 }
1084                         }
1085                 }
1086         }
1087
1088         playlists->add_state (node, full_state);
1089
1090         child = node->add_child ("RouteGroups");
1091         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1092                 child->add_child_nocopy ((*i)->get_state());
1093         }
1094
1095         if (_click_io) {
1096                 child = node->add_child ("Click");
1097                 child->add_child_nocopy (_click_io->state (full_state));
1098         }
1099
1100         if (full_state) {
1101                 child = node->add_child ("NamedSelections");
1102                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1103                         if (full_state) {
1104                                 child->add_child_nocopy ((*i)->get_state());
1105                         }
1106                 }
1107         }
1108
1109         node->add_child_nocopy (_tempo_map->get_state());
1110
1111         node->add_child_nocopy (get_control_protocol_state());
1112
1113         if (_extra_xml) {
1114                 node->add_child_copy (*_extra_xml);
1115         }
1116
1117         return *node;
1118 }
1119
1120 XMLNode&
1121 Session::get_control_protocol_state ()
1122 {
1123         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1124         return cpm.get_state();
1125 }
1126
1127 int
1128 Session::set_state (const XMLNode& node, int version)
1129 {
1130         XMLNodeList nlist;
1131         XMLNode* child;
1132         const XMLProperty* prop;
1133         int ret = -1;
1134
1135         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1136
1137         if (node.name() != X_("Session")){
1138                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1139                 return -1;
1140         }
1141
1142         if ((prop = node.property ("version")) != 0) {
1143                 version = atoi (prop->value ()) * 1000;
1144         }
1145
1146         if ((prop = node.property ("name")) != 0) {
1147                 _name = prop->value ();
1148         }
1149
1150         if ((prop = node.property (X_("sample-rate"))) != 0) {
1151
1152                 _nominal_frame_rate = atoi (prop->value());
1153
1154                 if (_nominal_frame_rate != _current_frame_rate) {
1155                         if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1156                                 return -1;
1157                         }
1158                 }
1159         }
1160
1161         setup_raid_path(_session_dir->root_path().to_string());
1162
1163         if ((prop = node.property (X_("id-counter"))) != 0) {
1164                 uint64_t x;
1165                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1166                 ID::init_counter (x);
1167         } else {
1168                 /* old sessions used a timebased counter, so fake
1169                    the startup ID counter based on a standard
1170                    timestamp.
1171                 */
1172                 time_t now;
1173                 time (&now);
1174                 ID::init_counter (now);
1175         }
1176
1177
1178         IO::disable_connecting ();
1179
1180         /* Object loading order:
1181
1182         Path
1183         Extra
1184         Options/Config
1185         MIDI Control // relies on data from Options/Config
1186         Metadata
1187         Locations
1188         Sources
1189         AudioRegions
1190         Connections
1191         Routes
1192         RouteGroups
1193         MixGroups
1194         Click
1195         ControlProtocols
1196         */
1197
1198         if ((child = find_named_node (node, "Extra")) != 0) {
1199                 _extra_xml = new XMLNode (*child);
1200         }
1201
1202         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1203                 load_options (*child);
1204         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1205                 load_options (*child);
1206         } else {
1207                 error << _("Session: XML state has no options section") << endmsg;
1208         }
1209
1210         if (use_config_midi_ports ()) {
1211         }
1212
1213         if (version >= 3000) {
1214                 if ((child = find_named_node (node, "Metadata")) == 0) {
1215                         warning << _("Session: XML state has no metadata section") << endmsg;
1216                 } else if (_metadata->set_state (*child, version)) {
1217                         goto out;
1218                 }
1219         }
1220
1221         if ((child = find_named_node (node, "Locations")) == 0) {
1222                 error << _("Session: XML state has no locations section") << endmsg;
1223                 goto out;
1224         } else if (_locations.set_state (*child, version)) {
1225                 goto out;
1226         }
1227
1228         Location* location;
1229
1230         if ((location = _locations.auto_loop_location()) != 0) {
1231                 set_auto_loop_location (location);
1232         }
1233
1234         if ((location = _locations.auto_punch_location()) != 0) {
1235                 set_auto_punch_location (location);
1236         }
1237
1238         if ((location = _locations.session_range_location()) != 0) {
1239                 delete _session_range_location;
1240                 _session_range_location = location;
1241         }
1242
1243         if (_session_range_location) {
1244                 AudioFileSource::set_header_position_offset (_session_range_location->start());
1245         }
1246
1247         if ((child = find_named_node (node, "Sources")) == 0) {
1248                 error << _("Session: XML state has no sources section") << endmsg;
1249                 goto out;
1250         } else if (load_sources (*child)) {
1251                 goto out;
1252         }
1253
1254         if ((child = find_named_node (node, "Regions")) == 0) {
1255                 error << _("Session: XML state has no Regions section") << endmsg;
1256                 goto out;
1257         } else if (load_regions (*child)) {
1258                 goto out;
1259         }
1260
1261         if ((child = find_named_node (node, "Playlists")) == 0) {
1262                 error << _("Session: XML state has no playlists section") << endmsg;
1263                 goto out;
1264         } else if (playlists->load (*this, *child)) {
1265                 goto out;
1266         }
1267
1268         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1269                 // this is OK
1270         } else if (playlists->load_unused (*this, *child)) {
1271                 goto out;
1272         }
1273         
1274         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1275                 if (load_named_selections (*child)) {
1276                         goto out;
1277                 }
1278         }
1279
1280         if (version >= 3000) {
1281                 if ((child = find_named_node (node, "Bundles")) == 0) {
1282                         warning << _("Session: XML state has no bundles section") << endmsg;
1283                         //goto out;
1284                 } else {
1285                         /* We can't load Bundles yet as they need to be able
1286                            to convert from port names to Port objects, which can't happen until
1287                            later */
1288                         _bundle_xml_node = new XMLNode (*child);
1289                 }
1290         }
1291         
1292         if ((child = find_named_node (node, "TempoMap")) == 0) {
1293                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1294                 goto out;
1295         } else if (_tempo_map->set_state (*child, version)) {
1296                 goto out;
1297         }
1298
1299         if (version < 3000) {
1300                 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1301                         error << _("Session: XML state has no diskstreams section") << endmsg;
1302                         goto out;
1303                 } else if (load_diskstreams_2X (*child, version)) {
1304                         goto out;
1305                 }
1306         }
1307
1308         if ((child = find_named_node (node, "Routes")) == 0) {
1309                 error << _("Session: XML state has no routes section") << endmsg;
1310                 goto out;
1311         } else if (load_routes (*child, version)) {
1312                 goto out;
1313         }
1314
1315         /* our diskstreams list is no longer needed as they are now all owned by their Route */
1316         _diskstreams_2X.clear ();
1317
1318         if (version >= 3000) {
1319                 
1320                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1321                         error << _("Session: XML state has no route groups section") << endmsg;
1322                         goto out;
1323                 } else if (load_route_groups (*child, version)) {
1324                         goto out;
1325                 }
1326                 
1327         } else if (version < 3000) {
1328                 
1329                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1330                         error << _("Session: XML state has no edit groups section") << endmsg;
1331                         goto out;
1332                 } else if (load_route_groups (*child, version)) {
1333                         goto out;
1334                 }
1335
1336                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1337                         error << _("Session: XML state has no mix groups section") << endmsg;
1338                         goto out;
1339                 } else if (load_route_groups (*child, version)) {
1340                         goto out;
1341                 }
1342         }
1343
1344         if ((child = find_named_node (node, "Click")) == 0) {
1345                 warning << _("Session: XML state has no click section") << endmsg;
1346         } else if (_click_io) {
1347                 _click_io->set_state (*child, version);
1348         }
1349
1350         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1351                 ControlProtocolManager::instance().set_protocol_states (*child);
1352         }
1353
1354         /* here beginneth the second phase ... */
1355
1356         StateReady (); /* EMIT SIGNAL */
1357
1358         return 0;
1359
1360   out:
1361         return ret;
1362 }
1363
1364 int
1365 Session::load_routes (const XMLNode& node, int version)
1366 {
1367         XMLNodeList nlist;
1368         XMLNodeConstIterator niter;
1369         RouteList new_routes;
1370
1371         nlist = node.children();
1372
1373         set_dirty();
1374
1375         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1376
1377                 boost::shared_ptr<Route> route;
1378                 if (version < 3000) {
1379                         route = XMLRouteFactory_2X (**niter, version);
1380                 } else {
1381                         route = XMLRouteFactory (**niter, version);
1382                 }
1383                 
1384                 if (route == 0) {
1385                         error << _("Session: cannot create Route from XML description.") << endmsg;
1386                         return -1;
1387                 }
1388
1389                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1390
1391                 new_routes.push_back (route);
1392         }
1393
1394         add_routes (new_routes, false);
1395
1396         return 0;
1397 }
1398
1399 boost::shared_ptr<Route>
1400 Session::XMLRouteFactory (const XMLNode& node, int version)
1401 {
1402         boost::shared_ptr<Route> ret;
1403
1404         if (node.name() != "Route") {
1405                 return ret;
1406         }
1407
1408         XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1409
1410         DataType type = DataType::AUDIO;
1411         const XMLProperty* prop = node.property("default-type");
1412
1413         if (prop) {
1414                 type = DataType (prop->value());
1415         }
1416
1417         assert (type != DataType::NIL);
1418
1419         if (ds_child) {
1420
1421                 Track* track;
1422                 
1423                 if (type == DataType::AUDIO) {
1424                         track = new AudioTrack (*this, X_("toBeResetFroXML"));
1425                         
1426                 } else {
1427                         track = new MidiTrack (*this, X_("toBeResetFroXML"));
1428                 }
1429                 
1430                 if (track->init()) {
1431                         delete track;
1432                         return ret;
1433                 }
1434                 
1435                 if (track->set_state (node, version)) {
1436                         delete track;
1437                         return ret;
1438                 }
1439                 
1440                 boost_debug_shared_ptr_mark_interesting (track, "Track");
1441                 ret.reset (track);
1442                 
1443         } else {
1444                 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1445
1446                 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1447                         boost_debug_shared_ptr_mark_interesting (rt, "Route");
1448                         ret.reset (rt);
1449                 } else {
1450                         delete rt;
1451                 }
1452         }
1453
1454         return ret;
1455 }
1456
1457 boost::shared_ptr<Route>
1458 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1459 {
1460         boost::shared_ptr<Route> ret;
1461
1462         if (node.name() != "Route") {
1463                 return ret;
1464         }
1465
1466         XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1467         if (!ds_prop) {
1468                 ds_prop = node.property (X_("diskstream"));
1469         }
1470
1471         DataType type = DataType::AUDIO;
1472         const XMLProperty* prop = node.property("default-type");
1473
1474         if (prop) {
1475                 type = DataType (prop->value());
1476         }
1477
1478         assert (type != DataType::NIL);
1479
1480         if (ds_prop) {
1481
1482                 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1483                 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1484                         ++i;
1485                 }
1486
1487                 if (i == _diskstreams_2X.end()) {
1488                         error << _("Could not find diskstream for route") << endmsg;
1489                         return boost::shared_ptr<Route> ();
1490                 }
1491
1492                 Track* track;
1493                 
1494                 if (type == DataType::AUDIO) {
1495                         track = new AudioTrack (*this, X_("toBeResetFroXML"));
1496                         
1497                 } else {
1498                         track = new MidiTrack (*this, X_("toBeResetFroXML"));
1499                 }
1500                 
1501                 if (track->init()) {
1502                         delete track;
1503                         return ret;
1504                 }
1505                 
1506                 if (track->set_state (node, version)) {
1507                         delete track;
1508                         return ret;
1509                 }
1510
1511                 track->set_diskstream (*i);
1512                 
1513                 boost_debug_shared_ptr_mark_interesting (track, "Track");
1514                 ret.reset (track);
1515                 
1516         } else {
1517                 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1518
1519                 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1520                         boost_debug_shared_ptr_mark_interesting (rt, "Route");
1521                         ret.reset (rt);
1522                 } else {
1523                         delete rt;
1524                 }
1525         }
1526
1527         return ret;
1528 }
1529
1530 int
1531 Session::load_regions (const XMLNode& node)
1532 {
1533         XMLNodeList nlist;
1534         XMLNodeConstIterator niter;
1535         boost::shared_ptr<Region> region;
1536
1537         nlist = node.children();
1538
1539         set_dirty();
1540
1541         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1542                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1543                         error << _("Session: cannot create Region from XML description.");
1544                         const XMLProperty *name = (**niter).property("name");
1545
1546                         if (name) {
1547                                 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1548                         }
1549
1550                         error << endmsg;
1551                 }
1552         }
1553
1554         return 0;
1555 }
1556
1557 boost::shared_ptr<Region>
1558 Session::XMLRegionFactory (const XMLNode& node, bool full)
1559 {
1560         const XMLProperty* type = node.property("type");
1561
1562         try {
1563
1564         if ( !type || type->value() == "audio" ) {
1565
1566                 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1567
1568         } else if (type->value() == "midi") {
1569
1570                 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1571
1572         }
1573
1574         } catch (failed_constructor& err) {
1575                 return boost::shared_ptr<Region> ();
1576         }
1577
1578         return boost::shared_ptr<Region> ();
1579 }
1580
1581 boost::shared_ptr<AudioRegion>
1582 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1583 {
1584         const XMLProperty* prop;
1585         boost::shared_ptr<Source> source;
1586         boost::shared_ptr<AudioSource> as;
1587         SourceList sources;
1588         SourceList master_sources;
1589         uint32_t nchans = 1;
1590         char buf[128];
1591
1592         if (node.name() != X_("Region")) {
1593                 return boost::shared_ptr<AudioRegion>();
1594         }
1595
1596         if ((prop = node.property (X_("channels"))) != 0) {
1597                 nchans = atoi (prop->value().c_str());
1598         }
1599
1600         if ((prop = node.property ("name")) == 0) {
1601                 cerr << "no name for this region\n";
1602                 abort ();
1603         }
1604
1605         if ((prop = node.property (X_("source-0"))) == 0) {
1606                 if ((prop = node.property ("source")) == 0) {
1607                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1608                         return boost::shared_ptr<AudioRegion>();
1609                 }
1610         }
1611
1612         PBD::ID s_id (prop->value());
1613
1614         if ((source = source_by_id (s_id)) == 0) {
1615                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1616                 return boost::shared_ptr<AudioRegion>();
1617         }
1618
1619         as = boost::dynamic_pointer_cast<AudioSource>(source);
1620         if (!as) {
1621                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1622                 return boost::shared_ptr<AudioRegion>();
1623         }
1624
1625         sources.push_back (as);
1626
1627         /* pickup other channels */
1628
1629         for (uint32_t n=1; n < nchans; ++n) {
1630                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1631                 if ((prop = node.property (buf)) != 0) {
1632
1633                         PBD::ID id2 (prop->value());
1634
1635                         if ((source = source_by_id (id2)) == 0) {
1636                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1637                                 return boost::shared_ptr<AudioRegion>();
1638                         }
1639
1640                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1641                         if (!as) {
1642                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1643                                 return boost::shared_ptr<AudioRegion>();
1644                         }
1645                         sources.push_back (as);
1646                 }
1647         }
1648
1649         for (uint32_t n = 0; n < nchans; ++n) {
1650                 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1651                 if ((prop = node.property (buf)) != 0) {
1652
1653                         PBD::ID id2 (prop->value());
1654
1655                         if ((source = source_by_id (id2)) == 0) {
1656                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1657                                 return boost::shared_ptr<AudioRegion>();
1658                         }
1659
1660                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1661                         if (!as) {
1662                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1663                                 return boost::shared_ptr<AudioRegion>();
1664                         }
1665                         master_sources.push_back (as);
1666                 }
1667         }
1668
1669         try {
1670                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1671
1672                 /* a final detail: this is the one and only place that we know how long missing files are */
1673
1674                 if (region->whole_file()) {
1675                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1676                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1677                                 if (sfp) {
1678                                         sfp->set_length (region->length());
1679                                 }
1680                         }
1681                 }
1682
1683                 if (!master_sources.empty()) {
1684                         if (master_sources.size() != nchans) {
1685                                 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1686                         } else {
1687                                 region->set_master_sources (master_sources);
1688                         }
1689                 }
1690
1691                 return region;
1692
1693         }
1694
1695         catch (failed_constructor& err) {
1696                 return boost::shared_ptr<AudioRegion>();
1697         }
1698 }
1699
1700 boost::shared_ptr<MidiRegion>
1701 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1702 {
1703         const XMLProperty* prop;
1704         boost::shared_ptr<Source> source;
1705         boost::shared_ptr<MidiSource> ms;
1706         SourceList sources;
1707         uint32_t nchans = 1;
1708
1709         if (node.name() != X_("Region")) {
1710                 return boost::shared_ptr<MidiRegion>();
1711         }
1712
1713         if ((prop = node.property (X_("channels"))) != 0) {
1714                 nchans = atoi (prop->value().c_str());
1715         }
1716
1717         if ((prop = node.property ("name")) == 0) {
1718                 cerr << "no name for this region\n";
1719                 abort ();
1720         }
1721
1722         // Multiple midi channels?  that's just crazy talk
1723         assert(nchans == 1);
1724
1725         if ((prop = node.property (X_("source-0"))) == 0) {
1726                 if ((prop = node.property ("source")) == 0) {
1727                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1728                         return boost::shared_ptr<MidiRegion>();
1729                 }
1730         }
1731
1732         PBD::ID s_id (prop->value());
1733
1734         if ((source = source_by_id (s_id)) == 0) {
1735                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1736                 return boost::shared_ptr<MidiRegion>();
1737         }
1738
1739         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1740         if (!ms) {
1741                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1742                 return boost::shared_ptr<MidiRegion>();
1743         }
1744
1745         sources.push_back (ms);
1746
1747         try {
1748                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1749                 /* a final detail: this is the one and only place that we know how long missing files are */
1750
1751                 if (region->whole_file()) {
1752                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1753                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1754                                 if (sfp) {
1755                                         sfp->set_length (region->length());
1756                                 }
1757                         }
1758                 }
1759
1760                 return region;
1761         }
1762
1763         catch (failed_constructor& err) {
1764                 return boost::shared_ptr<MidiRegion>();
1765         }
1766 }
1767
1768 XMLNode&
1769 Session::get_sources_as_xml ()
1770
1771 {
1772         XMLNode* node = new XMLNode (X_("Sources"));
1773         Glib::Mutex::Lock lm (source_lock);
1774
1775         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1776                 node->add_child_nocopy (i->second->get_state());
1777         }
1778
1779         return *node;
1780 }
1781
1782 string
1783 Session::path_from_region_name (DataType type, string name, string identifier)
1784 {
1785         char buf[PATH_MAX+1];
1786         uint32_t n;
1787         SessionDirectory sdir(get_best_session_directory_for_new_source());
1788         sys::path source_dir = ((type == DataType::AUDIO)
1789                 ? sdir.sound_path() : sdir.midi_path());
1790
1791         string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1792
1793         for (n = 0; n < 999999; ++n) {
1794                 if (identifier.length()) {
1795                         snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1796                                   identifier.c_str(), n, ext.c_str());
1797                 } else {
1798                         snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1799                                         n, ext.c_str());
1800                 }
1801
1802                 sys::path source_path = source_dir / buf;
1803
1804                 if (!sys::exists (source_path)) {
1805                         return source_path.to_string();
1806                 }
1807         }
1808
1809         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1810                                  name, identifier)
1811               << endmsg;
1812
1813         return "";
1814 }
1815
1816
1817 int
1818 Session::load_sources (const XMLNode& node)
1819 {
1820         XMLNodeList nlist;
1821         XMLNodeConstIterator niter;
1822         boost::shared_ptr<Source> source;
1823
1824         nlist = node.children();
1825
1826         set_dirty();
1827
1828         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1829                 try {
1830                         if ((source = XMLSourceFactory (**niter)) == 0) {
1831                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1832                         }
1833                 } catch (MissingSource& err) {
1834                         warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1835                         source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1836                 }
1837         }
1838
1839         return 0;
1840 }
1841
1842 boost::shared_ptr<Source>
1843 Session::XMLSourceFactory (const XMLNode& node)
1844 {
1845         if (node.name() != "Source") {
1846                 return boost::shared_ptr<Source>();
1847         }
1848
1849         try {
1850                 /* note: do peak building in another thread when loading session state */
1851                 return SourceFactory::create (*this, node, true);
1852         }
1853
1854         catch (failed_constructor& err) {
1855                 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1856                 return boost::shared_ptr<Source>();
1857         }
1858 }
1859
1860 int
1861 Session::save_template (string template_name)
1862 {
1863         XMLTree tree;
1864
1865         if (_state_of_the_state & CannotSave) {
1866                 return -1;
1867         }
1868
1869         sys::path user_template_dir(user_template_directory());
1870
1871         try
1872         {
1873                 sys::create_directories (user_template_dir);
1874         }
1875         catch(sys::filesystem_error& ex)
1876         {
1877                 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1878                                 user_template_dir.to_string(), ex.what()) << endmsg;
1879                 return -1;
1880         }
1881
1882         tree.set_root (&get_template());
1883
1884         sys::path template_file_path(user_template_dir);
1885         template_file_path /= template_name + template_suffix;
1886
1887         if (sys::exists (template_file_path))
1888         {
1889                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1890                                 template_file_path.to_string()) << endmsg;
1891                 return -1;
1892         }
1893
1894         if (!tree.write (template_file_path.to_string())) {
1895                 error << _("mix template not saved") << endmsg;
1896                 return -1;
1897         }
1898
1899         return 0;
1900 }
1901
1902 int
1903 Session::rename_template (string old_name, string new_name)
1904 {
1905         sys::path old_path (user_template_directory());
1906         old_path /= old_name + template_suffix;
1907
1908         sys::path new_path(user_template_directory());
1909         new_path /= new_name + template_suffix;
1910
1911         if (sys::exists (new_path)) {
1912                 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1913                                           new_path.to_string()) << endmsg;
1914                 return -1;
1915         }
1916
1917         try {
1918                 sys::rename (old_path, new_path);
1919                 return 0;
1920         } catch (...) {
1921                 return -1;
1922         }
1923 }
1924
1925 int
1926 Session::delete_template (string name)
1927 {
1928         sys::path path = user_template_directory();
1929         path /= name + template_suffix;
1930
1931         try {
1932                 sys::remove (path);
1933                 return 0;
1934         } catch (...) {
1935                 return -1;
1936         }
1937 }
1938
1939 void
1940 Session::refresh_disk_space ()
1941 {
1942 #if HAVE_SYS_VFS_H
1943         struct statfs statfsbuf;
1944         vector<space_and_path>::iterator i;
1945         Glib::Mutex::Lock lm (space_lock);
1946         double scale;
1947
1948         /* get freespace on every FS that is part of the session path */
1949
1950         _total_free_4k_blocks = 0;
1951
1952         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1953                 statfs ((*i).path.c_str(), &statfsbuf);
1954
1955                 scale = statfsbuf.f_bsize/4096.0;
1956
1957                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1958                 _total_free_4k_blocks += (*i).blocks;
1959         }
1960 #endif
1961 }
1962
1963 string
1964 Session::get_best_session_directory_for_new_source ()
1965 {
1966         vector<space_and_path>::iterator i;
1967         string result = _session_dir->root_path().to_string();
1968
1969         /* handle common case without system calls */
1970
1971         if (session_dirs.size() == 1) {
1972                 return result;
1973         }
1974
1975         /* OK, here's the algorithm we're following here:
1976
1977         We want to select which directory to use for
1978         the next file source to be created. Ideally,
1979         we'd like to use a round-robin process so as to
1980         get maximum performance benefits from splitting
1981         the files across multiple disks.
1982
1983         However, in situations without much diskspace, an
1984         RR approach may end up filling up a filesystem
1985         with new files while others still have space.
1986         Its therefore important to pay some attention to
1987         the freespace in the filesystem holding each
1988         directory as well. However, if we did that by
1989         itself, we'd keep creating new files in the file
1990         system with the most space until it was as full
1991         as all others, thus negating any performance
1992         benefits of this RAID-1 like approach.
1993
1994         So, we use a user-configurable space threshold. If
1995         there are at least 2 filesystems with more than this
1996         much space available, we use RR selection between them.
1997         If not, then we pick the filesystem with the most space.
1998
1999         This gets a good balance between the two
2000         approaches.
2001         */
2002
2003         refresh_disk_space ();
2004
2005         int free_enough = 0;
2006
2007         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2008                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2009                         free_enough++;
2010                 }
2011         }
2012
2013         if (free_enough >= 2) {
2014                 /* use RR selection process, ensuring that the one
2015                    picked works OK.
2016                 */
2017
2018                 i = last_rr_session_dir;
2019
2020                 do {
2021                         if (++i == session_dirs.end()) {
2022                                 i = session_dirs.begin();
2023                         }
2024
2025                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2026                                 if (create_session_directory ((*i).path)) {
2027                                         result = (*i).path;
2028                                         last_rr_session_dir = i;
2029                                         return result;
2030                                 }
2031                         }
2032
2033                 } while (i != last_rr_session_dir);
2034
2035         } else {
2036
2037                 /* pick FS with the most freespace (and that
2038                    seems to actually work ...)
2039                 */
2040
2041                 vector<space_and_path> sorted;
2042                 space_and_path_ascending_cmp cmp;
2043
2044                 sorted = session_dirs;
2045                 sort (sorted.begin(), sorted.end(), cmp);
2046
2047                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2048                         if (create_session_directory ((*i).path)) {
2049                                 result = (*i).path;
2050                                 last_rr_session_dir = i;
2051                                 return result;
2052                         }
2053                 }
2054         }
2055
2056         return result;
2057 }
2058
2059 int
2060 Session::load_named_selections (const XMLNode& node)
2061 {
2062         XMLNodeList nlist;
2063         XMLNodeConstIterator niter;
2064         NamedSelection *ns;
2065
2066         nlist = node.children();
2067
2068         set_dirty();
2069
2070         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2071
2072                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2073                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2074                 }
2075         }
2076
2077         return 0;
2078 }
2079
2080 NamedSelection *
2081 Session::XMLNamedSelectionFactory (const XMLNode& node)
2082 {
2083         try {
2084                 return new NamedSelection (*this, node);
2085         }
2086
2087         catch (failed_constructor& err) {
2088                 return 0;
2089         }
2090 }
2091
2092 string
2093 Session::automation_dir () const
2094 {
2095         return Glib::build_filename (_path, "automation");
2096 }
2097
2098 string
2099 Session::analysis_dir () const
2100 {
2101         return Glib::build_filename (_path, "analysis");
2102 }
2103
2104 int
2105 Session::load_bundles (XMLNode const & node)
2106 {
2107         XMLNodeList nlist = node.children();
2108         XMLNodeConstIterator niter;
2109
2110         set_dirty();
2111
2112         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2113                 if ((*niter)->name() == "InputBundle") {
2114                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2115                 } else if ((*niter)->name() == "OutputBundle") {
2116                         add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2117                 } else {
2118                         error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2119                         return -1;
2120                 }
2121         }
2122
2123         return 0;
2124 }
2125
2126 int
2127 Session::load_route_groups (const XMLNode& node, int version)
2128 {
2129         XMLNodeList nlist = node.children();
2130         XMLNodeConstIterator niter;
2131
2132         set_dirty ();
2133
2134         if (version >= 3000) {
2135                 
2136                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2137                         if ((*niter)->name() == "RouteGroup") {
2138                                 RouteGroup* rg = new RouteGroup (*this, "");
2139                                 add_route_group (rg);
2140                                 rg->set_state (**niter, version);
2141                         }
2142                 }
2143
2144         } else if (version < 3000) {
2145
2146                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2147                         if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2148                                 RouteGroup* rg = new RouteGroup (*this, "");
2149                                 add_route_group (rg);
2150                                 rg->set_state (**niter, version);
2151                         }
2152                 }
2153         }
2154
2155         return 0;
2156 }
2157
2158 void
2159 Session::auto_save()
2160 {
2161         save_state (_current_snapshot_name);
2162 }
2163
2164 static bool
2165 state_file_filter (const string &str, void */*arg*/)
2166 {
2167         return (str.length() > strlen(statefile_suffix) &&
2168                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2169 }
2170
2171 struct string_cmp {
2172         bool operator()(const string* a, const string* b) {
2173                 return *a < *b;
2174         }
2175 };
2176
2177 static string*
2178 remove_end(string* state)
2179 {
2180         string statename(*state);
2181
2182         string::size_type start,end;
2183         if ((start = statename.find_last_of ('/')) != string::npos) {
2184                 statename = statename.substr (start+1);
2185         }
2186
2187         if ((end = statename.rfind(".ardour")) == string::npos) {
2188                 end = statename.length();
2189         }
2190
2191         return new string(statename.substr (0, end));
2192 }
2193
2194 vector<string *> *
2195 Session::possible_states (string path)
2196 {
2197         PathScanner scanner;
2198         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2199
2200         transform(states->begin(), states->end(), states->begin(), remove_end);
2201
2202         string_cmp cmp;
2203         sort (states->begin(), states->end(), cmp);
2204
2205         return states;
2206 }
2207
2208 vector<string *> *
2209 Session::possible_states () const
2210 {
2211         return possible_states(_path);
2212 }
2213
2214 void
2215 Session::add_route_group (RouteGroup* g)
2216 {
2217         _route_groups.push_back (g);
2218         route_group_added (g); /* EMIT SIGNAL */
2219         set_dirty ();
2220 }
2221
2222 void
2223 Session::remove_route_group (RouteGroup& rg)
2224 {
2225         list<RouteGroup*>::iterator i;
2226
2227         if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2228                 _route_groups.erase (i);
2229                 delete &rg;
2230
2231                 route_group_removed (); /* EMIT SIGNAL */
2232         }
2233
2234 }
2235
2236 RouteGroup *
2237 Session::route_group_by_name (string name)
2238 {
2239         list<RouteGroup *>::iterator i;
2240
2241         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2242                 if ((*i)->name() == name) {
2243                         return* i;
2244                 }
2245         }
2246         return 0;
2247 }
2248
2249 UndoTransaction*
2250 Session::start_reversible_command (const string& name)
2251 {
2252         UndoTransaction* trans = new UndoTransaction();
2253         trans->set_name(name);
2254         return trans;
2255 }
2256
2257 void
2258 Session::finish_reversible_command (UndoTransaction& ut)
2259 {
2260         struct timeval now;
2261         gettimeofday(&now, 0);
2262         ut.set_timestamp(now);
2263         _history.add (&ut);
2264 }
2265
2266 void
2267 Session::begin_reversible_command(const string& name)
2268 {
2269         UndoTransaction* trans = new UndoTransaction();
2270         trans->set_name(name);
2271
2272         if (!_current_trans.empty()) {
2273                 _current_trans.top()->add_command (trans);
2274         } else {
2275                 _current_trans.push(trans);
2276         }
2277 }
2278
2279 void
2280 Session::commit_reversible_command(Command *cmd)
2281 {
2282         assert(!_current_trans.empty());
2283         struct timeval now;
2284
2285         if (cmd) {
2286                 _current_trans.top()->add_command(cmd);
2287         }
2288
2289         if (_current_trans.top()->empty()) {
2290                 _current_trans.pop();
2291                 return;
2292         }
2293
2294         gettimeofday(&now, 0);
2295         _current_trans.top()->set_timestamp(now);
2296
2297         _history.add(_current_trans.top());
2298         _current_trans.pop();
2299 }
2300
2301 static bool
2302 accept_all_non_peak_files (const string& path, void */*arg*/)
2303 {
2304         return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2305 }
2306
2307 static bool
2308 accept_all_state_files (const string& path, void */*arg*/)
2309 {
2310         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2311 }
2312
2313 int
2314 Session::find_all_sources (string path, set<string>& result)
2315 {
2316         XMLTree tree;
2317         XMLNode* node;
2318
2319         if (!tree.read (path)) {
2320                 return -1;
2321         }
2322
2323         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2324                 return -2;
2325         }
2326
2327         XMLNodeList nlist;
2328         XMLNodeConstIterator niter;
2329
2330         nlist = node->children();
2331
2332         set_dirty();
2333
2334         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2335
2336                 XMLProperty* prop;
2337
2338                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2339                         continue;
2340                 }
2341
2342                 DataType type (prop->value());
2343
2344                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2345                         continue;
2346                 }
2347
2348                 if (prop->value()[0] == '/') {
2349                         /* external file, ignore */
2350                         continue;
2351                 }
2352
2353                 Glib::ustring found_path;
2354                 bool is_new;
2355                 uint16_t chan;
2356
2357                 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2358                         result.insert (found_path);
2359                 }
2360         }
2361
2362         return 0;
2363 }
2364
2365 int
2366 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2367 {
2368         PathScanner scanner;
2369         vector<string*>* state_files;
2370         string ripped;
2371         string this_snapshot_path;
2372
2373         result.clear ();
2374
2375         ripped = _path;
2376
2377         if (ripped[ripped.length()-1] == '/') {
2378                 ripped = ripped.substr (0, ripped.length() - 1);
2379         }
2380
2381         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2382
2383         if (state_files == 0) {
2384                 /* impossible! */
2385                 return 0;
2386         }
2387
2388         this_snapshot_path = _path;
2389         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2390         this_snapshot_path += statefile_suffix;
2391
2392         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2393
2394                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2395                         continue;
2396                 }
2397
2398                 if (find_all_sources (**i, result) < 0) {
2399                         return -1;
2400                 }
2401         }
2402
2403         return 0;
2404 }
2405
2406 struct RegionCounter {
2407     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2408     AudioSourceList::iterator iter;
2409     boost::shared_ptr<Region> region;
2410     uint32_t count;
2411
2412     RegionCounter() : count (0) {}
2413 };
2414
2415 int
2416 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2417 {
2418         return *AskAboutPlaylistDeletion (p);
2419 }
2420
2421 int
2422 Session::cleanup_sources (CleanupReport& rep)
2423 {
2424         // FIXME: needs adaptation to midi
2425
2426         vector<boost::shared_ptr<Source> > dead_sources;
2427         PathScanner scanner;
2428         string sound_path;
2429         vector<space_and_path>::iterator i;
2430         vector<space_and_path>::iterator nexti;
2431         vector<string*>* soundfiles;
2432         vector<string> unused;
2433         set<string> all_sources;
2434         bool used;
2435         string spath;
2436         int ret = -1;
2437
2438         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2439
2440         /* step 1: consider deleting all unused playlists */
2441         
2442         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2443                 ret = 0;
2444                 goto out;
2445         }
2446
2447         /* step 2: find all un-used sources */
2448
2449         rep.paths.clear ();
2450         rep.space = 0;
2451
2452         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2453
2454                 SourceMap::iterator tmp;
2455
2456                 tmp = i;
2457                 ++tmp;
2458
2459                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2460                    capture files.
2461                 */
2462
2463                 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2464                         dead_sources.push_back (i->second);
2465                         i->second->drop_references ();
2466                 }
2467
2468                 i = tmp;
2469         }
2470
2471         /* build a list of all the possible sound directories for the session */
2472
2473         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2474
2475                 nexti = i;
2476                 ++nexti;
2477
2478                 SessionDirectory sdir ((*i).path);
2479                 sound_path += sdir.sound_path().to_string();
2480
2481                 if (nexti != session_dirs.end()) {
2482                         sound_path += ':';
2483                 }
2484
2485                 i = nexti;
2486         }
2487
2488         /* now do the same thing for the files that ended up in the sounds dir(s)
2489            but are not referenced as sources in any snapshot.
2490         */
2491
2492         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2493
2494         if (soundfiles == 0) {
2495                 return 0;
2496         }
2497
2498         /* find all sources, but don't use this snapshot because the
2499            state file on disk still references sources we may have already
2500            dropped.
2501         */
2502
2503         find_all_sources_across_snapshots (all_sources, true);
2504
2505         /*  add our current source list
2506          */
2507
2508         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2509                 boost::shared_ptr<FileSource> fs;
2510
2511                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2512                         all_sources.insert (fs->path());
2513                 }
2514         }
2515
2516         char tmppath1[PATH_MAX+1];
2517         char tmppath2[PATH_MAX+1];
2518
2519         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2520
2521                 used = false;
2522                 spath = **x;
2523
2524                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2525
2526                         realpath(spath.c_str(), tmppath1);
2527                         realpath((*i).c_str(),  tmppath2);
2528
2529                         if (strcmp(tmppath1, tmppath2) == 0) {
2530                                 used = true;
2531                                 break;
2532                         }
2533                 }
2534
2535                 if (!used) {
2536                         unused.push_back (spath);
2537                 }
2538         }
2539
2540         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2541
2542         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2543                 struct stat statbuf;
2544
2545                 rep.paths.push_back (*x);
2546                 if (stat ((*x).c_str(), &statbuf) == 0) {
2547                         rep.space += statbuf.st_size;
2548                 }
2549
2550                 string newpath;
2551
2552                 /* don't move the file across filesystems, just
2553                    stick it in the `dead_sound_dir_name' directory
2554                    on whichever filesystem it was already on.
2555                 */
2556
2557                 if ((*x).find ("/sounds/") != string::npos) {
2558
2559                         /* old school, go up 1 level */
2560
2561                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2562                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2563
2564                 } else {
2565
2566                         /* new school, go up 4 levels */
2567
2568                         newpath = Glib::path_get_dirname (*x);      // "audiofiles"
2569                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2570                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2571                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2572                 }
2573
2574                 newpath += '/';
2575                 newpath += dead_sound_dir_name;
2576
2577                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2578                         error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2579                         return -1;
2580                 }
2581
2582                 newpath += '/';
2583                 newpath += Glib::path_get_basename ((*x));
2584
2585                 if (access (newpath.c_str(), F_OK) == 0) {
2586
2587                         /* the new path already exists, try versioning */
2588
2589                         char buf[PATH_MAX+1];
2590                         int version = 1;
2591                         string newpath_v;
2592
2593                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2594                         newpath_v = buf;
2595
2596                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2597                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2598                                 newpath_v = buf;
2599                         }
2600
2601                         if (version == 999) {
2602                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2603                                                   newpath)
2604                                       << endmsg;
2605                         } else {
2606                                 newpath = newpath_v;
2607                         }
2608
2609                 } else {
2610
2611                         /* it doesn't exist, or we can't read it or something */
2612
2613                 }
2614
2615                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2616                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2617                                           (*x), newpath, strerror (errno))
2618                               << endmsg;
2619                         goto out;
2620                 }
2621
2622                 /* see if there an easy to find peakfile for this file, and remove it.
2623                  */
2624
2625                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2626                 peakpath += peakfile_suffix;
2627
2628                 if (access (peakpath.c_str(), W_OK) == 0) {
2629                         if (::unlink (peakpath.c_str()) != 0) {
2630                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2631                                                   peakpath, _path, strerror (errno))
2632                                       << endmsg;
2633                                 /* try to back out */
2634                                 rename (newpath.c_str(), _path.c_str());
2635                                 goto out;
2636                         }
2637                 }
2638         }
2639
2640         ret = 0;
2641
2642         /* dump the history list */
2643
2644         _history.clear ();
2645
2646         /* save state so we don't end up a session file
2647            referring to non-existent sources.
2648         */
2649
2650         save_state ("");
2651
2652   out:
2653         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2654
2655         return ret;
2656 }
2657
2658 int
2659 Session::cleanup_trash_sources (CleanupReport& rep)
2660 {
2661         // FIXME: needs adaptation for MIDI
2662
2663         vector<space_and_path>::iterator i;
2664         string dead_sound_dir;
2665         struct dirent* dentry;
2666         struct stat statbuf;
2667         DIR* dead;
2668
2669         rep.paths.clear ();
2670         rep.space = 0;
2671
2672         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2673
2674                 dead_sound_dir = (*i).path;
2675                 dead_sound_dir += dead_sound_dir_name;
2676
2677                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2678                         continue;
2679                 }
2680
2681                 while ((dentry = readdir (dead)) != 0) {
2682
2683                         /* avoid '.' and '..' */
2684
2685                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2686                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2687                                 continue;
2688                         }
2689
2690                         string fullpath;
2691
2692                         fullpath = dead_sound_dir;
2693                         fullpath += '/';
2694                         fullpath += dentry->d_name;
2695
2696                         if (stat (fullpath.c_str(), &statbuf)) {
2697                                 continue;
2698                         }
2699
2700                         if (!S_ISREG (statbuf.st_mode)) {
2701                                 continue;
2702                         }
2703
2704                         if (unlink (fullpath.c_str())) {
2705                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2706                                                   fullpath, strerror (errno))
2707                                       << endmsg;
2708                         }
2709
2710                         rep.paths.push_back (dentry->d_name);
2711                         rep.space += statbuf.st_size;
2712                 }
2713
2714                 closedir (dead);
2715
2716         }
2717
2718         return 0;
2719 }
2720
2721 void
2722 Session::set_dirty ()
2723 {
2724         bool was_dirty = dirty();
2725
2726         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2727
2728
2729         if (!was_dirty) {
2730                 DirtyChanged(); /* EMIT SIGNAL */
2731         }
2732 }
2733
2734
2735 void
2736 Session::set_clean ()
2737 {
2738         bool was_dirty = dirty();
2739
2740         _state_of_the_state = Clean;
2741
2742
2743         if (was_dirty) {
2744                 DirtyChanged(); /* EMIT SIGNAL */
2745         }
2746 }
2747
2748 void
2749 Session::set_deletion_in_progress ()
2750 {
2751         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2752 }
2753
2754 void
2755 Session::clear_deletion_in_progress ()
2756 {
2757         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2758 }
2759
2760 void
2761 Session::add_controllable (boost::shared_ptr<Controllable> c)
2762 {
2763         /* this adds a controllable to the list managed by the Session.
2764            this is a subset of those managed by the Controllable class
2765            itself, and represents the only ones whose state will be saved
2766            as part of the session.
2767         */
2768
2769         Glib::Mutex::Lock lm (controllables_lock);
2770         controllables.insert (c);
2771 }
2772
2773 struct null_deleter { void operator()(void const *) const {} };
2774
2775 void
2776 Session::remove_controllable (Controllable* c)
2777 {
2778         if (_state_of_the_state | Deletion) {
2779                 return;
2780         }
2781
2782         Glib::Mutex::Lock lm (controllables_lock);
2783
2784         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2785
2786         if (x != controllables.end()) {
2787                 controllables.erase (x);
2788         }
2789 }
2790
2791 boost::shared_ptr<Controllable>
2792 Session::controllable_by_id (const PBD::ID& id)
2793 {
2794         Glib::Mutex::Lock lm (controllables_lock);
2795
2796         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2797                 if ((*i)->id() == id) {
2798                         return *i;
2799                 }
2800         }
2801
2802         return boost::shared_ptr<Controllable>();
2803 }
2804
2805 boost::shared_ptr<Controllable>
2806 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2807 {
2808         boost::shared_ptr<Controllable> c;
2809         boost::shared_ptr<Route> r;
2810
2811         switch (desc.top_level_type()) {
2812         case ControllableDescriptor::NamedRoute:
2813         {
2814                 std::string str = desc.top_level_name();
2815                 if (str == "master") {
2816                         r = _master_out;
2817                 } else if (str == "control" || str == "listen") {
2818                         r = _monitor_out;
2819                 } else {
2820                         r = route_by_name (desc.top_level_name());
2821                 }
2822                 break;
2823         }
2824
2825         case ControllableDescriptor::RemoteControlID:
2826                 r = route_by_remote_id (desc.rid());
2827                 break;
2828         }
2829         
2830         if (!r) {
2831                 return c;
2832         }
2833
2834         switch (desc.subtype()) {
2835         case ControllableDescriptor::Gain:
2836                 c = r->gain_control ();
2837                 break;
2838
2839         case ControllableDescriptor::Solo:
2840                 c = r->solo_control();
2841                 break;
2842
2843         case ControllableDescriptor::Mute:
2844                 c = r->mute_control();
2845                 break;
2846
2847         case ControllableDescriptor::Recenable:
2848         {
2849                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2850                 
2851                 if (t) {
2852                         c = t->rec_enable_control ();
2853                 }
2854                 break;
2855         }
2856
2857         case ControllableDescriptor::Pan:
2858                 /* XXX pan control */
2859                 break;
2860
2861         case ControllableDescriptor::Balance:
2862                 /* XXX simple pan control */
2863                 break;
2864
2865         case ControllableDescriptor::PluginParameter:
2866         {
2867                 uint32_t plugin = desc.target (0);
2868                 uint32_t parameter_index = desc.target (1);
2869
2870                 /* revert to zero based counting */
2871                 
2872                 if (plugin > 0) {
2873                         --plugin;
2874                 }
2875                 
2876                 if (parameter_index > 0) {
2877                         --parameter_index;
2878                 }
2879
2880                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2881                 
2882                 if (p) {
2883                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2884                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2885                 }
2886                 break;
2887         }
2888
2889         case ControllableDescriptor::SendGain: 
2890         {
2891                 uint32_t send = desc.target (0);
2892
2893                 /* revert to zero-based counting */
2894                 
2895                 if (send > 0) {
2896                         --send;
2897                 }
2898                 
2899                 boost::shared_ptr<Processor> p = r->nth_send (send);
2900                 
2901                 if (p) {
2902                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2903                         boost::shared_ptr<Amp> a = s->amp();
2904
2905                         if (a) {
2906                                 c = s->amp()->gain_control();
2907                         }
2908                 }
2909                 break;
2910         }
2911
2912         default:
2913                 /* relax and return a null pointer */
2914                 break;
2915         }
2916
2917         return c;
2918 }
2919
2920 void
2921 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2922 {
2923         if (_writable) {
2924                 Stateful::add_instant_xml (node, _path);
2925         }
2926
2927         if (write_to_config) {
2928                 Config->add_instant_xml (node);
2929         }
2930 }
2931
2932 XMLNode*
2933 Session::instant_xml (const string& node_name)
2934 {
2935         return Stateful::instant_xml (node_name, _path);
2936 }
2937
2938 int
2939 Session::save_history (string snapshot_name)
2940 {
2941         XMLTree tree;
2942
2943         if (!_writable) {
2944                 return 0;
2945         }
2946
2947         if (snapshot_name.empty()) {
2948                 snapshot_name = _current_snapshot_name;
2949         }
2950
2951         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2952         const string backup_filename = history_filename + backup_suffix;
2953         const sys::path xml_path = _session_dir->root_path() / history_filename;
2954         const sys::path backup_path = _session_dir->root_path() / backup_filename;
2955
2956         if (sys::exists (xml_path)) {
2957                 try
2958                 {
2959                         sys::rename (xml_path, backup_path);
2960                 }
2961                 catch (const sys::filesystem_error& err)
2962                 {
2963                         error << _("could not backup old history file, current history not saved") << endmsg;
2964                         return -1;
2965                 }
2966         }
2967
2968         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2969                 return 0;
2970         }
2971
2972         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2973
2974         if (!tree.write (xml_path.to_string()))
2975         {
2976                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2977
2978                 try
2979                 {
2980                         sys::remove (xml_path);
2981                         sys::rename (backup_path, xml_path);
2982                 }
2983                 catch (const sys::filesystem_error& err)
2984                 {
2985                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
2986                                         backup_path.to_string(), err.what()) << endmsg;
2987                 }
2988
2989                 return -1;
2990         }
2991
2992         return 0;
2993 }
2994
2995 int
2996 Session::restore_history (string snapshot_name)
2997 {
2998         XMLTree tree;
2999
3000         if (snapshot_name.empty()) {
3001                 snapshot_name = _current_snapshot_name;
3002         }
3003
3004         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3005         const sys::path xml_path = _session_dir->root_path() / xml_filename;
3006
3007         info << "Loading history from " << xml_path.to_string() << endmsg;
3008
3009         if (!sys::exists (xml_path)) {
3010                 info << string_compose (_("%1: no history file \"%2\" for this session."),
3011                                 _name, xml_path.to_string()) << endmsg;
3012                 return 1;
3013         }
3014
3015         if (!tree.read (xml_path.to_string())) {
3016                 error << string_compose (_("Could not understand session history file \"%1\""),
3017                                 xml_path.to_string()) << endmsg;
3018                 return -1;
3019         }
3020
3021         // replace history
3022         _history.clear();
3023
3024         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3025
3026                 XMLNode *t = *it;
3027                 UndoTransaction* ut = new UndoTransaction ();
3028                 struct timeval tv;
3029
3030                 ut->set_name(t->property("name")->value());
3031                 stringstream ss(t->property("tv-sec")->value());
3032                 ss >> tv.tv_sec;
3033                 ss.str(t->property("tv-usec")->value());
3034                 ss >> tv.tv_usec;
3035                 ut->set_timestamp(tv);
3036
3037                 for (XMLNodeConstIterator child_it  = t->children().begin();
3038                                 child_it != t->children().end(); child_it++)
3039                 {
3040                         XMLNode *n = *child_it;
3041                         Command *c;
3042
3043                         if (n->name() == "MementoCommand" ||
3044                                         n->name() == "MementoUndoCommand" ||
3045                                         n->name() == "MementoRedoCommand") {
3046
3047                                 if ((c = memento_command_factory(n))) {
3048                                         ut->add_command(c);
3049                                 }
3050
3051                         } else if (n->name() == "DeltaCommand") {
3052                                 PBD::ID  id(n->property("midi-source")->value());
3053                                 boost::shared_ptr<MidiSource> midi_source =
3054                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3055                                 if (midi_source) {
3056                                         ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3057                                 } else {
3058                                         error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3059                                 }
3060
3061                         } else if (n->name() == "DiffCommand") {
3062                                 PBD::ID  id(n->property("midi-source")->value());
3063                                 boost::shared_ptr<MidiSource> midi_source =
3064                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3065                                 if (midi_source) {
3066                                         ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3067                                 } else {
3068                                         error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3069                                 }
3070
3071                         } else if (n->name() == "StatefulDiffCommand") {
3072                                 if ((c = stateful_diff_command_factory (n))) {
3073                                         ut->add_command (c);
3074                                 }
3075                         } else {
3076                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3077                         }
3078                 }
3079
3080                 _history.add (ut);
3081         }
3082
3083         return 0;
3084 }
3085
3086 void
3087 Session::config_changed (std::string p, bool ours)
3088 {
3089         if (ours) {
3090                 set_dirty ();
3091         }
3092
3093         if (p == "seamless-loop") {
3094
3095         } else if (p == "rf-speed") {
3096
3097         } else if (p == "auto-loop") {
3098
3099         } else if (p == "auto-input") {
3100
3101                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3102                         /* auto-input only makes a difference if we're rolling */
3103
3104                         boost::shared_ptr<RouteList> rl = routes.reader ();
3105                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3106                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3107                                 if (tr && tr->record_enabled ()) {
3108                                         tr->monitor_input (!config.get_auto_input());
3109                                 }
3110                         }
3111                 }
3112
3113         } else if (p == "punch-in") {
3114
3115                 Location* location;
3116
3117                 if ((location = _locations.auto_punch_location()) != 0) {
3118
3119                         if (config.get_punch_in ()) {
3120                                 replace_event (SessionEvent::PunchIn, location->start());
3121                         } else {
3122                                 remove_event (location->start(), SessionEvent::PunchIn);
3123                         }
3124                 }
3125
3126         } else if (p == "punch-out") {
3127
3128                 Location* location;
3129
3130                 if ((location = _locations.auto_punch_location()) != 0) {
3131
3132                         if (config.get_punch_out()) {
3133                                 replace_event (SessionEvent::PunchOut, location->end());
3134                         } else {
3135                                 clear_events (SessionEvent::PunchOut);
3136                         }
3137                 }
3138
3139         } else if (p == "edit-mode") {
3140
3141                 Glib::Mutex::Lock lm (playlists->lock);
3142
3143                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3144                         (*i)->set_edit_mode (Config->get_edit_mode ());
3145                 }
3146
3147         } else if (p == "use-video-sync") {
3148
3149                 waiting_for_sync_offset = config.get_use_video_sync();
3150
3151         } else if (p == "mmc-control") {
3152
3153                 //poke_midi_thread ();
3154
3155         } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3156
3157                 if (mmc) {
3158                         mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3159                 }
3160
3161         } else if (p == "mmc-send-id") {
3162
3163                 if (mmc) {
3164                         mmc->set_send_device_id (Config->get_mmc_send_device_id());
3165                 }
3166
3167         } else if (p == "midi-control") {
3168
3169                 //poke_midi_thread ();
3170
3171         } else if (p == "raid-path") {
3172
3173                 setup_raid_path (config.get_raid_path());
3174
3175         } else if (p == "timecode-format") {
3176
3177                 sync_time_vars ();
3178
3179         } else if (p == "video-pullup") {
3180
3181                 sync_time_vars ();
3182
3183         } else if (p == "seamless-loop") {
3184
3185                 if (play_loop && transport_rolling()) {
3186                         // to reset diskstreams etc
3187                         request_play_loop (true);
3188                 }
3189
3190         } else if (p == "rf-speed") {
3191
3192                 cumulative_rf_motion = 0;
3193                 reset_rf_scale (0);
3194
3195         } else if (p == "click-sound") {
3196
3197                 setup_click_sounds (1);
3198
3199         } else if (p == "click-emphasis-sound") {
3200
3201                 setup_click_sounds (-1);
3202
3203         } else if (p == "clicking") {
3204
3205                 if (Config->get_clicking()) {
3206                         if (_click_io && click_data) { // don't require emphasis data
3207                                 _clicking = true;
3208                         }
3209                 } else {
3210                         _clicking = false;
3211                 }
3212
3213         } else if (p == "send-mtc") {
3214
3215                 /* only set the internal flag if we have
3216                    a port.
3217                 */
3218
3219                 if (_mtc_port != 0) {
3220                         session_send_mtc = Config->get_send_mtc();
3221                         if (session_send_mtc) {
3222                                 /* mark us ready to send */
3223                                 next_quarter_frame_to_send = 0;
3224                         }
3225                 } else {
3226                         session_send_mtc = false;
3227                 }
3228
3229         } else if (p == "send-mmc") {
3230
3231                 /* only set the internal flag if we have
3232                    a port.
3233                 */
3234
3235                 if (_mmc_port != 0) {
3236                         session_send_mmc = Config->get_send_mmc();
3237                 } else {
3238                         mmc = 0;
3239                         session_send_mmc = false;
3240                 }
3241
3242         } else if (p == "midi-feedback") {
3243
3244                 /* only set the internal flag if we have
3245                    a port.
3246                 */
3247
3248                 if (_mtc_port != 0) {
3249                         session_midi_feedback = Config->get_midi_feedback();
3250                 }
3251
3252         } else if (p == "jack-time-master") {
3253
3254                 engine().reset_timebase ();
3255
3256         } else if (p == "native-file-header-format") {
3257
3258                 if (!first_file_header_format_reset) {
3259                         reset_native_file_format ();
3260                 }
3261
3262                 first_file_header_format_reset = false;
3263
3264         } else if (p == "native-file-data-format") {
3265
3266                 if (!first_file_data_format_reset) {
3267                         reset_native_file_format ();
3268                 }
3269
3270                 first_file_data_format_reset = false;
3271
3272         } else if (p == "external-sync") {
3273                 if (!config.get_external_sync()) {
3274                         drop_sync_source ();
3275                 } else {
3276                         switch_to_sync_source (config.get_sync_source());
3277                 }
3278         } else if (p == "remote-model") {
3279                 set_remote_control_ids ();
3280         }  else if (p == "denormal-model") {
3281                 setup_fpu ();
3282         } else if (p == "history-depth") {
3283                 set_history_depth (Config->get_history_depth());
3284         } else if (p == "sync-all-route-ordering") {
3285                 sync_order_keys ("session");
3286         } else if (p == "initial-program-change") {
3287
3288                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3289                         MIDI::byte buf[2];
3290
3291                         buf[0] = MIDI::program; // channel zero by default
3292                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3293
3294                         _mmc_port->midimsg (buf, sizeof (buf), 0);
3295                 }
3296         } else if (p == "initial-program-change") {
3297
3298                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3299                         MIDI::byte* buf = new MIDI::byte[2];
3300
3301                         buf[0] = MIDI::program; // channel zero by default
3302                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3303                         // deliver_midi (_mmc_port, buf, 2);
3304                 }
3305         } else if (p == "solo-mute-override") {
3306                 // catch_up_on_solo_mute_override ();
3307         } else if (p == "listen-position") {
3308                 listen_position_changed ();
3309         } else if (p == "solo-control-is-listen-control") {
3310                 solo_control_mode_changed ();
3311         }
3312
3313
3314         set_dirty ();
3315 }
3316
3317 void
3318 Session::set_history_depth (uint32_t d)
3319 {
3320         _history.set_depth (d);
3321 }
3322
3323 int
3324 Session::load_diskstreams_2X (XMLNode const & node, int)
3325 {
3326         XMLNodeList          clist;
3327         XMLNodeConstIterator citer;
3328
3329         clist = node.children();
3330
3331         for (citer = clist.begin(); citer != clist.end(); ++citer) {
3332
3333                 try {
3334                         /* diskstreams added automatically by DiskstreamCreated handler */
3335                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3336                                 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3337                                 _diskstreams_2X.push_back (dsp);
3338                         } else {
3339                                 error << _("Session: unknown diskstream type in XML") << endmsg;
3340                         }
3341                 }
3342
3343                 catch (failed_constructor& err) {
3344                         error << _("Session: could not load diskstream via XML state") << endmsg;
3345                         return -1;
3346                 }
3347         }
3348
3349         return 0;
3350 }