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