Allow edit group creation from the route UI's menu. Allow new tracks to be put in...
[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
2062         set_dirty();
2063
2064         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2065                 if ((*niter)->name() == "RouteGroup") {
2066                         RouteGroup* rg = new RouteGroup (*this, "");
2067                         if (edit) {
2068                                 add_edit_group (rg);
2069                                 rg->set_state (**niter);
2070                         } else {
2071                                 add_mix_group (rg);
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 void
2137 Session::add_edit_group (RouteGroup* g)
2138 {
2139         edit_groups.push_back (g);
2140         edit_group_added (g); /* EMIT SIGNAL */
2141         set_dirty ();
2142 }
2143
2144 void
2145 Session::add_mix_group (RouteGroup* g)
2146 {
2147         mix_groups.push_back (g);
2148         mix_group_added (g); /* EMIT SIGNAL */
2149         set_dirty ();
2150 }
2151
2152 void
2153 Session::remove_edit_group (RouteGroup& rg)
2154 {
2155         list<RouteGroup*>::iterator i;
2156
2157         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2158                 (*i)->apply (&Route::drop_edit_group, this);
2159                 edit_groups.erase (i);
2160                 edit_group_removed (); /* EMIT SIGNAL */
2161         }
2162
2163         delete &rg;
2164 }
2165
2166 void
2167 Session::remove_mix_group (RouteGroup& rg)
2168 {
2169         list<RouteGroup*>::iterator i;
2170
2171         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2172                 (*i)->apply (&Route::drop_mix_group, this);
2173                 mix_groups.erase (i);
2174                 mix_group_removed (); /* EMIT SIGNAL */
2175         }
2176
2177         delete &rg;
2178 }
2179
2180 RouteGroup *
2181 Session::mix_group_by_name (string name)
2182 {
2183         list<RouteGroup *>::iterator i;
2184
2185         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2186                 if ((*i)->name() == name) {
2187                         return* i;
2188                 }
2189         }
2190         return 0;
2191 }
2192
2193 RouteGroup *
2194 Session::edit_group_by_name (string name)
2195 {
2196         list<RouteGroup *>::iterator i;
2197
2198         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2199                 if ((*i)->name() == name) {
2200                         return* i;
2201                 }
2202         }
2203         return 0;
2204 }
2205
2206 void
2207 Session::begin_reversible_command(const string& name)
2208 {
2209         UndoTransaction* trans = new UndoTransaction();
2210         trans->set_name(name);
2211         if (!_current_trans.empty()) {
2212                 _current_trans.top()->add_command(trans);
2213         }
2214         _current_trans.push(trans);
2215 }
2216
2217 void
2218 Session::commit_reversible_command(Command *cmd)
2219 {
2220         assert(!_current_trans.empty());
2221         struct timeval now;
2222
2223         if (cmd) {
2224                 _current_trans.top()->add_command(cmd);
2225         }
2226
2227         if (_current_trans.top()->empty()) {
2228                 _current_trans.pop();
2229                 return;
2230         }
2231
2232         gettimeofday(&now, 0);
2233         _current_trans.top()->set_timestamp(now);
2234
2235         _history.add(_current_trans.top());
2236         _current_trans.pop();
2237 }
2238
2239 Session::GlobalRouteBooleanState 
2240 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2241 {
2242         GlobalRouteBooleanState s;
2243         boost::shared_ptr<RouteList> r = routes.reader ();
2244
2245         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2246                 if (!(*i)->is_hidden()) {
2247                         RouteBooleanState v;
2248                         
2249                         v.first =* i;
2250                         Route* r = (*i).get();
2251                         v.second = (r->*method)();
2252                         
2253                         s.push_back (v);
2254                 }
2255         }
2256
2257         return s;
2258 }
2259
2260 Session::GlobalRouteMeterState
2261 Session::get_global_route_metering ()
2262 {
2263         GlobalRouteMeterState s;
2264         boost::shared_ptr<RouteList> r = routes.reader ();
2265
2266         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267                 if (!(*i)->is_hidden()) {
2268                         RouteMeterState v;
2269                         
2270                         v.first =* i;
2271                         v.second = (*i)->meter_point();
2272                         
2273                         s.push_back (v);
2274                 }
2275         }
2276
2277         return s;
2278 }
2279
2280 void
2281 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2282 {
2283         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2284
2285                 boost::shared_ptr<Route> r = (i->first.lock());
2286
2287                 if (r) {
2288                         r->set_meter_point (i->second, arg);
2289                 }
2290         }
2291 }
2292
2293 void
2294 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2295 {
2296         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2297
2298                 boost::shared_ptr<Route> r = (i->first.lock());
2299
2300                 if (r) {
2301                         Route* rp = r.get();
2302                         (rp->*method) (i->second, arg);
2303                 }
2304         }
2305 }
2306
2307 void
2308 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2309 {
2310         set_global_route_boolean (s, &Route::set_mute, src);
2311 }
2312
2313 void
2314 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2315 {
2316         set_global_route_boolean (s, &Route::set_solo, src);
2317 }
2318
2319 void
2320 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2321 {
2322         set_global_route_boolean (s, &Route::set_record_enable, src);
2323 }
2324
2325 static bool
2326 accept_all_non_peak_files (const string& path, void *arg)
2327 {
2328         return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2329 }
2330
2331 static bool
2332 accept_all_state_files (const string& path, void *arg)
2333 {
2334         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2335 }
2336
2337 int 
2338 Session::find_all_sources (string path, set<string>& result)
2339 {
2340         XMLTree tree;
2341         XMLNode* node;
2342
2343         if (!tree.read (path)) {
2344                 return -1;
2345         }
2346
2347         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2348                 return -2;
2349         }
2350
2351         XMLNodeList nlist;
2352         XMLNodeConstIterator niter;
2353
2354         nlist = node->children();
2355
2356         set_dirty();
2357
2358         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2359                 
2360                 XMLProperty* prop;
2361
2362                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2363                         continue;
2364                 }
2365
2366                 if (prop->value()[0] == '/') {
2367                         /* external file, ignore */
2368                         continue;
2369                 }
2370
2371                 sys::path source_path = _session_dir->sound_path ();
2372
2373                 source_path /= prop->value ();
2374
2375                 result.insert (source_path.to_string ());
2376         }
2377
2378         return 0;
2379 }
2380
2381 int
2382 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2383 {
2384         PathScanner scanner;
2385         vector<string*>* state_files;
2386         string ripped;
2387         string this_snapshot_path;
2388
2389         result.clear ();
2390
2391         ripped = _path;
2392
2393         if (ripped[ripped.length()-1] == '/') {
2394                 ripped = ripped.substr (0, ripped.length() - 1);
2395         }
2396
2397         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2398         
2399         if (state_files == 0) {
2400                 /* impossible! */
2401                 return 0;
2402         }
2403
2404         this_snapshot_path = _path;
2405         this_snapshot_path += _current_snapshot_name;
2406         this_snapshot_path += statefile_suffix;
2407
2408         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2409
2410                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2411                         continue;
2412                 }
2413
2414                 if (find_all_sources (**i, result) < 0) {
2415                         return -1;
2416                 }
2417         }
2418
2419         return 0;
2420 }
2421
2422 struct RegionCounter {
2423     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2424     AudioSourceList::iterator iter;
2425     boost::shared_ptr<Region> region;
2426     uint32_t count;
2427     
2428     RegionCounter() : count (0) {}
2429 };
2430
2431 int
2432 Session::cleanup_sources (Session::cleanup_report& rep)
2433 {
2434         // FIXME: needs adaptation to midi
2435         
2436         vector<boost::shared_ptr<Source> > dead_sources;
2437         vector<boost::shared_ptr<Playlist> > playlists_tbd;
2438         PathScanner scanner;
2439         string sound_path;
2440         vector<space_and_path>::iterator i;
2441         vector<space_and_path>::iterator nexti;
2442         vector<string*>* soundfiles;
2443         vector<string> unused;
2444         set<string> all_sources;
2445         bool used;
2446         string spath;
2447         int ret = -1;
2448                 
2449         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2450
2451         
2452         /* step 1: consider deleting all unused playlists */
2453
2454         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2455                 int status;
2456
2457                 status = AskAboutPlaylistDeletion (*x);
2458
2459                 switch (status) {
2460                 case -1:
2461                         ret = 0;
2462                         goto out;
2463                         break;
2464
2465                 case 0:
2466                         playlists_tbd.push_back (*x);
2467                         break;
2468
2469                 default:
2470                         /* leave it alone */
2471                         break;
2472                 }
2473         }
2474
2475         /* now delete any that were marked for deletion */
2476
2477         for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2478                 (*x)->drop_references ();
2479         }
2480
2481         playlists_tbd.clear ();
2482
2483         /* step 2: find all un-used sources */
2484
2485         rep.paths.clear ();
2486         rep.space = 0;
2487
2488         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2489                 
2490                 SourceMap::iterator tmp;
2491
2492                 tmp = i;
2493                 ++tmp;
2494
2495                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2496                    capture files.
2497                 */
2498
2499                 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2500                         dead_sources.push_back (i->second);
2501                         i->second->GoingAway();
2502                 } 
2503
2504                 i = tmp;
2505         }
2506
2507         /* build a list of all the possible sound directories for the session */
2508
2509         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2510
2511                 nexti = i;
2512                 ++nexti;
2513
2514                 SessionDirectory sdir ((*i).path);
2515                 sound_path += sdir.sound_path().to_string();
2516
2517                 if (nexti != session_dirs.end()) {
2518                         sound_path += ':';
2519                 }
2520
2521                 i = nexti;
2522         }
2523
2524         /* now do the same thing for the files that ended up in the sounds dir(s) 
2525            but are not referenced as sources in any snapshot.
2526         */
2527
2528         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2529
2530         if (soundfiles == 0) {
2531                 return 0;
2532         }
2533
2534         /* find all sources, but don't use this snapshot because the
2535            state file on disk still references sources we may have already
2536            dropped.
2537         */
2538         
2539         find_all_sources_across_snapshots (all_sources, true);
2540
2541         /*  add our current source list
2542          */
2543         
2544         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2545                 boost::shared_ptr<FileSource> fs;
2546                 
2547                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2548                         all_sources.insert (fs->path());
2549                 } 
2550         }
2551
2552         char tmppath1[PATH_MAX+1];
2553         char tmppath2[PATH_MAX+1];
2554         
2555         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2556
2557                 used = false;
2558                 spath = **x;
2559
2560                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2561
2562                         realpath(spath.c_str(), tmppath1);
2563                         realpath((*i).c_str(),  tmppath2);
2564
2565                         if (strcmp(tmppath1, tmppath2) == 0) {
2566                                 used = true;
2567                                 break;
2568                         }
2569                 }
2570
2571                 if (!used) {
2572                         unused.push_back (spath);
2573                 }
2574         }
2575
2576         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2577
2578         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2579                 struct stat statbuf;
2580
2581                 rep.paths.push_back (*x);
2582                 if (stat ((*x).c_str(), &statbuf) == 0) {
2583                         rep.space += statbuf.st_size;
2584                 }
2585
2586                 string newpath;
2587                 
2588                 /* don't move the file across filesystems, just
2589                    stick it in the `dead_sound_dir_name' directory
2590                    on whichever filesystem it was already on.
2591                 */
2592
2593                 if ((*x).find ("/sounds/") != string::npos) {
2594
2595                         /* old school, go up 1 level */
2596
2597                         newpath = Glib::path_get_dirname (*x);      // "sounds" 
2598                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2599
2600                 } else {
2601
2602                         /* new school, go up 4 levels */
2603                         
2604                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" 
2605                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2606                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2607                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2608                 }
2609
2610                 newpath += '/';
2611                 newpath += dead_sound_dir_name;
2612
2613                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2614                         error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2615                         return -1;
2616                 }
2617
2618                 newpath += '/';
2619                 newpath += Glib::path_get_basename ((*x));
2620                 
2621                 if (access (newpath.c_str(), F_OK) == 0) {
2622                         
2623                         /* the new path already exists, try versioning */
2624                         
2625                         char buf[PATH_MAX+1];
2626                         int version = 1;
2627                         string newpath_v;
2628                         
2629                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2630                         newpath_v = buf;
2631
2632                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2633                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2634                                 newpath_v = buf;
2635                         }
2636                         
2637                         if (version == 999) {
2638                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2639                                                   newpath)
2640                                       << endmsg;
2641                         } else {
2642                                 newpath = newpath_v;
2643                         }
2644                         
2645                 } else {
2646                         
2647                         /* it doesn't exist, or we can't read it or something */
2648                         
2649                 }
2650
2651                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2652                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2653                                           (*x), newpath, strerror (errno))
2654                               << endmsg;
2655                         goto out;
2656                 }
2657
2658                 /* see if there an easy to find peakfile for this file, and remove it.
2659                  */
2660
2661                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2662                 peakpath += peakfile_suffix;
2663
2664                 if (access (peakpath.c_str(), W_OK) == 0) {
2665                         if (::unlink (peakpath.c_str()) != 0) {
2666                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2667                                                   peakpath, _path, strerror (errno))
2668                                       << endmsg;
2669                                 /* try to back out */
2670                                 rename (newpath.c_str(), _path.c_str());
2671                                 goto out;
2672                         }
2673                 }
2674         }
2675
2676         ret = 0;
2677
2678         /* dump the history list */
2679
2680         _history.clear ();
2681
2682         /* save state so we don't end up a session file
2683            referring to non-existent sources.
2684         */
2685         
2686         save_state ("");
2687
2688   out:
2689         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2690
2691         return ret;
2692 }
2693
2694 int
2695 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2696 {
2697         // FIXME: needs adaptation for MIDI
2698         
2699         vector<space_and_path>::iterator i;
2700         string dead_sound_dir;
2701         struct dirent* dentry;
2702         struct stat statbuf;
2703         DIR* dead;
2704
2705         rep.paths.clear ();
2706         rep.space = 0;
2707
2708         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2709                 
2710                 dead_sound_dir = (*i).path;
2711                 dead_sound_dir += dead_sound_dir_name;
2712
2713                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2714                         continue;
2715                 }
2716
2717                 while ((dentry = readdir (dead)) != 0) {
2718
2719                         /* avoid '.' and '..' */
2720                         
2721                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
2722                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2723                                 continue;
2724                         }
2725
2726                         string fullpath;
2727
2728                         fullpath = dead_sound_dir;
2729                         fullpath += '/';
2730                         fullpath += dentry->d_name;
2731
2732                         if (stat (fullpath.c_str(), &statbuf)) {
2733                                 continue;
2734                         }
2735
2736                         if (!S_ISREG (statbuf.st_mode)) {
2737                                 continue;
2738                         }
2739
2740                         if (unlink (fullpath.c_str())) {
2741                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2742                                                   fullpath, strerror (errno))
2743                                       << endmsg;
2744                         }
2745
2746                         rep.paths.push_back (dentry->d_name);
2747                         rep.space += statbuf.st_size;
2748                 }
2749
2750                 closedir (dead);
2751                 
2752         }
2753
2754         return 0;
2755 }
2756
2757 void
2758 Session::set_dirty ()
2759 {
2760         bool was_dirty = dirty();
2761
2762         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2763
2764
2765         if (!was_dirty) {
2766                 DirtyChanged(); /* EMIT SIGNAL */
2767         }
2768 }
2769
2770
2771 void
2772 Session::set_clean ()
2773 {
2774         bool was_dirty = dirty();
2775         
2776         _state_of_the_state = Clean;
2777
2778
2779         if (was_dirty) {
2780                 DirtyChanged(); /* EMIT SIGNAL */
2781         }
2782 }
2783
2784 void
2785 Session::set_deletion_in_progress ()
2786 {
2787         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2788 }
2789
2790 void
2791 Session::clear_deletion_in_progress ()
2792 {
2793         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2794 }
2795
2796 void
2797 Session::add_controllable (boost::shared_ptr<Controllable> c)
2798 {
2799         /* this adds a controllable to the list managed by the Session.
2800            this is a subset of those managed by the Controllable class
2801            itself, and represents the only ones whose state will be saved
2802            as part of the session.
2803         */
2804
2805         Glib::Mutex::Lock lm (controllables_lock);
2806         controllables.insert (c);
2807 }
2808         
2809 struct null_deleter { void operator()(void const *) const {} };
2810
2811 void
2812 Session::remove_controllable (Controllable* c)
2813 {
2814         if (_state_of_the_state | Deletion) {
2815                 return;
2816         }
2817
2818         Glib::Mutex::Lock lm (controllables_lock);
2819
2820         Controllables::iterator x = controllables.find(
2821                  boost::shared_ptr<Controllable>(c, null_deleter()));
2822
2823         if (x != controllables.end()) {
2824                 controllables.erase (x);
2825         }
2826 }       
2827
2828 boost::shared_ptr<Controllable>
2829 Session::controllable_by_id (const PBD::ID& id)
2830 {
2831         Glib::Mutex::Lock lm (controllables_lock);
2832         
2833         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2834                 if ((*i)->id() == id) {
2835                         return *i;
2836                 }
2837         }
2838
2839         return boost::shared_ptr<Controllable>();
2840 }
2841
2842 void 
2843 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2844 {
2845         Stateful::add_instant_xml (node, _path);
2846         if (write_to_config) {
2847                 Config->add_instant_xml (node);
2848         }
2849 }
2850
2851 XMLNode*
2852 Session::instant_xml (const string& node_name)
2853 {
2854         return Stateful::instant_xml (node_name, _path);
2855 }
2856
2857 int 
2858 Session::save_history (string snapshot_name)
2859 {
2860         XMLTree tree;
2861         
2862         if (snapshot_name.empty()) {
2863                 snapshot_name = _current_snapshot_name;
2864         }
2865   
2866         const string history_filename = snapshot_name + history_suffix;
2867         const string backup_filename = history_filename + backup_suffix;
2868         const sys::path xml_path = _session_dir->root_path() / history_filename;
2869         const sys::path backup_path = _session_dir->root_path() / backup_filename;
2870
2871         if (sys::exists (xml_path)) {
2872                 try
2873                 {
2874                         sys::rename (xml_path, backup_path);
2875                 }
2876                 catch (const sys::filesystem_error& err)
2877                 {
2878                         error << _("could not backup old history file, current history not saved") << endmsg;
2879                         return -1;
2880                 }
2881         }
2882
2883
2884         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2885                 return 0;
2886         }
2887
2888         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2889
2890         if (!tree.write (xml_path.to_string()))
2891         {
2892                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2893
2894                 try
2895                 {
2896                         sys::remove (xml_path);
2897                         sys::rename (backup_path, xml_path);
2898                 }
2899                 catch (const sys::filesystem_error& err)
2900                 {
2901                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
2902                                         backup_path.to_string(), err.what()) << endmsg;
2903                 }
2904
2905                 return -1;
2906         }
2907
2908         return 0;
2909 }
2910
2911 int
2912 Session::restore_history (string snapshot_name)
2913 {
2914         XMLTree tree;
2915
2916         if (snapshot_name.empty()) {
2917                 snapshot_name = _current_snapshot_name;
2918         }
2919
2920         const string xml_filename = snapshot_name + history_suffix;
2921         const sys::path xml_path = _session_dir->root_path() / xml_filename;
2922
2923     cerr << "Loading history from " << xml_path.to_string() << endmsg;
2924
2925         if (!sys::exists (xml_path)) {
2926                 info << string_compose (_("%1: no history file \"%2\" for this session."),
2927                                 _name, xml_path.to_string()) << endmsg;
2928                 return 1;
2929         }
2930
2931         if (!tree.read (xml_path.to_string())) {
2932                 error << string_compose (_("Could not understand session history file \"%1\""),
2933                                 xml_path.to_string()) << endmsg;
2934                 return -1;
2935         }
2936
2937         // replace history
2938         _history.clear();
2939
2940     for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2941             
2942             XMLNode *t = *it;
2943             UndoTransaction* ut = new UndoTransaction ();
2944             struct timeval tv;
2945             
2946             ut->set_name(t->property("name")->value());
2947             stringstream ss(t->property("tv-sec")->value());
2948             ss >> tv.tv_sec;
2949             ss.str(t->property("tv-usec")->value());
2950             ss >> tv.tv_usec;
2951             ut->set_timestamp(tv);
2952             
2953             for (XMLNodeConstIterator child_it  = t->children().begin();
2954                                 child_it != t->children().end(); child_it++)
2955             {
2956                     XMLNode *n = *child_it;
2957                     Command *c;
2958         
2959                     if (n->name() == "MementoCommand" ||
2960                                         n->name() == "MementoUndoCommand" ||
2961                                         n->name() == "MementoRedoCommand") {
2962
2963                             if ((c = memento_command_factory(n))) {
2964                                     ut->add_command(c);
2965                             }
2966                             
2967                     } else if (n->name() == X_("GlobalRouteStateCommand")) {
2968
2969                             if ((c = global_state_command_factory (*n))) {
2970                                     ut->add_command (c);
2971                             }
2972                             
2973                     } else if (n->name() == "DeltaCommand") {
2974                          PBD::ID  id(n->property("midi-source")->value());
2975                          boost::shared_ptr<MidiSource> midi_source = 
2976                                  boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2977                          if(midi_source) {
2978                                  ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));                                 
2979                          } else {
2980                                  error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
2981                          }
2982                     } else {
2983                             error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2984                     }
2985             }
2986
2987             _history.add (ut);
2988     }
2989
2990     return 0;
2991 }
2992
2993 void
2994 Session::config_changed (std::string p, bool ours)
2995 {
2996         if (ours) {
2997                 set_dirty ();
2998         }
2999         
3000         if (p == "seamless-loop") {
3001                 
3002         } else if (p == "rf-speed") {
3003                 
3004         } else if (p == "auto-loop") {
3005                 
3006         } else if (p == "auto-input") {
3007                 
3008                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3009                         /* auto-input only makes a difference if we're rolling */
3010                         
3011                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3012                         
3013                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3014                                 if ((*i)->record_enabled ()) {
3015                                         (*i)->monitor_input (!config.get_auto_input());
3016                                 }
3017                         }
3018                 }
3019
3020         } else if (p == "punch-in") {
3021
3022                 Location* location;
3023                 
3024                 if ((location = _locations.auto_punch_location()) != 0) {
3025                         
3026                         if (config.get_punch_in ()) {
3027                                 replace_event (Event::PunchIn, location->start());
3028                         } else {
3029                                 remove_event (location->start(), Event::PunchIn);
3030                         }
3031                 }
3032                 
3033         } else if (p == "punch-out") {
3034
3035                 Location* location;
3036                 
3037                 if ((location = _locations.auto_punch_location()) != 0) {
3038                         
3039                         if (config.get_punch_out()) {
3040                                 replace_event (Event::PunchOut, location->end());
3041                         } else {
3042                                 clear_events (Event::PunchOut);
3043                         }
3044                 }
3045
3046         } else if (p == "edit-mode") {
3047
3048                 Glib::Mutex::Lock lm (playlist_lock);
3049                 
3050                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3051                         (*i)->set_edit_mode (Config->get_edit_mode ());
3052                 }
3053
3054         } else if (p == "use-video-sync") {
3055
3056                 waiting_for_sync_offset = config.get_use_video_sync();
3057
3058         } else if (p == "mmc-control") {
3059
3060                 //poke_midi_thread ();
3061
3062         } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3063
3064                 if (mmc) {
3065                         mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3066                 }
3067
3068         } else if (p == "mmc-send-id") {
3069
3070                 if (mmc) {
3071                         mmc->set_send_device_id (Config->get_mmc_send_device_id());
3072                 }
3073
3074         } else if (p == "midi-control") {
3075                 
3076                 //poke_midi_thread ();
3077
3078         } else if (p == "raid-path") {
3079
3080                 setup_raid_path (config.get_raid_path());
3081
3082         } else if (p == "smpte-format") {
3083
3084                 sync_time_vars ();
3085
3086         } else if (p == "video-pullup") {
3087
3088                 sync_time_vars ();
3089
3090         } else if (p == "seamless-loop") {
3091
3092                 if (play_loop && transport_rolling()) {
3093                         // to reset diskstreams etc
3094                         request_play_loop (true);
3095                 }
3096
3097         } else if (p == "rf-speed") {
3098
3099                 cumulative_rf_motion = 0;
3100                 reset_rf_scale (0);
3101
3102         } else if (p == "click-sound") {
3103
3104                 setup_click_sounds (1);
3105
3106         } else if (p == "click-emphasis-sound") {
3107
3108                 setup_click_sounds (-1);
3109
3110         } else if (p == "clicking") {
3111
3112                 if (Config->get_clicking()) {
3113                         if (_click_io && click_data) { // don't require emphasis data
3114                                 _clicking = true;
3115                         }
3116                 } else {
3117                         _clicking = false;
3118                 }
3119
3120         } else if (p == "send-mtc") {
3121                 
3122                 /* only set the internal flag if we have
3123                    a port.
3124                 */
3125                 
3126                 if (_mtc_port != 0) {
3127                         session_send_mtc = Config->get_send_mtc();
3128                         if (session_send_mtc) {
3129                                 /* mark us ready to send */
3130                                 next_quarter_frame_to_send = 0;
3131                         }
3132                 } else {
3133                         session_send_mtc = false;
3134                 }
3135
3136         } else if (p == "send-mmc") {
3137                 
3138                 /* only set the internal flag if we have
3139                    a port.
3140                 */
3141                 
3142                 if (_mmc_port != 0) {
3143                         session_send_mmc = Config->get_send_mmc();
3144                 } else {
3145                         mmc = 0;
3146                         session_send_mmc = false; 
3147                 }
3148
3149         } else if (p == "midi-feedback") {
3150                 
3151                 /* only set the internal flag if we have
3152                    a port.
3153                 */
3154                 
3155                 if (_mtc_port != 0) {
3156                         session_midi_feedback = Config->get_midi_feedback();
3157                 }
3158
3159         } else if (p == "jack-time-master") {
3160
3161                 engine().reset_timebase ();
3162
3163         } else if (p == "native-file-header-format") {
3164
3165                 if (!first_file_header_format_reset) {
3166                         reset_native_file_format ();
3167                 }
3168
3169                 first_file_header_format_reset = false;
3170
3171         } else if (p == "native-file-data-format") {
3172
3173                 if (!first_file_data_format_reset) {
3174                         reset_native_file_format ();
3175                 }
3176
3177                 first_file_data_format_reset = false;
3178
3179         } else if (p == "slave-source") {
3180                                 set_slave_source (Config->get_slave_source());
3181         } else if (p == "remote-model") {
3182                 set_remote_control_ids ();
3183         }  else if (p == "denormal-model") {
3184                 setup_fpu ();
3185         } else if (p == "history-depth") {
3186                 set_history_depth (Config->get_history_depth());
3187         } else if (p == "sync-all-route-ordering") {
3188                 sync_order_keys ("session");
3189         } else if (p == "initial-program-change") {
3190
3191                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3192                         MIDI::byte buf[2];
3193                         
3194                         buf[0] = MIDI::program; // channel zero by default
3195                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3196
3197                         _mmc_port->midimsg (buf, sizeof (buf), 0);
3198                 }
3199         } else if (p == "initial-program-change") {
3200
3201                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3202                         MIDI::byte* buf = new MIDI::byte[2];
3203                         
3204                         buf[0] = MIDI::program; // channel zero by default
3205                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3206                         // deliver_midi (_mmc_port, buf, 2);
3207                 }
3208         } else if (p == "solo-mute-override") {
3209                 // catch_up_on_solo_mute_override ();
3210         } else if (p == "solo-model") {
3211                 solo_model_changed ();
3212         }
3213
3214         set_dirty ();
3215 }
3216
3217 void
3218 Session::set_history_depth (uint32_t d)
3219 {
3220         _history.set_depth (d);
3221 }