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