More tinkering with State<>. Use some StateDiffCommands instead of
[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
34 #include <cstdio> /* snprintf(3) ... grrr */
35 #include <cmath>
36 #include <unistd.h>
37 #include <sys/stat.h>
38 #include <climits>
39 #include <fcntl.h>
40 #include <poll.h>
41 #include <signal.h>
42 #include <sys/mman.h>
43 #include <sys/time.h>
44 #include <dirent.h>
45
46 #ifdef HAVE_SYS_VFS_H
47 #include <sys/vfs.h>
48 #else
49 #include <sys/param.h>
50 #include <sys/mount.h>
51 #endif
52
53 #include <glibmm.h>
54 #include <glibmm/thread.h>
55
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.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 #include "pbd/convert.h"
68
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_command.h"
96 #include "ardour/region_factory.h"
97 #include "ardour/route_group.h"
98 #include "ardour/send.h"
99 #include "ardour/session.h"
100 #include "ardour/session_directory.h"
101 #include "ardour/session_metadata.h"
102 #include "ardour/session_state_utils.h"
103 #include "ardour/session_playlists.h"
104 #include "ardour/session_utils.h"
105 #include "ardour/silentfilesource.h"
106 #include "ardour/slave.h"
107 #include "ardour/smf_source.h"
108 #include "ardour/sndfile_helpers.h"
109 #include "ardour/sndfilesource.h"
110 #include "ardour/source_factory.h"
111 #include "ardour/template_utils.h"
112 #include "ardour/tempo.h"
113 #include "ardour/ticker.h"
114 #include "ardour/user_bundle.h"
115 #include "ardour/utils.h"
116 #include "ardour/utils.h"
117 #include "ardour/version.h"
118 #include "ardour/playlist_factory.h"
119
120 #include "control_protocol/control_protocol.h"
121
122 #include "i18n.h"
123 #include <locale.h>
124
125 using namespace std;
126 using namespace ARDOUR;
127 using namespace PBD;
128
129 void
130 Session::first_stage_init (string fullpath, string snapshot_name)
131 {
132         if (fullpath.length() == 0) {
133                 destroy ();
134                 throw failed_constructor();
135         }
136
137         char buf[PATH_MAX+1];
138         if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
139                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140                 destroy ();
141                 throw failed_constructor();
142         }
143
144         _path = string(buf);
145
146         if (_path[_path.length()-1] != '/') {
147                 _path += '/';
148         }
149
150         if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
151                 _writable = false;
152         } else {
153                 _writable = true;
154         }
155
156         /* these two are just provisional settings. set_state()
157            will likely override them.
158         */
159
160         _name = _current_snapshot_name = snapshot_name;
161
162         set_history_depth (Config->get_history_depth());
163
164         _current_frame_rate = _engine.frame_rate ();
165         _nominal_frame_rate = _current_frame_rate;
166         _base_frame_rate = _current_frame_rate;
167
168         _tempo_map = new TempoMap (_current_frame_rate);
169         _tempo_map->StateChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
170
171
172         _non_soloed_outs_muted = false;
173         _listen_cnt = 0;
174         g_atomic_int_set (&processing_prohibited, 0);
175         _transport_speed = 0;
176         _last_transport_speed = 0;
177         _target_transport_speed = 0;
178         auto_play_legal = false;
179         transport_sub_state = 0;
180         _transport_frame = 0;
181         _requested_return_frame = -1;
182         end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
183         start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
184         g_atomic_int_set (&_record_status, Disabled);
185         loop_changing = false;
186         play_loop = false;
187         have_looped = false;
188         _last_roll_location = 0;
189         _last_record_location = 0;
190         pending_locate_frame = 0;
191         pending_locate_roll = false;
192         pending_locate_flush = false;
193         state_was_pending = false;
194         set_next_event ();
195         outbound_mtc_timecode_frame = 0;
196         next_quarter_frame_to_send = -1;
197         current_block_size = 0;
198         solo_update_disabled = false;
199         _have_captured = false;
200         _worst_output_latency = 0;
201         _worst_input_latency = 0;
202         _worst_track_latency = 0;
203         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204         _was_seamless = Config->get_seamless_loop ();
205         _slave = 0;
206         session_send_mmc = false;
207         session_send_mtc = false;
208         g_atomic_int_set (&_playback_load, 100);
209         g_atomic_int_set (&_capture_load, 100);
210         g_atomic_int_set (&_playback_load_min, 100);
211         g_atomic_int_set (&_capture_load_min, 100);
212         _play_range = false;
213         _exporting = 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_control_ui = 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_same_thread (*this, boost::bind (&Session::graph_reordered, this));
271
272         /* These are all static "per-class" signals */
273
274         RegionFactory::CheckNewRegion.connect_same_thread (*this, boost::bind (&Session::add_region, this, _1));
275         SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
276         PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
277         Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
278         AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
279         Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
280         IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
281
282         /* stop IO objects from doing stuff until we're ready for them */
283
284         Delivery::disable_panners ();
285         IO::disable_connecting ();
286 }
287
288 int
289 Session::second_stage_init (bool new_session)
290 {
291         AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
292
293         if (!new_session) {
294                 if (load_state (_current_snapshot_name)) {
295                         return -1;
296                 }
297                 remove_empty_sounds ();
298         }
299
300         if (_butler->start_thread()) {
301                 return -1;
302         }
303
304         if (start_midi_thread ()) {
305                 return -1;
306         }
307
308         // set_state() will call setup_raid_path(), but if it's a new session we need
309         // to call setup_raid_path() here.
310
311         if (state_tree) {
312                 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
313                         return -1;
314                 }
315         } else {
316                 setup_raid_path(_path);
317         }
318
319         /* we can't save till after ::when_engine_running() is called,
320            because otherwise we save state with no connections made.
321            therefore, we reset _state_of_the_state because ::set_state()
322            will have cleared it.
323
324            we also have to include Loading so that any events that get
325            generated between here and the end of ::when_engine_running()
326            will be processed directly rather than queued.
327         */
328
329         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
330
331
332         _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
333         _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
334         setup_click_sounds (0);
335         setup_midi_control ();
336
337         /* Pay attention ... */
338
339         _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
340         _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
341
342         try {
343                 when_engine_running();
344         }
345
346         /* handle this one in a different way than all others, so that its clear what happened */
347
348         catch (AudioEngine::PortRegistrationFailure& err) {
349                 error << err.what() << endmsg;
350                 return -1;
351         }
352
353         catch (...) {
354                 return -1;
355         }
356
357         BootMessage (_("Reset Remote Controls"));
358
359         send_full_time_code (0);
360         _engine.transport_locate (0);
361         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
362         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
363
364         MidiClockTicker::instance().set_session (this);
365         MIDI::Name::MidiPatchManager::instance().set_session (this);
366
367         /* initial program change will be delivered later; see ::config_changed() */
368
369         BootMessage (_("Reset Control Protocols"));
370
371         ControlProtocolManager::instance().set_session (this);
372
373         config.set_end_marker_is_free (new_session);
374
375         _state_of_the_state = Clean;
376
377         DirtyChanged (); /* EMIT SIGNAL */
378
379         if (state_was_pending) {
380                 save_state (_current_snapshot_name);
381                 remove_pending_capture_state ();
382                 state_was_pending = false;
383         }
384
385         BootMessage (_("Session loading complete"));
386
387         return 0;
388 }
389
390 string
391 Session::raid_path () const
392 {
393         SearchPath raid_search_path;
394
395         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396                 raid_search_path += sys::path((*i).path);
397         }
398
399         return raid_search_path.to_string ();
400 }
401
402 void
403 Session::setup_raid_path (string path)
404 {
405         if (path.empty()) {
406                 return;
407         }
408
409         space_and_path sp;
410         string fspath;
411
412         session_dirs.clear ();
413
414         SearchPath search_path(path);
415         SearchPath sound_search_path;
416         SearchPath midi_search_path;
417
418         for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419                 sp.path = (*i).to_string ();
420                 sp.blocks = 0; // not needed
421                 session_dirs.push_back (sp);
422
423                 SessionDirectory sdir(sp.path);
424
425                 sound_search_path += sdir.sound_path ();
426                 midi_search_path += sdir.midi_path ();
427         }
428
429         // set the search path for each data type
430         FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
431         SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
432
433         // reset the round-robin soundfile path thingie
434         last_rr_session_dir = session_dirs.begin();
435 }
436
437 bool
438 Session::path_is_within_session (const std::string& path)
439 {
440         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
441                 if (path.find ((*i).path) == 0) {
442                         return true;
443                 }
444         }
445         return false;
446 }
447
448 int
449 Session::ensure_subdirs ()
450 {
451         string dir;
452
453         dir = session_directory().peak_path().to_string();
454
455         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456                 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457                 return -1;
458         }
459
460         dir = session_directory().sound_path().to_string();
461
462         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464                 return -1;
465         }
466
467         dir = session_directory().midi_path().to_string();
468
469         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470                 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471                 return -1;
472         }
473
474         dir = session_directory().dead_sound_path().to_string();
475
476         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477                 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
478                 return -1;
479         }
480
481         dir = session_directory().export_path().to_string();
482
483         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484                 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485                 return -1;
486         }
487
488         dir = analysis_dir ();
489
490         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491                 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492                 return -1;
493         }
494
495         return 0;
496 }
497
498 int
499 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
500 {
501
502         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
503                 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
504                 return -1;
505         }
506
507         if (ensure_subdirs ()) {
508                 return -1;
509         }
510
511         /* check new_session so we don't overwrite an existing one */
512
513         if (!mix_template.empty()) {
514                 std::string in_path = mix_template;
515
516                 ifstream in(in_path.c_str());
517
518                 if (in){
519                         string out_path = _path;
520                         out_path += _name;
521                         out_path += statefile_suffix;
522
523                         ofstream out(out_path.c_str());
524
525                         if (out){
526                                 out << in.rdbuf();
527
528                                 // okay, session is set up.  Treat like normal saved
529                                 // session from now on.
530
531                                 new_session = false;
532                                 return 0;
533
534                         } else {
535                                 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
536                                         << endmsg;
537                                 return -1;
538                         }
539
540                 } else {
541                         error << string_compose (_("Could not open mix template %1 for reading"), in_path)
542                                 << endmsg;
543                         return -1;
544                 }
545
546         }
547
548         /* Instantiate metadata */
549
550         _metadata = new SessionMetadata ();
551
552         /* set initial start + end point */
553
554         start_location->set_end (0);
555         _locations.add (start_location);
556
557         end_location->set_end (initial_length);
558         _locations.add (end_location);
559
560         _state_of_the_state = Clean;
561
562         save_state ("");
563
564         return 0;
565 }
566
567
568 int
569 Session::load_diskstreams (const XMLNode& node)
570 {
571         XMLNodeList          clist;
572         XMLNodeConstIterator citer;
573
574         clist = node.children();
575
576         for (citer = clist.begin(); citer != clist.end(); ++citer) {
577
578                 try {
579                         /* diskstreams added automatically by DiskstreamCreated handler */
580                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
581                                 AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
582                                 boost::shared_ptr<AudioDiskstream> dstream (dsp);
583                                 add_diskstream (dstream);
584                         } else if ((*citer)->name() == "MidiDiskstream") {
585                                 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
586                                 add_diskstream (dstream);
587                         } else {
588                                 error << _("Session: unknown diskstream type in XML") << endmsg;
589                         }
590                 }
591
592                 catch (failed_constructor& err) {
593                         error << _("Session: could not load diskstream via XML state") << endmsg;
594                         return -1;
595                 }
596         }
597
598         return 0;
599 }
600
601 void
602 Session::maybe_write_autosave()
603 {
604         if (dirty() && record_status() != Recording) {
605                 save_state("", true);
606         }
607 }
608
609 void
610 Session::remove_pending_capture_state ()
611 {
612         sys::path pending_state_file_path(_session_dir->root_path());
613
614         pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
615
616         try
617         {
618                 sys::remove (pending_state_file_path);
619         }
620         catch(sys::filesystem_error& ex)
621         {
622                 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
623                                 pending_state_file_path.to_string(), ex.what()) << endmsg;
624         }
625 }
626
627 /** Rename a state file.
628  * @param snapshot_name Snapshot name.
629  */
630 void
631 Session::rename_state (string old_name, string new_name)
632 {
633         if (old_name == _current_snapshot_name || old_name == _name) {
634                 /* refuse to rename the current snapshot or the "main" one */
635                 return;
636         }
637
638         const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
639         const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
640
641         const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
642         const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
643
644         try
645         {
646                 sys::rename (old_xml_path, new_xml_path);
647         }
648         catch (const sys::filesystem_error& err)
649         {
650                 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
651                                 old_name, new_name, err.what()) << endmsg;
652         }
653 }
654
655 /** Remove a state file.
656  * @param snapshot_name Snapshot name.
657  */
658 void
659 Session::remove_state (string snapshot_name)
660 {
661         if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
662                 // refuse to remove the current snapshot or the "main" one
663                 return;
664         }
665
666         sys::path xml_path(_session_dir->root_path());
667
668         xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
669
670         if (!create_backup_file (xml_path)) {
671                 // don't remove it if a backup can't be made
672                 // create_backup_file will log the error.
673                 return;
674         }
675
676         // and delete it
677         sys::remove (xml_path);
678 }
679
680 int
681 Session::save_state (string snapshot_name, bool pending)
682 {
683         XMLTree tree;
684         sys::path xml_path(_session_dir->root_path());
685
686         if (!_writable || (_state_of_the_state & CannotSave)) {
687                 return 1;
688         }
689
690         if (!_engine.connected ()) {
691                 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
692                       << endmsg;
693                 return 1;
694         }
695
696         /* tell sources we're saving first, in case they write out to a new file
697          * which should be saved with the state rather than the old one */
698         for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
699                 i->second->session_saved();
700
701         tree.set_root (&get_state());
702
703         if (snapshot_name.empty()) {
704                 snapshot_name = _current_snapshot_name;
705         }
706
707         if (!pending) {
708
709                 /* proper save: use statefile_suffix (.ardour in English) */
710
711                 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
712
713                 /* make a backup copy of the old file */
714
715                 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
716                         // create_backup_file will log the error
717                         return -1;
718                 }
719
720         } else {
721
722                 /* pending save: use pending_suffix (.pending in English) */
723                 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
724         }
725
726         sys::path tmp_path(_session_dir->root_path());
727
728         tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
729
730         // cerr << "actually writing state to " << xml_path.to_string() << endl;
731
732         if (!tree.write (tmp_path.to_string())) {
733                 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
734                 sys::remove (tmp_path);
735                 return -1;
736
737         } else {
738
739                 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
740                         error << string_compose (_("could not rename temporary session file %1 to %2"),
741                                         tmp_path.to_string(), xml_path.to_string()) << endmsg;
742                         sys::remove (tmp_path);
743                         return -1;
744                 }
745         }
746
747         if (!pending) {
748
749                 save_history (snapshot_name);
750
751                 bool was_dirty = dirty();
752
753                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
754
755                 if (was_dirty) {
756                         DirtyChanged (); /* EMIT SIGNAL */
757                 }
758
759                 StateSaved (snapshot_name); /* EMIT SIGNAL */
760         }
761
762         return 0;
763 }
764
765 int
766 Session::restore_state (string snapshot_name)
767 {
768         if (load_state (snapshot_name) == 0) {
769                 set_state (*state_tree->root(), Stateful::loading_state_version);
770         }
771
772         return 0;
773 }
774
775 int
776 Session::load_state (string snapshot_name)
777 {
778         delete state_tree;
779         state_tree = 0;
780
781         state_was_pending = false;
782
783         /* check for leftover pending state from a crashed capture attempt */
784
785         sys::path xmlpath(_session_dir->root_path());
786         xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
787
788         if (sys::exists (xmlpath)) {
789
790                 /* there is pending state from a crashed capture attempt */
791
792                 if (*AskAboutPendingState()) {
793                         state_was_pending = true;
794                 }
795         }
796
797         if (!state_was_pending) {
798                 xmlpath = _session_dir->root_path();
799                 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
800         }
801
802         if (!sys::exists (xmlpath)) {
803                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
804                 return 1;
805         }
806
807         state_tree = new XMLTree;
808
809         set_dirty();
810
811         /* writable() really reflects the whole folder, but if for any
812            reason the session state file can't be written to, still
813            make us unwritable.
814         */
815
816         if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
817                 _writable = false;
818         }
819
820         if (!state_tree->read (xmlpath.to_string())) {
821                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
822                 delete state_tree;
823                 state_tree = 0;
824                 return -1;
825         }
826
827         XMLNode& root (*state_tree->root());
828
829         if (root.name() != X_("Session")) {
830                 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
831                 delete state_tree;
832                 state_tree = 0;
833                 return -1;
834         }
835
836         const XMLProperty* prop;
837
838         if ((prop = root.property ("version")) == 0) {
839                 /* no version implies very old version of Ardour */
840                 Stateful::loading_state_version = 1000;
841         } else {
842                 int major;
843                 int minor;
844                 int micro;
845
846                 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, &micro);
847                 Stateful::loading_state_version = (major * 1000) + minor;
848         }
849                 
850         if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
851
852                 sys::path backup_path(_session_dir->root_path());
853
854                 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
855
856                 // only create a backup once
857                 if (sys::exists (backup_path)) {
858                         return 0;
859                 }
860
861                 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
862                                         xmlpath.to_string(), backup_path.to_string())
863                      << endmsg;
864
865                 try
866                 {
867                         sys::copy_file (xmlpath, backup_path);
868                 }
869                 catch(sys::filesystem_error& ex)
870                 {
871                         error << string_compose (_("Unable to make backup of state file %1 (%2)"),
872                                         xmlpath.to_string(), ex.what())
873                                 << endmsg;
874                         return -1;
875                 }
876         }
877
878         return 0;
879 }
880
881 int
882 Session::load_options (const XMLNode& node)
883 {
884         LocaleGuard lg (X_("POSIX"));
885         config.set_variables (node);
886         return 0;
887 }
888
889 XMLNode&
890 Session::get_state()
891 {
892         return state(true);
893 }
894
895 XMLNode&
896 Session::get_template()
897 {
898         /* if we don't disable rec-enable, diskstreams
899            will believe they need to store their capture
900            sources in their state node.
901         */
902
903         disable_record (false);
904
905         return state(false);
906 }
907
908 XMLNode&
909 Session::state(bool full_state)
910 {
911         XMLNode* node = new XMLNode("Session");
912         XMLNode* child;
913
914         // store libardour version, just in case
915         char buf[16];
916         snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
917         node->add_property("version", string(buf));
918
919         /* store configuration settings */
920
921         if (full_state) {
922
923                 node->add_property ("name", _name);
924                 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
925                 node->add_property ("sample-rate", buf);
926
927                 if (session_dirs.size() > 1) {
928
929                         string p;
930
931                         vector<space_and_path>::iterator i = session_dirs.begin();
932                         vector<space_and_path>::iterator next;
933
934                         ++i; /* skip the first one */
935                         next = i;
936                         ++next;
937
938                         while (i != session_dirs.end()) {
939
940                                 p += (*i).path;
941
942                                 if (next != session_dirs.end()) {
943                                         p += ':';
944                                 } else {
945                                         break;
946                                 }
947
948                                 ++next;
949                                 ++i;
950                         }
951
952                         child = node->add_child ("Path");
953                         child->add_content (p);
954                 }
955         }
956
957         /* save the ID counter */
958
959         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
960         node->add_property ("id-counter", buf);
961
962         /* various options */
963
964         node->add_child_nocopy (config.get_variables ());
965
966         node->add_child_nocopy (_metadata->get_state());
967
968         child = node->add_child ("Sources");
969
970         if (full_state) {
971                 Glib::Mutex::Lock sl (source_lock);
972
973                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
974
975                         /* Don't save information about non-destructive file sources that are empty */
976                         /* FIXME: MIDI breaks if this is made FileSource like it should be... */
977
978                         boost::shared_ptr<AudioFileSource> fs;
979                         if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
980                                 if (!fs->destructive()) {
981                                         if (fs->length(fs->timeline_position()) == 0) {
982                                                 continue;
983                                         }
984                                 }
985                         }
986
987                         child->add_child_nocopy (siter->second->get_state());
988                 }
989         }
990
991         child = node->add_child ("Regions");
992
993         if (full_state) {
994                 Glib::Mutex::Lock rl (region_lock);
995
996                 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
997
998                         /* only store regions not attached to playlists */
999
1000                         if (i->second->playlist() == 0) {
1001                                 child->add_child_nocopy (i->second->state (true));
1002                         }
1003                 }
1004         }
1005
1006         child = node->add_child ("DiskStreams");
1007
1008         {
1009                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1010                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1011                         if (!(*i)->hidden()) {
1012                                 child->add_child_nocopy ((*i)->get_state());
1013                         }
1014                 }
1015         }
1016
1017         if (full_state) {
1018                 node->add_child_nocopy (_locations.get_state());
1019         } else {
1020                 // for a template, just create a new Locations, populate it
1021                 // with the default start and end, and get the state for that.
1022                 Locations loc;
1023                 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1024                 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1025                 start->set_end(0);
1026                 loc.add (start);
1027                 end->set_end(compute_initial_length());
1028                 loc.add (end);
1029                 node->add_child_nocopy (loc.get_state());
1030         }
1031
1032         child = node->add_child ("Bundles");
1033         {
1034                 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1035                 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1036                         boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1037                         if (b) {
1038                                 child->add_child_nocopy (b->get_state());
1039                         }
1040                 }
1041         }
1042
1043         child = node->add_child ("Routes");
1044         {
1045                 boost::shared_ptr<RouteList> r = routes.reader ();
1046
1047                 RoutePublicOrderSorter cmp;
1048                 RouteList public_order (*r);
1049                 public_order.sort (cmp);
1050
1051                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1052                         if (!(*i)->is_hidden()) {
1053                                 if (full_state) {
1054                                         child->add_child_nocopy ((*i)->get_state());
1055                                 } else {
1056                                         child->add_child_nocopy ((*i)->get_template());
1057                                 }
1058                         }
1059                 }
1060         }
1061
1062         playlists->add_state (node, full_state);
1063
1064         child = node->add_child ("RouteGroups");
1065         for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1066                 child->add_child_nocopy ((*i)->get_state());
1067         }
1068
1069         if (_click_io) {
1070                 child = node->add_child ("Click");
1071                 child->add_child_nocopy (_click_io->state (full_state));
1072         }
1073
1074         if (full_state) {
1075                 child = node->add_child ("NamedSelections");
1076                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1077                         if (full_state) {
1078                                 child->add_child_nocopy ((*i)->get_state());
1079                         }
1080                 }
1081         }
1082
1083         node->add_child_nocopy (_tempo_map->get_state());
1084
1085         node->add_child_nocopy (get_control_protocol_state());
1086
1087         if (_extra_xml) {
1088                 node->add_child_copy (*_extra_xml);
1089         }
1090
1091         return *node;
1092 }
1093
1094 XMLNode&
1095 Session::get_control_protocol_state ()
1096 {
1097         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1098         return cpm.get_state();
1099 }
1100
1101 int
1102 Session::set_state (const XMLNode& node, int version)
1103 {
1104         XMLNodeList nlist;
1105         XMLNode* child;
1106         const XMLProperty* prop;
1107         int ret = -1;
1108
1109         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1110
1111         if (node.name() != X_("Session")){
1112                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1113                 return -1;
1114         }
1115
1116         if ((prop = node.property ("version")) != 0) {
1117                 version = atoi (prop->value ()) * 1000;
1118         }
1119
1120         if ((prop = node.property ("name")) != 0) {
1121                 _name = prop->value ();
1122         }
1123
1124         if ((prop = node.property (X_("sample-rate"))) != 0) {
1125
1126                 _nominal_frame_rate = atoi (prop->value());
1127
1128                 if (_nominal_frame_rate != _current_frame_rate) {
1129                         if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1130                                 return -1;
1131                         }
1132                 }
1133         }
1134
1135         setup_raid_path(_session_dir->root_path().to_string());
1136
1137         if ((prop = node.property (X_("id-counter"))) != 0) {
1138                 uint64_t x;
1139                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1140                 ID::init_counter (x);
1141         } else {
1142                 /* old sessions used a timebased counter, so fake
1143                    the startup ID counter based on a standard
1144                    timestamp.
1145                 */
1146                 time_t now;
1147                 time (&now);
1148                 ID::init_counter (now);
1149         }
1150
1151
1152         IO::disable_connecting ();
1153
1154         /* Object loading order:
1155
1156         Path
1157         Extra
1158         Options/Config
1159         MIDI Control // relies on data from Options/Config
1160         Metadata
1161         Locations
1162         Sources
1163         AudioRegions
1164         AudioDiskstreams
1165         Connections
1166         Routes
1167         RouteGroups
1168         MixGroups
1169         Click
1170         ControlProtocols
1171         */
1172
1173         if ((child = find_named_node (node, "Extra")) != 0) {
1174                 _extra_xml = new XMLNode (*child);
1175         }
1176
1177         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1178                 load_options (*child);
1179         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1180                 load_options (*child);
1181         } else {
1182                 error << _("Session: XML state has no options section") << endmsg;
1183         }
1184
1185         if (use_config_midi_ports ()) {
1186         }
1187
1188         if (version >= 3000) {
1189                 if ((child = find_named_node (node, "Metadata")) == 0) {
1190                         warning << _("Session: XML state has no metadata section") << endmsg;
1191                 } else if (_metadata->set_state (*child, version)) {
1192                         goto out;
1193                 }
1194         }
1195
1196         if ((child = find_named_node (node, "Locations")) == 0) {
1197                 error << _("Session: XML state has no locations section") << endmsg;
1198                 goto out;
1199         } else if (_locations.set_state (*child, version)) {
1200                 goto out;
1201         }
1202
1203         Location* location;
1204
1205         if ((location = _locations.auto_loop_location()) != 0) {
1206                 set_auto_loop_location (location);
1207         }
1208
1209         if ((location = _locations.auto_punch_location()) != 0) {
1210                 set_auto_punch_location (location);
1211         }
1212
1213         if ((location = _locations.end_location()) == 0) {
1214                 _locations.add (end_location);
1215         } else {
1216                 delete end_location;
1217                 end_location = location;
1218         }
1219
1220         if ((location = _locations.start_location()) == 0) {
1221                 _locations.add (start_location);
1222         } else {
1223                 delete start_location;
1224                 start_location = location;
1225         }
1226
1227         AudioFileSource::set_header_position_offset (start_location->start());
1228
1229         if ((child = find_named_node (node, "Sources")) == 0) {
1230                 error << _("Session: XML state has no sources section") << endmsg;
1231                 goto out;
1232         } else if (load_sources (*child)) {
1233                 goto out;
1234         }
1235
1236         if ((child = find_named_node (node, "Regions")) == 0) {
1237                 error << _("Session: XML state has no Regions section") << endmsg;
1238                 goto out;
1239         } else if (load_regions (*child)) {
1240                 goto out;
1241         }
1242
1243         if ((child = find_named_node (node, "Playlists")) == 0) {
1244                 error << _("Session: XML state has no playlists section") << endmsg;
1245                 goto out;
1246         } else if (playlists->load (*this, *child)) {
1247                 goto out;
1248         }
1249
1250         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1251                 // this is OK
1252         } else if (playlists->load_unused (*this, *child)) {
1253                 goto out;
1254         }
1255         
1256         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1257                 if (load_named_selections (*child)) {
1258                         goto out;
1259                 }
1260         }
1261
1262         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1263                 error << _("Session: XML state has no diskstreams section") << endmsg;
1264                 goto out;
1265         } else if (load_diskstreams (*child)) {
1266                 goto out;
1267         }
1268
1269         if (version >= 3000) {
1270                 if ((child = find_named_node (node, "Bundles")) == 0) {
1271                         warning << _("Session: XML state has no bundles section") << endmsg;
1272                         //goto out;
1273                 } else {
1274                         /* We can't load Bundles yet as they need to be able
1275                            to convert from port names to Port objects, which can't happen until
1276                            later */
1277                         _bundle_xml_node = new XMLNode (*child);
1278                 }
1279         }
1280         
1281         if ((child = find_named_node (node, "TempoMap")) == 0) {
1282                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1283                 goto out;
1284         } else if (_tempo_map->set_state (*child, version)) {
1285                 goto out;
1286         }
1287
1288         if ((child = find_named_node (node, "Routes")) == 0) {
1289                 error << _("Session: XML state has no routes section") << endmsg;
1290                 goto out;
1291         } else if (load_routes (*child, version)) {
1292                 goto out;
1293         }
1294
1295         if (version >= 3000) {
1296                 
1297                 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1298                         error << _("Session: XML state has no route groups section") << endmsg;
1299                         goto out;
1300                 } else if (load_route_groups (*child, version)) {
1301                         goto out;
1302                 }
1303                 
1304         } else if (version < 3000) {
1305                 
1306                 if ((child = find_named_node (node, "EditGroups")) == 0) {
1307                         error << _("Session: XML state has no edit groups section") << endmsg;
1308                         goto out;
1309                 } else if (load_route_groups (*child, version)) {
1310                         goto out;
1311                 }
1312
1313                 if ((child = find_named_node (node, "MixGroups")) == 0) {
1314                         error << _("Session: XML state has no mix groups section") << endmsg;
1315                         goto out;
1316                 } else if (load_route_groups (*child, version)) {
1317                         goto out;
1318                 }
1319         }
1320
1321         if ((child = find_named_node (node, "Click")) == 0) {
1322                 warning << _("Session: XML state has no click section") << endmsg;
1323         } else if (_click_io) {
1324                 _click_io->set_state (*child, version);
1325         }
1326
1327         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1328                 ControlProtocolManager::instance().set_protocol_states (*child);
1329         }
1330
1331         /* here beginneth the second phase ... */
1332
1333         StateReady (); /* EMIT SIGNAL */
1334
1335         return 0;
1336
1337   out:
1338         return ret;
1339 }
1340
1341 int
1342 Session::load_routes (const XMLNode& node, int version)
1343 {
1344         XMLNodeList nlist;
1345         XMLNodeConstIterator niter;
1346         RouteList new_routes;
1347
1348         nlist = node.children();
1349
1350         set_dirty();
1351
1352         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1353
1354                 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1355
1356                 if (route == 0) {
1357                         error << _("Session: cannot create Route from XML description.") << endmsg;
1358                         return -1;
1359                 }
1360
1361                 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1362
1363                 new_routes.push_back (route);
1364         }
1365
1366         add_routes (new_routes, false);
1367
1368         return 0;
1369 }
1370
1371 boost::shared_ptr<Route>
1372 Session::XMLRouteFactory (const XMLNode& node, int version)
1373 {
1374         if (node.name() != "Route") {
1375                 return boost::shared_ptr<Route> ((Route*) 0);
1376         }
1377
1378         bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1379
1380         DataType type = DataType::AUDIO;
1381         const XMLProperty* prop = node.property("default-type");
1382         boost::shared_ptr<Route> ret;
1383
1384         if (prop) {
1385                 type = DataType(prop->value());
1386         }
1387
1388         assert(type != DataType::NIL);
1389
1390         if (has_diskstream) {
1391                 if (type == DataType::AUDIO) {
1392                         AudioTrack* at = new AudioTrack (*this, node, version);
1393                         boost_debug_shared_ptr_mark_interesting (at, "Track");
1394                         ret.reset (at);
1395                         
1396                 } else {
1397                         ret.reset (new MidiTrack (*this, node, version));
1398                 }
1399         } else {
1400                 Route* rt = new Route (*this, node);
1401                 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1402                 ret.reset (rt);
1403         }
1404
1405         return ret;
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                 _route_groups.erase (i);
2107                 delete &rg;
2108
2109                 route_group_removed (); /* EMIT SIGNAL */
2110         }
2111
2112 }
2113
2114 RouteGroup *
2115 Session::route_group_by_name (string name)
2116 {
2117         list<RouteGroup *>::iterator i;
2118
2119         for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2120                 if ((*i)->name() == name) {
2121                         return* i;
2122                 }
2123         }
2124         return 0;
2125 }
2126
2127 UndoTransaction*
2128 Session::start_reversible_command (const string& name)
2129 {
2130         UndoTransaction* trans = new UndoTransaction();
2131         trans->set_name(name);
2132         return trans;
2133 }
2134
2135 void
2136 Session::finish_reversible_command (UndoTransaction& ut)
2137 {
2138         struct timeval now;
2139         gettimeofday(&now, 0);
2140         ut.set_timestamp(now);
2141         _history.add (&ut);
2142 }
2143
2144 void
2145 Session::begin_reversible_command(const string& name)
2146 {
2147         UndoTransaction* trans = new UndoTransaction();
2148         trans->set_name(name);
2149
2150         if (!_current_trans.empty()) {
2151                 _current_trans.top()->add_command (trans);
2152         } else {
2153                 _current_trans.push(trans);
2154         }
2155 }
2156
2157 void
2158 Session::commit_reversible_command(Command *cmd)
2159 {
2160         assert(!_current_trans.empty());
2161         struct timeval now;
2162
2163         if (cmd) {
2164                 _current_trans.top()->add_command(cmd);
2165         }
2166
2167         if (_current_trans.top()->empty()) {
2168                 _current_trans.pop();
2169                 return;
2170         }
2171
2172         gettimeofday(&now, 0);
2173         _current_trans.top()->set_timestamp(now);
2174
2175         _history.add(_current_trans.top());
2176         _current_trans.pop();
2177 }
2178
2179 static bool
2180 accept_all_non_peak_files (const string& path, void */*arg*/)
2181 {
2182         return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2183 }
2184
2185 static bool
2186 accept_all_state_files (const string& path, void */*arg*/)
2187 {
2188         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2189 }
2190
2191 int
2192 Session::find_all_sources (string path, set<string>& result)
2193 {
2194         XMLTree tree;
2195         XMLNode* node;
2196
2197         if (!tree.read (path)) {
2198                 return -1;
2199         }
2200
2201         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2202                 return -2;
2203         }
2204
2205         XMLNodeList nlist;
2206         XMLNodeConstIterator niter;
2207
2208         nlist = node->children();
2209
2210         set_dirty();
2211
2212         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2213
2214                 XMLProperty* prop;
2215
2216                 if ((prop = (*niter)->property (X_("type"))) == 0) {
2217                         continue;
2218                 }
2219
2220                 DataType type (prop->value());
2221
2222                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2223                         continue;
2224                 }
2225
2226                 if (prop->value()[0] == '/') {
2227                         /* external file, ignore */
2228                         continue;
2229                 }
2230
2231                 Glib::ustring found_path;
2232                 bool is_new;
2233                 uint16_t chan;
2234
2235                 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2236                         result.insert (found_path);
2237                 }
2238         }
2239
2240         return 0;
2241 }
2242
2243 int
2244 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2245 {
2246         PathScanner scanner;
2247         vector<string*>* state_files;
2248         string ripped;
2249         string this_snapshot_path;
2250
2251         result.clear ();
2252
2253         ripped = _path;
2254
2255         if (ripped[ripped.length()-1] == '/') {
2256                 ripped = ripped.substr (0, ripped.length() - 1);
2257         }
2258
2259         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2260
2261         if (state_files == 0) {
2262                 /* impossible! */
2263                 return 0;
2264         }
2265
2266         this_snapshot_path = _path;
2267         this_snapshot_path += legalize_for_path (_current_snapshot_name);
2268         this_snapshot_path += statefile_suffix;
2269
2270         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2271
2272                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2273                         continue;
2274                 }
2275
2276                 if (find_all_sources (**i, result) < 0) {
2277                         return -1;
2278                 }
2279         }
2280
2281         return 0;
2282 }
2283
2284 struct RegionCounter {
2285     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2286     AudioSourceList::iterator iter;
2287     boost::shared_ptr<Region> region;
2288     uint32_t count;
2289
2290     RegionCounter() : count (0) {}
2291 };
2292
2293 int
2294 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2295 {
2296         return *AskAboutPlaylistDeletion (p);
2297 }
2298
2299 int
2300 Session::cleanup_sources (CleanupReport& rep)
2301 {
2302         // FIXME: needs adaptation to midi
2303
2304         vector<boost::shared_ptr<Source> > dead_sources;
2305         PathScanner scanner;
2306         string sound_path;
2307         vector<space_and_path>::iterator i;
2308         vector<space_and_path>::iterator nexti;
2309         vector<string*>* soundfiles;
2310         vector<string> unused;
2311         set<string> all_sources;
2312         bool used;
2313         string spath;
2314         int ret = -1;
2315
2316         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2317
2318         /* step 1: consider deleting all unused playlists */
2319         
2320         if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2321                 ret = 0;
2322                 goto out;
2323         }
2324
2325         /* step 2: find all un-used sources */
2326
2327         rep.paths.clear ();
2328         rep.space = 0;
2329
2330         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2331
2332                 SourceMap::iterator tmp;
2333
2334                 tmp = i;
2335                 ++tmp;
2336
2337                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2338                    capture files.
2339                 */
2340
2341                 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2342                         dead_sources.push_back (i->second);
2343                         i->second->drop_references ();
2344                 }
2345
2346                 i = tmp;
2347         }
2348
2349         /* build a list of all the possible sound directories for the session */
2350
2351         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2352
2353                 nexti = i;
2354                 ++nexti;
2355
2356                 SessionDirectory sdir ((*i).path);
2357                 sound_path += sdir.sound_path().to_string();
2358
2359                 if (nexti != session_dirs.end()) {
2360                         sound_path += ':';
2361                 }
2362
2363                 i = nexti;
2364         }
2365
2366         /* now do the same thing for the files that ended up in the sounds dir(s)
2367            but are not referenced as sources in any snapshot.
2368         */
2369
2370         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2371
2372         if (soundfiles == 0) {
2373                 return 0;
2374         }
2375
2376         /* find all sources, but don't use this snapshot because the
2377            state file on disk still references sources we may have already
2378            dropped.
2379         */
2380
2381         find_all_sources_across_snapshots (all_sources, true);
2382
2383         /*  add our current source list
2384          */
2385
2386         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2387                 boost::shared_ptr<FileSource> fs;
2388
2389                 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2390                         all_sources.insert (fs->path());
2391                 }
2392         }
2393
2394         char tmppath1[PATH_MAX+1];
2395         char tmppath2[PATH_MAX+1];
2396
2397         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2398
2399                 used = false;
2400                 spath = **x;
2401
2402                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2403
2404                         realpath(spath.c_str(), tmppath1);
2405                         realpath((*i).c_str(),  tmppath2);
2406
2407                         if (strcmp(tmppath1, tmppath2) == 0) {
2408                                 used = true;
2409                                 break;
2410                         }
2411                 }
2412
2413                 if (!used) {
2414                         unused.push_back (spath);
2415                 }
2416         }
2417
2418         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2419
2420         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2421                 struct stat statbuf;
2422
2423                 rep.paths.push_back (*x);
2424                 if (stat ((*x).c_str(), &statbuf) == 0) {
2425                         rep.space += statbuf.st_size;
2426                 }
2427
2428                 string newpath;
2429
2430                 /* don't move the file across filesystems, just
2431                    stick it in the `dead_sound_dir_name' directory
2432                    on whichever filesystem it was already on.
2433                 */
2434
2435                 if ((*x).find ("/sounds/") != string::npos) {
2436
2437                         /* old school, go up 1 level */
2438
2439                         newpath = Glib::path_get_dirname (*x);      // "sounds"
2440                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2441
2442                 } else {
2443
2444                         /* new school, go up 4 levels */
2445
2446                         newpath = Glib::path_get_dirname (*x);      // "audiofiles"
2447                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2448                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2449                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2450                 }
2451
2452                 newpath += '/';
2453                 newpath += dead_sound_dir_name;
2454
2455                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2456                         error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2457                         return -1;
2458                 }
2459
2460                 newpath += '/';
2461                 newpath += Glib::path_get_basename ((*x));
2462
2463                 if (access (newpath.c_str(), F_OK) == 0) {
2464
2465                         /* the new path already exists, try versioning */
2466
2467                         char buf[PATH_MAX+1];
2468                         int version = 1;
2469                         string newpath_v;
2470
2471                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2472                         newpath_v = buf;
2473
2474                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2475                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2476                                 newpath_v = buf;
2477                         }
2478
2479                         if (version == 999) {
2480                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2481                                                   newpath)
2482                                       << endmsg;
2483                         } else {
2484                                 newpath = newpath_v;
2485                         }
2486
2487                 } else {
2488
2489                         /* it doesn't exist, or we can't read it or something */
2490
2491                 }
2492
2493                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2494                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2495                                           (*x), newpath, strerror (errno))
2496                               << endmsg;
2497                         goto out;
2498                 }
2499
2500                 /* see if there an easy to find peakfile for this file, and remove it.
2501                  */
2502
2503                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2504                 peakpath += peakfile_suffix;
2505
2506                 if (access (peakpath.c_str(), W_OK) == 0) {
2507                         if (::unlink (peakpath.c_str()) != 0) {
2508                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2509                                                   peakpath, _path, strerror (errno))
2510                                       << endmsg;
2511                                 /* try to back out */
2512                                 rename (newpath.c_str(), _path.c_str());
2513                                 goto out;
2514                         }
2515                 }
2516         }
2517
2518         ret = 0;
2519
2520         /* dump the history list */
2521
2522         _history.clear ();
2523
2524         /* save state so we don't end up a session file
2525            referring to non-existent sources.
2526         */
2527
2528         save_state ("");
2529
2530   out:
2531         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2532
2533         return ret;
2534 }
2535
2536 int
2537 Session::cleanup_trash_sources (CleanupReport& rep)
2538 {
2539         // FIXME: needs adaptation for MIDI
2540
2541         vector<space_and_path>::iterator i;
2542         string dead_sound_dir;
2543         struct dirent* dentry;
2544         struct stat statbuf;
2545         DIR* dead;
2546
2547         rep.paths.clear ();
2548         rep.space = 0;
2549
2550         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2551
2552                 dead_sound_dir = (*i).path;
2553                 dead_sound_dir += dead_sound_dir_name;
2554
2555                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2556                         continue;
2557                 }
2558
2559                 while ((dentry = readdir (dead)) != 0) {
2560
2561                         /* avoid '.' and '..' */
2562
2563                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2564                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2565                                 continue;
2566                         }
2567
2568                         string fullpath;
2569
2570                         fullpath = dead_sound_dir;
2571                         fullpath += '/';
2572                         fullpath += dentry->d_name;
2573
2574                         if (stat (fullpath.c_str(), &statbuf)) {
2575                                 continue;
2576                         }
2577
2578                         if (!S_ISREG (statbuf.st_mode)) {
2579                                 continue;
2580                         }
2581
2582                         if (unlink (fullpath.c_str())) {
2583                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2584                                                   fullpath, strerror (errno))
2585                                       << endmsg;
2586                         }
2587
2588                         rep.paths.push_back (dentry->d_name);
2589                         rep.space += statbuf.st_size;
2590                 }
2591
2592                 closedir (dead);
2593
2594         }
2595
2596         return 0;
2597 }
2598
2599 void
2600 Session::set_dirty ()
2601 {
2602         bool was_dirty = dirty();
2603
2604         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2605
2606
2607         if (!was_dirty) {
2608                 DirtyChanged(); /* EMIT SIGNAL */
2609         }
2610 }
2611
2612
2613 void
2614 Session::set_clean ()
2615 {
2616         bool was_dirty = dirty();
2617
2618         _state_of_the_state = Clean;
2619
2620
2621         if (was_dirty) {
2622                 DirtyChanged(); /* EMIT SIGNAL */
2623         }
2624 }
2625
2626 void
2627 Session::set_deletion_in_progress ()
2628 {
2629         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2630 }
2631
2632 void
2633 Session::clear_deletion_in_progress ()
2634 {
2635         _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2636 }
2637
2638 void
2639 Session::add_controllable (boost::shared_ptr<Controllable> c)
2640 {
2641         /* this adds a controllable to the list managed by the Session.
2642            this is a subset of those managed by the Controllable class
2643            itself, and represents the only ones whose state will be saved
2644            as part of the session.
2645         */
2646
2647         Glib::Mutex::Lock lm (controllables_lock);
2648         controllables.insert (c);
2649 }
2650
2651 struct null_deleter { void operator()(void const *) const {} };
2652
2653 void
2654 Session::remove_controllable (Controllable* c)
2655 {
2656         if (_state_of_the_state | Deletion) {
2657                 return;
2658         }
2659
2660         Glib::Mutex::Lock lm (controllables_lock);
2661
2662         Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2663
2664         if (x != controllables.end()) {
2665                 controllables.erase (x);
2666         }
2667 }
2668
2669 boost::shared_ptr<Controllable>
2670 Session::controllable_by_id (const PBD::ID& id)
2671 {
2672         Glib::Mutex::Lock lm (controllables_lock);
2673
2674         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2675                 if ((*i)->id() == id) {
2676                         return *i;
2677                 }
2678         }
2679
2680         return boost::shared_ptr<Controllable>();
2681 }
2682
2683 boost::shared_ptr<Controllable>
2684 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2685 {
2686         boost::shared_ptr<Controllable> c;
2687         boost::shared_ptr<Route> r;
2688
2689         switch (desc.top_level_type()) {
2690         case ControllableDescriptor::NamedRoute:
2691         {
2692                 std::string str = desc.top_level_name();
2693                 if (str == "master") {
2694                         r = _master_out;
2695                 } else if (str == "control" || str == "listen") {
2696                         r = _control_out;
2697                 } else {
2698                         r = route_by_name (desc.top_level_name());
2699                 }
2700                 break;
2701         }
2702
2703         case ControllableDescriptor::RemoteControlID:
2704                 r = route_by_remote_id (desc.rid());
2705                 break;
2706         }
2707         
2708         if (!r) {
2709                 return c;
2710         }
2711
2712         switch (desc.subtype()) {
2713         case ControllableDescriptor::Gain:
2714                 c = r->gain_control ();
2715                 break;
2716
2717         case ControllableDescriptor::Solo:
2718                 c = r->solo_control();
2719                 break;
2720
2721         case ControllableDescriptor::Mute:
2722                 c = r->mute_control();
2723                 break;
2724
2725         case ControllableDescriptor::Recenable:
2726         {
2727                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2728                 
2729                 if (t) {
2730                         c = t->rec_enable_control ();
2731                 }
2732                 break;
2733         }
2734
2735         case ControllableDescriptor::Pan:
2736                 /* XXX pan control */
2737                 break;
2738
2739         case ControllableDescriptor::Balance:
2740                 /* XXX simple pan control */
2741                 break;
2742
2743         case ControllableDescriptor::PluginParameter:
2744         {
2745                 uint32_t plugin = desc.target (0);
2746                 uint32_t parameter_index = desc.target (1);
2747
2748                 /* revert to zero based counting */
2749                 
2750                 if (plugin > 0) {
2751                         --plugin;
2752                 }
2753                 
2754                 if (parameter_index > 0) {
2755                         --parameter_index;
2756                 }
2757
2758                 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2759                 
2760                 if (p) {
2761                         c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2762                                 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2763                 }
2764                 break;
2765         }
2766
2767         case ControllableDescriptor::SendGain: 
2768         {
2769                 uint32_t send = desc.target (0);
2770
2771                 /* revert to zero-based counting */
2772                 
2773                 if (send > 0) {
2774                         --send;
2775                 }
2776                 
2777                 boost::shared_ptr<Processor> p = r->nth_send (send);
2778                 
2779                 if (p) {
2780                         boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2781                         boost::shared_ptr<Amp> a = s->amp();
2782
2783                         if (a) {
2784                                 c = s->amp()->gain_control();
2785                         }
2786                 }
2787                 break;
2788         }
2789
2790         default:
2791                 /* relax and return a null pointer */
2792                 break;
2793         }
2794
2795         return c;
2796 }
2797
2798 void
2799 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2800 {
2801         if (_writable) {
2802                 Stateful::add_instant_xml (node, _path);
2803         }
2804
2805         if (write_to_config) {
2806                 Config->add_instant_xml (node);
2807         }
2808 }
2809
2810 XMLNode*
2811 Session::instant_xml (const string& node_name)
2812 {
2813         return Stateful::instant_xml (node_name, _path);
2814 }
2815
2816 int
2817 Session::save_history (string snapshot_name)
2818 {
2819         XMLTree tree;
2820
2821         if (!_writable) {
2822                 return 0;
2823         }
2824
2825         if (snapshot_name.empty()) {
2826                 snapshot_name = _current_snapshot_name;
2827         }
2828
2829         const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2830         const string backup_filename = history_filename + backup_suffix;
2831         const sys::path xml_path = _session_dir->root_path() / history_filename;
2832         const sys::path backup_path = _session_dir->root_path() / backup_filename;
2833
2834         if (sys::exists (xml_path)) {
2835                 try
2836                 {
2837                         sys::rename (xml_path, backup_path);
2838                 }
2839                 catch (const sys::filesystem_error& err)
2840                 {
2841                         error << _("could not backup old history file, current history not saved") << endmsg;
2842                         return -1;
2843                 }
2844         }
2845
2846         if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2847                 return 0;
2848         }
2849
2850         tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2851
2852         if (!tree.write (xml_path.to_string()))
2853         {
2854                 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2855
2856                 try
2857                 {
2858                         sys::remove (xml_path);
2859                         sys::rename (backup_path, xml_path);
2860                 }
2861                 catch (const sys::filesystem_error& err)
2862                 {
2863                         error << string_compose (_("could not restore history file from backup %1 (%2)"),
2864                                         backup_path.to_string(), err.what()) << endmsg;
2865                 }
2866
2867                 return -1;
2868         }
2869
2870         return 0;
2871 }
2872
2873 int
2874 Session::restore_history (string snapshot_name)
2875 {
2876         XMLTree tree;
2877
2878         if (snapshot_name.empty()) {
2879                 snapshot_name = _current_snapshot_name;
2880         }
2881
2882         const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2883         const sys::path xml_path = _session_dir->root_path() / xml_filename;
2884
2885         info << "Loading history from " << xml_path.to_string() << endmsg;
2886
2887         if (!sys::exists (xml_path)) {
2888                 info << string_compose (_("%1: no history file \"%2\" for this session."),
2889                                 _name, xml_path.to_string()) << endmsg;
2890                 return 1;
2891         }
2892
2893         if (!tree.read (xml_path.to_string())) {
2894                 error << string_compose (_("Could not understand session history file \"%1\""),
2895                                 xml_path.to_string()) << endmsg;
2896                 return -1;
2897         }
2898
2899         // replace history
2900         _history.clear();
2901
2902         for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2903
2904                 XMLNode *t = *it;
2905                 UndoTransaction* ut = new UndoTransaction ();
2906                 struct timeval tv;
2907
2908                 ut->set_name(t->property("name")->value());
2909                 stringstream ss(t->property("tv-sec")->value());
2910                 ss >> tv.tv_sec;
2911                 ss.str(t->property("tv-usec")->value());
2912                 ss >> tv.tv_usec;
2913                 ut->set_timestamp(tv);
2914
2915                 for (XMLNodeConstIterator child_it  = t->children().begin();
2916                                 child_it != t->children().end(); child_it++)
2917                 {
2918                         XMLNode *n = *child_it;
2919                         Command *c;
2920
2921                         if (n->name() == "MementoCommand" ||
2922                                         n->name() == "MementoUndoCommand" ||
2923                                         n->name() == "MementoRedoCommand") {
2924
2925                                 if ((c = memento_command_factory(n))) {
2926                                         ut->add_command(c);
2927                                 }
2928
2929                         } else if (n->name() == "DeltaCommand") {
2930                                 PBD::ID  id(n->property("midi-source")->value());
2931                                 boost::shared_ptr<MidiSource> midi_source =
2932                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2933                                 if (midi_source) {
2934                                         ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2935                                 } else {
2936                                         error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2937                                 }
2938
2939                         } else if (n->name() == "DiffCommand") {
2940                                 PBD::ID  id(n->property("midi-source")->value());
2941                                 boost::shared_ptr<MidiSource> midi_source =
2942                                         boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2943                                 if (midi_source) {
2944                                         ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2945                                 } else {
2946                                         error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2947                                 }
2948
2949                         } else if (n->name() == "RegionCommand") {
2950                                 PBD::ID id (n->property ("region")->value());
2951                                 boost::shared_ptr<Region> region = RegionFactory::region_by_id (id);
2952
2953                                 if (region) {
2954                                         ut->add_command (new RegionCommand (region, *n));
2955                                 } else {
2956                                         error << string_compose (_("Region command references an unknown region ID=%1"), id.to_s()) << endmsg;
2957                                 }
2958
2959                         } else if (n->name() == "StatefulDiffCommand") {
2960                                 if ((c = stateful_diff_command_factory (n))) {
2961                                         ut->add_command (c);
2962                                 }
2963                         } else {
2964                                 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2965                         }
2966                 }
2967
2968                 _history.add (ut);
2969         }
2970
2971         return 0;
2972 }
2973
2974 void
2975 Session::config_changed (std::string p, bool ours)
2976 {
2977         if (ours) {
2978                 set_dirty ();
2979         }
2980
2981         if (p == "seamless-loop") {
2982
2983         } else if (p == "rf-speed") {
2984
2985         } else if (p == "auto-loop") {
2986
2987         } else if (p == "auto-input") {
2988
2989                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2990                         /* auto-input only makes a difference if we're rolling */
2991
2992                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2993
2994                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2995                                 if ((*i)->record_enabled ()) {
2996                                         (*i)->monitor_input (!config.get_auto_input());
2997                                 }
2998                         }
2999                 }
3000
3001         } else if (p == "punch-in") {
3002
3003                 Location* location;
3004
3005                 if ((location = _locations.auto_punch_location()) != 0) {
3006
3007                         if (config.get_punch_in ()) {
3008                                 replace_event (SessionEvent::PunchIn, location->start());
3009                         } else {
3010                                 remove_event (location->start(), SessionEvent::PunchIn);
3011                         }
3012                 }
3013
3014         } else if (p == "punch-out") {
3015
3016                 Location* location;
3017
3018                 if ((location = _locations.auto_punch_location()) != 0) {
3019
3020                         if (config.get_punch_out()) {
3021                                 replace_event (SessionEvent::PunchOut, location->end());
3022                         } else {
3023                                 clear_events (SessionEvent::PunchOut);
3024                         }
3025                 }
3026
3027         } else if (p == "edit-mode") {
3028
3029                 Glib::Mutex::Lock lm (playlists->lock);
3030
3031                 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3032                         (*i)->set_edit_mode (Config->get_edit_mode ());
3033                 }
3034
3035         } else if (p == "use-video-sync") {
3036
3037                 waiting_for_sync_offset = config.get_use_video_sync();
3038
3039         } else if (p == "mmc-control") {
3040
3041                 //poke_midi_thread ();
3042
3043         } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3044
3045                 if (mmc) {
3046                         mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3047                 }
3048
3049         } else if (p == "mmc-send-id") {
3050
3051                 if (mmc) {
3052                         mmc->set_send_device_id (Config->get_mmc_send_device_id());
3053                 }
3054
3055         } else if (p == "midi-control") {
3056
3057                 //poke_midi_thread ();
3058
3059         } else if (p == "raid-path") {
3060
3061                 setup_raid_path (config.get_raid_path());
3062
3063         } else if (p == "timecode-format") {
3064
3065                 sync_time_vars ();
3066
3067         } else if (p == "video-pullup") {
3068
3069                 sync_time_vars ();
3070
3071         } else if (p == "seamless-loop") {
3072
3073                 if (play_loop && transport_rolling()) {
3074                         // to reset diskstreams etc
3075                         request_play_loop (true);
3076                 }
3077
3078         } else if (p == "rf-speed") {
3079
3080                 cumulative_rf_motion = 0;
3081                 reset_rf_scale (0);
3082
3083         } else if (p == "click-sound") {
3084
3085                 setup_click_sounds (1);
3086
3087         } else if (p == "click-emphasis-sound") {
3088
3089                 setup_click_sounds (-1);
3090
3091         } else if (p == "clicking") {
3092
3093                 if (Config->get_clicking()) {
3094                         if (_click_io && click_data) { // don't require emphasis data
3095                                 _clicking = true;
3096                         }
3097                 } else {
3098                         _clicking = false;
3099                 }
3100
3101         } else if (p == "send-mtc") {
3102
3103                 /* only set the internal flag if we have
3104                    a port.
3105                 */
3106
3107                 if (_mtc_port != 0) {
3108                         session_send_mtc = Config->get_send_mtc();
3109                         if (session_send_mtc) {
3110                                 /* mark us ready to send */
3111                                 next_quarter_frame_to_send = 0;
3112                         }
3113                 } else {
3114                         session_send_mtc = false;
3115                 }
3116
3117         } else if (p == "send-mmc") {
3118
3119                 /* only set the internal flag if we have
3120                    a port.
3121                 */
3122
3123                 if (_mmc_port != 0) {
3124                         session_send_mmc = Config->get_send_mmc();
3125                 } else {
3126                         mmc = 0;
3127                         session_send_mmc = false;
3128                 }
3129
3130         } else if (p == "midi-feedback") {
3131
3132                 /* only set the internal flag if we have
3133                    a port.
3134                 */
3135
3136                 if (_mtc_port != 0) {
3137                         session_midi_feedback = Config->get_midi_feedback();
3138                 }
3139
3140         } else if (p == "jack-time-master") {
3141
3142                 engine().reset_timebase ();
3143
3144         } else if (p == "native-file-header-format") {
3145
3146                 if (!first_file_header_format_reset) {
3147                         reset_native_file_format ();
3148                 }
3149
3150                 first_file_header_format_reset = false;
3151
3152         } else if (p == "native-file-data-format") {
3153
3154                 if (!first_file_data_format_reset) {
3155                         reset_native_file_format ();
3156                 }
3157
3158                 first_file_data_format_reset = false;
3159
3160         } else if (p == "external-sync") {
3161                 if (!config.get_external_sync()) {
3162                         drop_sync_source ();
3163                 } else {
3164                         switch_to_sync_source (config.get_sync_source());
3165                 }
3166         } else if (p == "remote-model") {
3167                 set_remote_control_ids ();
3168         }  else if (p == "denormal-model") {
3169                 setup_fpu ();
3170         } else if (p == "history-depth") {
3171                 set_history_depth (Config->get_history_depth());
3172         } else if (p == "sync-all-route-ordering") {
3173                 sync_order_keys ("session");
3174         } else if (p == "initial-program-change") {
3175
3176                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3177                         MIDI::byte buf[2];
3178
3179                         buf[0] = MIDI::program; // channel zero by default
3180                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3181
3182                         _mmc_port->midimsg (buf, sizeof (buf), 0);
3183                 }
3184         } else if (p == "initial-program-change") {
3185
3186                 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3187                         MIDI::byte* buf = new MIDI::byte[2];
3188
3189                         buf[0] = MIDI::program; // channel zero by default
3190                         buf[1] = (Config->get_initial_program_change() & 0x7f);
3191                         // deliver_midi (_mmc_port, buf, 2);
3192                 }
3193         } else if (p == "solo-mute-override") {
3194                 // catch_up_on_solo_mute_override ();
3195         } else if (p == "listen-position") {
3196                 listen_position_changed ();
3197         } else if (p == "solo-control-is-listen-control") {
3198                 solo_control_mode_changed ();
3199         }
3200
3201
3202         set_dirty ();
3203 }
3204
3205 void
3206 Session::set_history_depth (uint32_t d)
3207 {
3208         _history.set_depth (d);
3209 }