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