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