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