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