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