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