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