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