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