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