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