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