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