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