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