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