a) persist whether the end marker should move at first capture in the session file
[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
85 #include "i18n.h"
86 #include <locale.h>
87
88 using namespace std;
89 using namespace ARDOUR;
90
91 void
92 Session::first_stage_init (string fullpath, string snapshot_name)
93 {
94         if (fullpath.length() == 0) {
95                 throw failed_constructor();
96         }
97
98         char buf[PATH_MAX+1];
99         if (!realpath(fullpath.c_str(), buf) && (errno != ENOENT)) {
100                 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
101                 throw failed_constructor();
102         }
103         _path = string(buf);
104
105         if (_path[_path.length()-1] != '/') {
106                 _path += '/';
107         }
108
109         /* these two are just provisional settings. set_state()
110            will likely override them.
111         */
112
113         _name = _current_snapshot_name = snapshot_name;
114         setup_raid_path (_path);
115
116         _current_frame_rate = _engine.frame_rate ();
117         _tempo_map = new TempoMap (_current_frame_rate);
118         _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
119
120         atomic_set (&processing_prohibited, 0);
121         send_cnt = 0;
122         insert_cnt = 0;
123         _transport_speed = 0;
124         _last_transport_speed = 0;
125         transport_sub_state = 0;
126         _transport_frame = 0;
127         last_stop_frame = 0;
128         end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
129         start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
130         _end_location_is_free = true;
131         atomic_set (&_record_status, Disabled);
132         auto_play = false;
133         punch_in = false;
134         punch_out = false;
135         auto_loop = false;
136         seamless_loop = false;
137         loop_changing = false;
138         auto_input = true;
139         crossfades_active = false;
140         all_safe = false;
141         auto_return = false;
142         _last_roll_location = 0;
143         _last_record_location = 0;
144         pending_locate_frame = 0;
145         pending_locate_roll = false;
146         pending_locate_flush = false;
147         dstream_buffer_size = 0;
148         state_tree = 0;
149         state_was_pending = false;
150         set_next_event ();
151         outbound_mtc_smpte_frame = 0;
152         next_quarter_frame_to_send = -1;
153         current_block_size = 0;
154         _solo_latched = true;
155         _solo_model = InverseMute;
156         solo_update_disabled = false;
157         currently_soloing = false;
158         _have_captured = false;
159         _worst_output_latency = 0;
160         _worst_input_latency = 0;
161         _worst_track_latency = 0;
162         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
163         _slave = 0;
164         _slave_type = None;
165         butler_mixdown_buffer = 0;
166         butler_gain_buffer = 0;
167         auditioner = 0;
168         mmc_control = false;
169         midi_feedback = 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         if (start_midi_thread ()) {
301                 return -1;
302         }
303
304         if (init_feedback ()) {
305                 return -1;
306         }
307
308         if (state_tree) {
309                 if (set_state (*state_tree->root())) {
310                         return -1;
311                 }
312         }
313
314         /* we can't save till after ::when_engine_running() is called,
315            because otherwise we save state with no connections made.
316            therefore, we reset _state_of_the_state because ::set_state()
317            will have cleared it.
318
319            we also have to include Loading so that any events that get
320            generated between here and the end of ::when_engine_running()
321            will be processed directly rather than queued.
322         */
323
324         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325
326         // set_auto_input (true);
327         _locations.changed.connect (mem_fun (this, &Session::locations_changed));
328         _locations.added.connect (mem_fun (this, &Session::locations_added));
329         setup_click_sounds (0);
330         setup_midi_control ();
331
332         /* Pay attention ... */
333
334         _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
335         _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
336
337         if (_engine.running()) {
338                 when_engine_running();
339         } else {
340                 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
341         }
342
343         send_full_time_code ();
344         _engine.transport_locate (0);
345         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
346         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
347         send_all_midi_feedback();
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::template_path ()
2300 {
2301         string path;
2302
2303         path += get_user_ardour_path();
2304         if (path[path.length()-1] != ':') {
2305                 path += ':';
2306         }
2307         path += get_system_ardour_path();
2308
2309         vector<string> split_path;
2310         
2311         split (path, split_path, ':');
2312         path = "";
2313
2314         for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2315                 path += *i;
2316                 path += "templates/";
2317                 
2318                 if (distance (i, split_path.end()) != 1) {
2319                         path += ':';
2320                 }
2321         }
2322                 
2323         return path;
2324 }
2325
2326 int
2327 Session::load_connections (const XMLNode& node)
2328 {
2329         XMLNodeList nlist = node.children();
2330         XMLNodeConstIterator niter;
2331
2332         set_dirty();
2333
2334         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2335                 if ((*niter)->name() == "InputConnection") {
2336                         add_connection (new ARDOUR::InputConnection (**niter));
2337                 } else if ((*niter)->name() == "OutputConnection") {
2338                         add_connection (new ARDOUR::OutputConnection (**niter));
2339                 } else {
2340                         error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2341                         return -1;
2342                 }
2343         }
2344
2345         return 0;
2346 }                               
2347
2348 int
2349 Session::load_edit_groups (const XMLNode& node)
2350 {
2351         return load_route_groups (node, true);
2352 }
2353
2354 int
2355 Session::load_mix_groups (const XMLNode& node)
2356 {
2357         return load_route_groups (node, false);
2358 }
2359
2360 int
2361 Session::load_route_groups (const XMLNode& node, bool edit)
2362 {
2363         XMLNodeList nlist = node.children();
2364         XMLNodeConstIterator niter;
2365         RouteGroup* route;
2366
2367         set_dirty();
2368
2369         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2370                 if ((*niter)->name() == "RouteGroup") {
2371                         if (edit) {
2372                                 route = add_edit_group ("");
2373                                 route->set_state (**niter);
2374                         } else {
2375                                 route = add_mix_group ("");
2376                                 route->set_state (**niter);
2377                         }
2378                 }
2379         }
2380         
2381         return 0;
2382 }                               
2383
2384 void
2385 Session::swap_configuration(Configuration** new_config)
2386 {
2387         RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2388         Configuration* tmp = *new_config;
2389         *new_config = Config;
2390         Config = tmp;
2391         set_dirty();
2392 }
2393
2394 void
2395 Session::copy_configuration(Configuration* new_config)
2396 {
2397         RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2398         new_config = new Configuration(*Config);
2399 }
2400
2401 static bool
2402 state_file_filter (const string &str, void *arg)
2403 {
2404         return (str.length() > strlen(Session::statefile_suffix()) &&
2405                 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2406 }
2407
2408 struct string_cmp {
2409         bool operator()(const string* a, const string* b) {
2410                 return *a < *b;
2411         }
2412 };
2413
2414 static string*
2415 remove_end(string* state)
2416 {
2417         string statename(*state);
2418         
2419         string::size_type start,end;
2420         if ((start = statename.find_last_of ('/')) != string::npos) {
2421                 statename = statename.substr (start+1);
2422         }
2423                 
2424         if ((end = statename.rfind(".ardour")) < 0) {
2425                 end = statename.length();
2426         }
2427
2428         return new string(statename.substr (0, end));
2429 }
2430
2431 vector<string *> *
2432 Session::possible_states (string path) 
2433 {
2434         PathScanner scanner;
2435         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2436         
2437         transform(states->begin(), states->end(), states->begin(), remove_end);
2438         
2439         string_cmp cmp;
2440         sort (states->begin(), states->end(), cmp);
2441         
2442         return states;
2443 }
2444
2445 vector<string *> *
2446 Session::possible_states () const
2447 {
2448         return possible_states(_path);
2449 }
2450
2451 void
2452 Session::auto_save()
2453 {
2454         save_state (_current_snapshot_name);
2455 }
2456
2457 RouteGroup *
2458 Session::add_edit_group (string name)
2459 {
2460         RouteGroup* rg = new RouteGroup (*this, name);
2461         edit_groups.push_back (rg);
2462         edit_group_added (rg); /* EMIT SIGNAL */
2463         set_dirty();
2464         return rg;
2465 }
2466
2467 RouteGroup *
2468 Session::add_mix_group (string name)
2469 {
2470         RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2471         mix_groups.push_back (rg);
2472         mix_group_added (rg); /* EMIT SIGNAL */
2473         set_dirty();
2474         return rg;
2475 }
2476
2477 void
2478 Session::remove_edit_group (RouteGroup& rg)
2479 {
2480         list<RouteGroup*>::iterator i;
2481
2482         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2483                 (*i)->apply (&Route::drop_edit_group, this);
2484                 edit_groups.erase (i);
2485                 edit_group_removed (); /* EMIT SIGNAL */
2486         }
2487
2488         delete &rg;
2489 }
2490
2491 void
2492 Session::remove_mix_group (RouteGroup& rg)
2493 {
2494         list<RouteGroup*>::iterator i;
2495
2496         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2497                 (*i)->apply (&Route::drop_mix_group, this);
2498                 mix_groups.erase (i);
2499                 mix_group_removed (); /* EMIT SIGNAL */
2500         }
2501
2502         delete &rg;
2503 }
2504
2505 RouteGroup *
2506 Session::mix_group_by_name (string name)
2507 {
2508         list<RouteGroup *>::iterator i;
2509
2510         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2511                 if ((*i)->name() == name) {
2512                         return* i;
2513                 }
2514         }
2515         return 0;
2516 }
2517
2518 RouteGroup *
2519 Session::edit_group_by_name (string name)
2520 {
2521         list<RouteGroup *>::iterator i;
2522
2523         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2524                 if ((*i)->name() == name) {
2525                         return* i;
2526                 }
2527         }
2528         return 0;
2529 }
2530
2531 void
2532 Session::set_meter_hold (float val)
2533 {
2534         _meter_hold = val;
2535         MeterHoldChanged(); // emit
2536 }
2537
2538 void
2539 Session::set_meter_falloff (float val)
2540 {
2541         _meter_falloff = val;
2542         MeterFalloffChanged(); // emit
2543 }
2544
2545
2546 void
2547 Session::begin_reversible_command (string name, UndoAction* private_undo)
2548 {
2549         current_cmd.clear ();
2550         current_cmd.set_name (name);
2551
2552         if (private_undo) {
2553                 current_cmd.add_undo (*private_undo);
2554         }
2555 }
2556
2557 void
2558 Session::commit_reversible_command (UndoAction* private_redo)
2559 {
2560         struct timeval now;
2561
2562         if (private_redo) {
2563                 current_cmd.add_redo_no_execute (*private_redo);
2564         }
2565
2566         gettimeofday (&now, 0);
2567         current_cmd.set_timestamp (now);
2568
2569         history.add (current_cmd);
2570 }
2571
2572 Session::GlobalRouteBooleanState 
2573 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2574 {
2575         GlobalRouteBooleanState s;
2576         RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2577
2578         for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2579                 if (!(*i)->hidden()) {
2580                         RouteBooleanState v;
2581                         
2582                         v.first =* i;
2583                         v.second = ((*i)->*method)();
2584                         
2585                         s.push_back (v);
2586                 }
2587         }
2588
2589         return s;
2590 }
2591
2592 Session::GlobalRouteMeterState
2593 Session::get_global_route_metering ()
2594 {
2595         GlobalRouteMeterState s;
2596         RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2597
2598         for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2599                 if (!(*i)->hidden()) {
2600                         RouteMeterState v;
2601                         
2602                         v.first =* i;
2603                         v.second = (*i)->meter_point();
2604                         
2605                         s.push_back (v);
2606                 }
2607         }
2608
2609         return s;
2610 }
2611
2612 void
2613 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2614 {
2615         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2616                 i->first->set_meter_point (i->second, arg);
2617         }
2618 }
2619
2620 void
2621 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2622 {
2623         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2624                 (i->first->*method) (i->second, arg);
2625         }
2626 }
2627
2628 void
2629 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2630 {
2631         set_global_route_boolean (s, &Route::set_mute, src);
2632 }
2633
2634 void
2635 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2636 {
2637         set_global_route_boolean (s, &Route::set_solo, src);
2638 }
2639
2640 void
2641 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2642 {
2643         set_global_route_boolean (s, &Route::set_record_enable, src);
2644 }
2645
2646 UndoAction
2647 Session::global_mute_memento (void* src)
2648 {
2649         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2650 }
2651
2652 UndoAction
2653 Session::global_metering_memento (void* src)
2654 {
2655         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2656 }
2657
2658 UndoAction
2659 Session::global_solo_memento (void* src)
2660 {
2661         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2662 }
2663
2664 UndoAction
2665 Session::global_record_enable_memento (void* src)
2666 {
2667         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2668 }
2669
2670 static bool
2671 template_filter (const string &str, void *arg)
2672 {
2673         return (str.length() > strlen(Session::template_suffix()) &&
2674                 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2675 }
2676
2677 void
2678 Session::get_template_list (list<string> &template_names)
2679 {
2680         vector<string *> *templates;
2681         PathScanner scanner;
2682         string path;
2683
2684         path = template_path ();
2685
2686         templates = scanner (path, template_filter, 0, false, true);
2687         
2688         vector<string*>::iterator i;
2689         for (i = templates->begin(); i != templates->end(); ++i) {
2690                 string fullpath = *(*i);
2691                 int start, end;
2692
2693                 start = fullpath.find_last_of ('/') + 1;
2694                 if ((end = fullpath.find_last_of ('.')) <0) {
2695                         end = fullpath.length();
2696                 }
2697                 
2698                 template_names.push_back(fullpath.substr(start, (end-start)));
2699         }
2700 }
2701
2702 int
2703 Session::read_favorite_dirs (FavoriteDirs & favs)
2704 {
2705         string path = get_user_ardour_path();
2706         path += "/favorite_dirs";
2707
2708         ifstream fav (path.c_str());
2709
2710         favs.clear();
2711         
2712         if (!fav) {
2713                 if (errno != ENOENT) {
2714                         //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2715                         return -1;
2716                 } else {
2717                         return 1;
2718                 }
2719         }
2720
2721         while (true) {
2722
2723                 string newfav;
2724
2725                 getline(fav, newfav);
2726
2727                 if (!fav.good()) {
2728                         break;
2729                 }
2730
2731                 favs.push_back (newfav);
2732         }
2733
2734         return 0;
2735 }
2736
2737 int
2738 Session::write_favorite_dirs (FavoriteDirs & favs)
2739 {
2740         string path = get_user_ardour_path();
2741         path += "/favorite_dirs";
2742
2743         ofstream fav (path.c_str());
2744
2745         if (!fav) {
2746                 return -1;
2747         }
2748
2749         for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2750                 fav << (*i) << endl;
2751         }
2752         
2753         return 0;
2754 }
2755
2756 static bool
2757 accept_all_non_peak_files (const string& path, void *arg)
2758 {
2759         return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2760 }
2761
2762 static bool
2763 accept_all_state_files (const string& path, void *arg)
2764 {
2765         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2766 }
2767
2768 int 
2769 Session::find_all_sources (string path, set<string>& result)
2770 {
2771         XMLTree tree;
2772         XMLNode* node;
2773
2774         if (!tree.read (path)) {
2775                 return -1;
2776         }
2777
2778         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2779                 return -2;
2780         }
2781
2782         XMLNodeList nlist;
2783         XMLNodeConstIterator niter;
2784
2785         nlist = node->children();
2786
2787         set_dirty();
2788
2789         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2790                 
2791                 XMLProperty* prop;
2792
2793                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2794                         continue;
2795                 }
2796
2797                 if (prop->value()[0] == '/') {
2798                         /* external file, ignore */
2799                         continue;
2800                 }
2801
2802                 string path = _path; /* /-terminated */
2803                 path += sound_dir_name;
2804                 path += '/';
2805                 path += prop->value();
2806
2807                 result.insert (path);
2808         }
2809
2810         return 0;
2811 }
2812
2813 int
2814 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2815 {
2816         PathScanner scanner;
2817         vector<string*>* state_files;
2818         string ripped;
2819         string this_snapshot_path;
2820
2821         result.clear ();
2822
2823         ripped = _path;
2824
2825         if (ripped[ripped.length()-1] == '/') {
2826                 ripped = ripped.substr (0, ripped.length() - 1);
2827         }
2828
2829         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2830         
2831         if (state_files == 0) {
2832                 /* impossible! */
2833                 return 0;
2834         }
2835
2836         this_snapshot_path = _path;
2837         this_snapshot_path += _current_snapshot_name;
2838         this_snapshot_path += _statefile_suffix;
2839
2840         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2841
2842                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2843                         continue;
2844                 }
2845
2846                 if (find_all_sources (**i, result) < 0) {
2847                         return -1;
2848                 }
2849         }
2850
2851         return 0;
2852 }
2853
2854 int
2855 Session::cleanup_sources (Session::cleanup_report& rep)
2856 {
2857         vector<Source*> dead_sources;
2858         vector<Playlist*> playlists_tbd;
2859         PathScanner scanner;
2860         string sound_path;
2861         vector<space_and_path>::iterator i;
2862         vector<space_and_path>::iterator nexti;
2863         vector<string*>* soundfiles;
2864         vector<string> unused;
2865         set<string> all_sources;
2866         bool used;
2867         string spath;
2868         int ret = -1;
2869                 
2870         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2871         
2872         /* step 1: consider deleting all unused playlists */
2873
2874         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2875                 int status;
2876
2877                 status = AskAboutPlaylistDeletion (*x);
2878
2879                 switch (status) {
2880                 case -1:
2881                         ret = 0;
2882                         goto out;
2883                         break;
2884
2885                 case 0:
2886                         playlists_tbd.push_back (*x);
2887                         break;
2888
2889                 default:
2890                         /* leave it alone */
2891                         break;
2892                 }
2893         }
2894
2895         /* now delete any that were marked for deletion */
2896
2897         for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2898                 PlaylistList::iterator foo;
2899
2900                 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2901                         unused_playlists.erase (foo);
2902                 }
2903                 delete *x;
2904         }
2905
2906         /* step 2: clear the undo/redo history for all playlists */
2907
2908         for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2909                 (*x)->drop_all_states ();
2910         }
2911
2912         /* step 3: find all un-referenced sources */
2913
2914         rep.paths.clear ();
2915         rep.space = 0;
2916
2917         for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2918
2919                 SourceList::iterator tmp;
2920
2921                 tmp = i;
2922                 ++tmp;
2923
2924                 /* only remove files that are not in use and have some size
2925                    to them. otherwise we remove the current "nascent"
2926                    capture files.
2927                 */
2928
2929                 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2930                         dead_sources.push_back (i->second);
2931
2932                         /* remove this source from our own list to avoid us
2933                            adding it to the list of all sources below
2934                         */
2935
2936                         sources.erase (i);
2937                 }
2938
2939                 i = tmp;
2940         }
2941
2942         /* Step 4: get rid of all regions in the region list that use any dead sources
2943            in case the sources themselves don't go away (they might be referenced in
2944            other snapshots).
2945         */
2946                 
2947         for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2948
2949                 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2950                         AudioRegionList::iterator tmp;
2951                         AudioRegion* ar;
2952
2953                         tmp = r;
2954                         ++tmp;
2955                         
2956                         ar = (*r).second;
2957
2958                         for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2959                                 if (&ar->source (n) == (*i)) {
2960                                         /* this region is dead */
2961                                         remove_region (ar);
2962                                 }
2963                         }
2964                         
2965                         r = tmp;
2966                 }
2967         }
2968
2969         /* build a list of all the possible sound directories for the session */
2970
2971         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2972
2973                 nexti = i;
2974                 ++nexti;
2975
2976                 sound_path += (*i).path;
2977                 sound_path += sound_dir_name;
2978
2979                 if (nexti != session_dirs.end()) {
2980                         sound_path += ':';
2981                 }
2982
2983                 i = nexti;
2984         }
2985         
2986         /* now do the same thing for the files that ended up in the sounds dir(s) 
2987            but are not referenced as sources in any snapshot.
2988         */
2989
2990         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2991
2992         if (soundfiles == 0) {
2993                 return 0;
2994         }
2995
2996         /* find all sources, but don't use this snapshot because the
2997            state file on disk still references sources we may have already
2998            dropped.
2999         */
3000
3001         find_all_sources_across_snapshots (all_sources, true);
3002
3003         /* add our current source list
3004          */
3005
3006         for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
3007                 FileSource* fs;
3008                 ExternalSource* sfs;
3009                 
3010                 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
3011                         all_sources.insert (fs->path());
3012                 } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
3013                         all_sources.insert (sfs->path());
3014                 } 
3015         }
3016
3017         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3018
3019                 used = false;
3020                 spath = **x;
3021
3022                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3023
3024                         if (spath == *i) {
3025                                 used = true;
3026                                 break;
3027                         }
3028
3029                 }
3030
3031                 if (!used) {
3032                         unused.push_back (spath);
3033                 }
3034         }
3035
3036         /* now try to move all unused files into the "dead_sounds" directory(ies) */
3037
3038         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3039                 struct stat statbuf;
3040
3041                 rep.paths.push_back (*x);
3042                 if (stat ((*x).c_str(), &statbuf) == 0) {
3043                         rep.space += statbuf.st_size;
3044                 }
3045
3046                 string newpath;
3047                 
3048                 /* don't move the file across filesystems, just
3049                    stick it in the `dead_sound_dir_name' directory
3050                    on whichever filesystem it was already on.
3051                 */
3052
3053                 newpath = PBD::dirname (*x);
3054                 newpath = PBD::dirname (newpath);
3055
3056                 newpath += '/';
3057                 newpath += dead_sound_dir_name;
3058                 newpath += '/';
3059                 newpath += PBD::basename ((*x));
3060                 
3061                 if (access (newpath.c_str(), F_OK) == 0) {
3062                         
3063                         /* the new path already exists, try versioning */
3064                         
3065                         char buf[PATH_MAX+1];
3066                         int version = 1;
3067                         string newpath_v;
3068                         
3069                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3070                         newpath_v = buf;
3071
3072                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3073                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3074                                 newpath_v = buf;
3075                         }
3076                         
3077                         if (version == 999) {
3078                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3079                                                   newpath)
3080                                       << endmsg;
3081                         } else {
3082                                 newpath = newpath_v;
3083                         }
3084                         
3085                 } else {
3086                         
3087                         /* it doesn't exist, or we can't read it or something */
3088                         
3089                 }
3090
3091                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3092                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3093                                           (*x), newpath, strerror (errno))
3094                               << endmsg;
3095                         goto out;
3096                 }
3097                 
3098
3099                 /* see if there an easy to find peakfile for this file, and remove it.
3100                  */
3101
3102                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3103                 peakpath += ".peak";
3104
3105                 if (access (peakpath.c_str(), W_OK) == 0) {
3106                         if (::unlink (peakpath.c_str()) != 0) {
3107                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3108                                                   peakpath, _path, strerror (errno))
3109                                       << endmsg;
3110                                 /* try to back out */
3111                                 rename (newpath.c_str(), _path.c_str());
3112                                 goto out;
3113                         }
3114                 }
3115
3116         }
3117
3118         ret = 0;
3119
3120         /* dump the history list */
3121
3122         history.clear ();
3123
3124         /* save state so we don't end up a session file
3125            referring to non-existent sources.
3126         */
3127         
3128         save_state ("");
3129
3130   out:
3131         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3132         return ret;
3133 }
3134
3135 int
3136 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3137 {
3138         vector<space_and_path>::iterator i;
3139         string dead_sound_dir;
3140         struct dirent* dentry;
3141         struct stat statbuf;
3142         DIR* dead;
3143
3144         rep.paths.clear ();
3145         rep.space = 0;
3146
3147         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3148                 
3149                 dead_sound_dir = (*i).path;
3150                 dead_sound_dir += dead_sound_dir_name;
3151
3152                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3153                         continue;
3154                 }
3155
3156                 while ((dentry = readdir (dead)) != 0) {
3157
3158                         /* avoid '.' and '..' */
3159                         
3160                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
3161                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3162                                 continue;
3163                         }
3164
3165                         string fullpath;
3166
3167                         fullpath = dead_sound_dir;
3168                         fullpath += '/';
3169                         fullpath += dentry->d_name;
3170
3171                         if (stat (fullpath.c_str(), &statbuf)) {
3172                                 continue;
3173                         }
3174
3175                         if (!S_ISREG (statbuf.st_mode)) {
3176                                 continue;
3177                         }
3178
3179                         if (unlink (fullpath.c_str())) {
3180                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3181                                                   fullpath, strerror (errno))
3182                                       << endmsg;
3183                         }
3184
3185                         rep.paths.push_back (dentry->d_name);
3186                         rep.space += statbuf.st_size;
3187                 }
3188
3189                 closedir (dead);
3190                 
3191         }
3192
3193         return 0;
3194 }
3195
3196 void
3197 Session::set_dirty ()
3198 {
3199         bool was_dirty = dirty();
3200         
3201         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3202
3203         if (!was_dirty) {
3204                 DirtyChanged(); /* EMIT SIGNAL */
3205         }
3206 }
3207
3208
3209 void
3210 Session::set_clean ()
3211 {
3212         bool was_dirty = dirty();
3213         
3214         _state_of_the_state = Clean;
3215
3216         if (was_dirty) {
3217                 DirtyChanged(); /* EMIT SIGNAL */
3218         }
3219 }
3220