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