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