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