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