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