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