a) fix problems with multichannel tape tracks
[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         _worst_output_latency = 0;
159         _worst_input_latency = 0;
160         _worst_track_latency = 0;
161         _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
162         _slave = 0;
163         _slave_type = None;
164         butler_mixdown_buffer = 0;
165         butler_gain_buffer = 0;
166         auditioner = 0;
167         mmc_control = false;
168         midi_feedback = false;
169         midi_control = true;
170         mmc = 0;
171         post_transport_work = PostTransportWork (0);
172         atomic_set (&butler_should_do_transport_work, 0);
173         atomic_set (&butler_active, 0);
174         atomic_set (&_playback_load, 100);
175         atomic_set (&_capture_load, 100);
176         atomic_set (&_playback_load_min, 100);
177         atomic_set (&_capture_load_min, 100);
178         pending_audition_region = 0;
179         _edit_mode = Slide;
180         pending_edit_mode = _edit_mode;
181         _play_range = false;
182         _control_out = 0;
183         _master_out = 0;
184         input_auto_connect = AutoConnectOption (0);
185         output_auto_connect = AutoConnectOption (0);
186         _have_captured = false;
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, "layer-model")) != 0) {
1027                 if ((prop = child->property ("val")) != 0) {
1028                         if (prop->value() == X_("LaterHigher")) {
1029                                 set_layer_model (LaterHigher);
1030                         } else if (prop->value() == X_("AddHigher")) {
1031                                 set_layer_model (AddHigher);
1032                         } else {
1033                                 set_layer_model (MoveAddHigher);
1034                         }
1035                 }
1036         }
1037
1038         if ((child = find_named_node (node, "xfade-model")) != 0) {
1039                 if ((prop = child->property ("val")) != 0) {
1040                         if (prop->value() == X_("Short")) {
1041                                 set_xfade_model (ShortCrossfade);
1042                         } else {
1043                                 set_xfade_model (FullCrossfade);
1044                         }
1045                 }
1046         }
1047
1048         if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1049                 if ((prop = child->property ("val")) != 0) {
1050                         /* value is stored as a fractional seconds */
1051                         float secs = atof (prop->value().c_str());
1052                         Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1053                 } 
1054         }
1055
1056         if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1057                 if ((prop = child->property ("val")) != 0) {
1058                         crossfades_active = (prop->value() == "yes");
1059                 }
1060         } 
1061
1062         /* TIED OPTIONS */
1063
1064         if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1065                 if ((prop = child->property ("val")) != 0) {
1066                         fade_steepness = atof (prop->value().c_str());
1067                         have_fade_steepness = true;
1068                 }
1069         }
1070         if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1071                 if ((prop = child->property ("val")) != 0) {
1072                         fade_msecs = atof (prop->value().c_str());
1073                         have_fade_msecs = true;
1074                 }
1075         }
1076
1077         if (have_fade_steepness || have_fade_msecs) {
1078                 // set_default_fade (fade_steepness, fade_msecs);
1079         }
1080
1081         return 0;
1082 }
1083
1084 XMLNode&
1085 Session::get_options () const
1086 {
1087         XMLNode* opthead;
1088         XMLNode* child;
1089         char buf[32];
1090         LocaleGuard lg (X_("POSIX"));
1091
1092         opthead = new XMLNode ("Options");
1093
1094         SlaveSource src = slave_source ();
1095         string src_string;
1096         switch (src) {
1097         case None:
1098                 src_string = "none";
1099                 break;
1100         case MTC:
1101                 src_string = "mtc";
1102                 break;
1103         case JACK:
1104                 src_string = "jack";
1105                 break;
1106         }
1107         child = opthead->add_child ("slave");
1108         child->add_property ("type", src_string);
1109         
1110         child = opthead->add_child ("send-midi-timecode");
1111         child->add_property ("val", send_midi_timecode?"yes":"no");
1112
1113         child = opthead->add_child ("send-midi-machine-control");
1114         child->add_property ("val", send_midi_machine_control?"yes":"no");
1115
1116         snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1117         child = opthead->add_child ("input-auto-connect");
1118         child->add_property ("val", buf);
1119
1120         snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1121         child = opthead->add_child ("output-auto-connect");
1122         child->add_property ("val", buf);
1123
1124         snprintf (buf, sizeof(buf)-1, "%d", max_level);
1125         child = opthead->add_child ("max-level");
1126         child->add_property ("val", buf);
1127
1128         snprintf (buf, sizeof(buf)-1, "%d", min_level);
1129         child = opthead->add_child ("min-level");
1130         child->add_property ("val", buf);
1131
1132         snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1133         child = opthead->add_child ("meter-hold");
1134         child->add_property ("val", buf);
1135
1136         snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1137         child = opthead->add_child ("meter-falloff");
1138         child->add_property ("val", buf);
1139         
1140         snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1141         child = opthead->add_child ("long-over-length");
1142         child->add_property ("val", buf);
1143
1144         snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1145         child = opthead->add_child ("short-over-length");
1146         child->add_property ("val", buf);
1147
1148         snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1149         child = opthead->add_child ("shuttle-speed-factor");
1150         child->add_property ("val", buf);
1151
1152         snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1153         child = opthead->add_child ("shuttle-speed-threshold");
1154         child->add_property ("val", buf);
1155
1156         snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1157         child = opthead->add_child ("rf-speed");
1158         child->add_property ("val", buf);
1159
1160         snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1161         child = opthead->add_child ("smpte-frames-per-second");
1162         child->add_property ("val", buf);
1163         
1164         child = opthead->add_child ("smpte-drop-frames");
1165         child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1166         
1167         snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1168         child = opthead->add_child ("smpte-offset");
1169         child->add_property ("val", buf);
1170         
1171         child = opthead->add_child ("smpte-offset-negative");
1172         child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1173         
1174         child = opthead->add_child ("edit-mode");
1175         switch (_edit_mode) {
1176         case Splice:
1177                 child->add_property ("val", "splice");
1178                 break;
1179
1180         case Slide:
1181                 child->add_property ("val", "slide");
1182                 break;
1183         }
1184
1185         child = opthead->add_child ("auto-play");
1186         child->add_property ("val", get_auto_play () ? "yes" : "no");
1187         child = opthead->add_child ("auto-input");
1188         child->add_property ("val", get_auto_input () ? "yes" : "no");
1189         child = opthead->add_child ("seamless-loop");
1190         child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1191         child = opthead->add_child ("punch-in");
1192         child->add_property ("val", get_punch_in () ? "yes" : "no");
1193         child = opthead->add_child ("punch-out");
1194         child->add_property ("val", get_punch_out () ? "yes" : "no");
1195         child = opthead->add_child ("all-safe");
1196         child->add_property ("val", get_all_safe () ? "yes" : "no");
1197         child = opthead->add_child ("auto-return");
1198         child->add_property ("val", get_auto_return () ? "yes" : "no");
1199         child = opthead->add_child ("mmc-control");
1200         child->add_property ("val", get_mmc_control () ? "yes" : "no");
1201         child = opthead->add_child ("midi-control");
1202         child->add_property ("val", get_midi_control () ? "yes" : "no");
1203         child = opthead->add_child ("midi-feedback");
1204         child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1205         child = opthead->add_child ("do-not-record-plugins");
1206         child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1207         child = opthead->add_child ("auto-crossfade");
1208         child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1209         child = opthead->add_child ("audible-click");
1210         child->add_property ("val", get_clicking () ? "yes" : "no");
1211
1212         if (click_sound.length()) {
1213                 child = opthead->add_child ("click-sound");
1214                 child->add_property ("val", click_sound);
1215         }
1216
1217         if (click_emphasis_sound.length()) {
1218                 child = opthead->add_child ("click-emphasis-sound");
1219                 child->add_property ("val", click_emphasis_sound);
1220         }
1221
1222         child = opthead->add_child ("solo-model");
1223         child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1224
1225         child = opthead->add_child ("layer-model");
1226         switch (layer_model) {
1227         case LaterHigher:
1228                 child->add_property ("val", X_("LaterHigher"));
1229                 break;
1230         case MoveAddHigher:
1231                 child->add_property ("val", X_("MoveAddHigher"));
1232                 break;
1233         case AddHigher:
1234                 child->add_property ("val", X_("AddHigher"));
1235                 break;
1236         }
1237
1238         child = opthead->add_child ("xfade-model");
1239         switch (xfade_model) {
1240         case FullCrossfade:
1241                 child->add_property ("val", X_("Full"));
1242                 break;
1243         case ShortCrossfade:
1244                 child->add_property ("val", X_("Short"));
1245         }
1246
1247         child = opthead->add_child ("short-xfade-length");
1248         /* store as fractions of a second */
1249         snprintf (buf, sizeof(buf)-1, "%f", 
1250                   (float) Crossfade::short_xfade_length() / frame_rate());
1251         child->add_property ("val", buf);
1252
1253         child = opthead->add_child ("full-xfades-unmuted");
1254         child->add_property ("val", crossfades_active ? "yes" : "no");
1255
1256         return *opthead;
1257 }
1258
1259 XMLNode&
1260 Session::get_state()
1261 {
1262         return state(true);
1263 }
1264
1265 XMLNode&
1266 Session::get_template()
1267 {
1268         /* if we don't disable rec-enable, diskstreams
1269            will believe they need to store their capture
1270            sources in their state node. 
1271         */
1272         
1273         disable_record ();
1274
1275         return state(false);
1276 }
1277
1278 XMLNode&
1279 Session::state(bool full_state)
1280 {
1281         XMLNode* node = new XMLNode("Session");
1282         XMLNode* child;
1283
1284         // store libardour version, just in case
1285         char buf[16];
1286         snprintf(buf, sizeof(buf)-1, "%d.%d.%d", 
1287                  libardour_major_version, libardour_minor_version, libardour_micro_version);
1288         node->add_property("version", string(buf));
1289                 
1290         /* store configuration settings */
1291
1292         if (full_state) {
1293         
1294                 /* store the name */
1295                 node->add_property ("name", _name);
1296
1297                 if (session_dirs.size() > 1) {
1298
1299                         string p;
1300
1301                         vector<space_and_path>::iterator i = session_dirs.begin();
1302                         vector<space_and_path>::iterator next;
1303
1304                         ++i; /* skip the first one */
1305                         next = i;
1306                         ++next;
1307
1308                         while (i != session_dirs.end()) {
1309
1310                                 p += (*i).path;
1311
1312                                 if (next != session_dirs.end()) {
1313                                         p += ':';
1314                                 } else {
1315                                         break;
1316                                 }
1317
1318                                 ++next;
1319                                 ++i;
1320                         }
1321                         
1322                         child = node->add_child ("Path");
1323                         child->add_content (p);
1324                 }
1325         }
1326
1327         node->add_child_nocopy (get_options());
1328
1329         child = node->add_child ("Sources");
1330
1331         if (full_state) {
1332                 LockMonitor sl (source_lock, __LINE__, __FILE__);
1333
1334                 for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1335                         
1336                         /* Don't save information about FileSources that are empty */
1337                         
1338                         FileSource* fs;
1339
1340                         if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
1341                                 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1342
1343                                 /* destructive file sources are OK if they are empty, because
1344                                    we will re-use them every time.
1345                                 */
1346
1347                                 if (!dfs) {
1348                                         if (fs->length() == 0) {
1349                                                 continue;
1350                                         }
1351                                 }
1352                         }
1353                         
1354                         child->add_child_nocopy ((*siter).second->get_state());
1355                 }
1356         }
1357
1358         child = node->add_child ("Regions");
1359
1360         if (full_state) { 
1361                 LockMonitor rl (region_lock, __LINE__, __FILE__);
1362
1363                 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1364                         
1365                         /* only store regions not attached to playlists */
1366
1367                         if ((*i).second->playlist() == 0) {
1368                                 child->add_child_nocopy (i->second->state (true));
1369                         }
1370                 }
1371         }
1372
1373         child = node->add_child ("DiskStreams");
1374
1375         { 
1376                 RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
1377                 for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1378                         if (!(*i)->hidden()) {
1379                                 child->add_child_nocopy ((*i)->get_state());
1380                         }
1381                 }
1382         }
1383
1384         node->add_child_nocopy (_locations.get_state());
1385         
1386         child = node->add_child ("Connections");
1387         {
1388                 LockMonitor lm (connection_lock, __LINE__, __FILE__);
1389                 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1390                         if (!(*i)->system_dependent()) {
1391                                 child->add_child_nocopy ((*i)->get_state());
1392                         }
1393                 }
1394         }
1395
1396         child = node->add_child ("Routes");
1397         {
1398                 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
1399                 
1400                 RoutePublicOrderSorter cmp;
1401                 RouteList public_order(routes);
1402                 public_order.sort (cmp);
1403                 
1404                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1405                         if (!(*i)->hidden()) {
1406                                 if (full_state) {
1407                                         child->add_child_nocopy ((*i)->get_state());
1408                                 } else {
1409                                         child->add_child_nocopy ((*i)->get_template());
1410                                 }
1411                         }
1412                 }
1413         }
1414
1415         
1416         child = node->add_child ("EditGroups");
1417         for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1418                 child->add_child_nocopy ((*i)->get_state());
1419         }
1420
1421         child = node->add_child ("MixGroups");
1422         for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1423                 child->add_child_nocopy ((*i)->get_state());
1424         }
1425
1426         child = node->add_child ("Playlists");
1427         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1428                 if (!(*i)->hidden()) {
1429                         if (!(*i)->empty()) {
1430                                 if (full_state) {
1431                                         child->add_child_nocopy ((*i)->get_state());
1432                                 } else {
1433                                         child->add_child_nocopy ((*i)->get_template());
1434                                 }
1435                         }
1436                 }
1437         }
1438
1439         child = node->add_child ("UnusedPlaylists");
1440         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1441                 if (!(*i)->hidden()) {
1442                         if (!(*i)->empty()) {
1443                                 if (full_state) {
1444                                         child->add_child_nocopy ((*i)->get_state());
1445                                 } else {
1446                                         child->add_child_nocopy ((*i)->get_template());
1447                                 }
1448                         }
1449                 }
1450         }
1451         
1452         
1453         if (_click_io) {
1454                 child = node->add_child ("Click");
1455                 child->add_child_nocopy (_click_io->state (full_state));
1456         }
1457
1458         if (full_state) {
1459                 child = node->add_child ("NamedSelections");
1460                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1461                         if (full_state) {
1462                                 child->add_child_nocopy ((*i)->get_state());
1463                         } 
1464                 }
1465         }
1466
1467         node->add_child_nocopy (_tempo_map->get_state());
1468
1469         if (_extra_xml) {
1470                 node->add_child_copy (*_extra_xml);
1471         }
1472
1473         return *node;
1474 }
1475
1476 int
1477 Session::set_state (const XMLNode& node)
1478 {
1479         XMLNodeList nlist;
1480         XMLNode* child;
1481         const XMLProperty* prop;
1482         int ret = -1;
1483
1484         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1485         
1486         if (node.name() != "Session"){
1487                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1488                 return -1;
1489         }
1490
1491         StateManager::prohibit_save ();
1492
1493         if ((prop = node.property ("name")) != 0) {
1494                 _name = prop->value ();
1495         }
1496         
1497         IO::disable_ports ();
1498         IO::disable_connecting ();
1499
1500         /* Object loading order:
1501
1502         MIDI
1503         Path
1504         extra
1505         Options
1506         Sources
1507         AudioRegions
1508         DiskStreams
1509         Connections
1510         Locations
1511         Routes
1512         EditGroups
1513         MixGroups
1514         Click
1515         */
1516
1517         if (use_config_midi_ports ()) {
1518         }
1519
1520         if ((child = find_named_node (node, "Path")) != 0) {
1521                 /* XXX this XML content stuff horrible API design */
1522                 string raid_path = _path + ':' + child->children().front()->content();
1523                 setup_raid_path (raid_path);
1524         } else {
1525                 /* the path is already set */
1526         }
1527
1528         if ((child = find_named_node (node, "extra")) != 0) {
1529                 _extra_xml = new XMLNode (*child);
1530         }
1531
1532         if ((child = find_named_node (node, "Options")) == 0) {
1533                 error << _("Session: XML state has no options section") << endmsg;
1534         } else if (load_options (*child)) {
1535         }
1536
1537         if ((child = find_named_node (node, "Sources")) == 0) {
1538                 error << _("Session: XML state has no sources section") << endmsg;
1539                 goto out;
1540         } else if (load_sources (*child)) {
1541                 goto out;
1542         }
1543
1544         if ((child = find_named_node (node, "Regions")) == 0) {
1545                 error << _("Session: XML state has no Regions section") << endmsg;
1546                 goto out;
1547         } else if (load_regions (*child)) {
1548                 goto out;
1549         }
1550
1551         if ((child = find_named_node (node, "Playlists")) == 0) {
1552                 error << _("Session: XML state has no playlists section") << endmsg;
1553                 goto out;
1554         } else if (load_playlists (*child)) {
1555                 goto out;
1556         }
1557
1558         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1559                 // this is OK
1560         } else if (load_unused_playlists (*child)) {
1561                 goto out;
1562         }
1563         
1564         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1565                 if (load_named_selections (*child)) {
1566                         goto out;
1567                 }
1568         }
1569
1570         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1571                 error << _("Session: XML state has no diskstreams section") << endmsg;
1572                 goto out;
1573         } else if (load_diskstreams (*child)) {
1574                 goto out;
1575         }
1576
1577         if ((child = find_named_node (node, "Connections")) == 0) {
1578                 error << _("Session: XML state has no connections section") << endmsg;
1579                 goto out;
1580         } else if (load_connections (*child)) {
1581                 goto out;
1582         }
1583
1584         if ((child = find_named_node (node, "Locations")) == 0) {
1585                 error << _("Session: XML state has no locations section") << endmsg;
1586                 goto out;
1587         } else if (_locations.set_state (*child)) {
1588                 goto out;
1589         }
1590
1591         Location* location;
1592
1593         if ((location = _locations.auto_loop_location()) != 0) {
1594                 set_auto_loop_location (location);
1595         }
1596
1597         if ((location = _locations.auto_punch_location()) != 0) {
1598                 set_auto_punch_location (location);
1599         }
1600
1601         if ((location = _locations.end_location()) == 0) {
1602                 _locations.add (end_location);
1603         } else {
1604                 delete end_location;
1605                 end_location = location;
1606         }
1607
1608         if ((location = _locations.start_location()) == 0) {
1609                 _locations.add (start_location);
1610         } else {
1611                 delete start_location;
1612                 start_location = location;
1613         }
1614
1615         _locations.save_state (_("initial state"));
1616
1617         if ((child = find_named_node (node, "EditGroups")) == 0) {
1618                 error << _("Session: XML state has no edit groups section") << endmsg;
1619                 goto out;
1620         } else if (load_edit_groups (*child)) {
1621                 goto out;
1622         }
1623
1624         if ((child = find_named_node (node, "MixGroups")) == 0) {
1625                 error << _("Session: XML state has no mix groups section") << endmsg;
1626                 goto out;
1627         } else if (load_mix_groups (*child)) {
1628                 goto out;
1629         }
1630
1631         if ((child = find_named_node (node, "TempoMap")) == 0) {
1632                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1633                 goto out;
1634         } else if (_tempo_map->set_state (*child)) {
1635                 goto out;
1636         }
1637
1638         if ((child = find_named_node (node, "Routes")) == 0) {
1639                 error << _("Session: XML state has no routes section") << endmsg;
1640                 goto out;
1641         } else if (load_routes (*child)) {
1642                 goto out;
1643         }
1644
1645         if ((child = find_named_node (node, "Click")) == 0) {
1646                 warning << _("Session: XML state has no click section") << endmsg;
1647         } else if (_click_io) {
1648                 _click_io->set_state (*child);
1649         }
1650         
1651         /* OK, now we can set edit mode */
1652
1653         set_edit_mode (pending_edit_mode);
1654
1655         /* here beginneth the second phase ... */
1656
1657         StateReady (); /* EMIT SIGNAL */
1658
1659         _state_of_the_state = Clean;
1660
1661         StateManager::allow_save (_("initial state"), true);
1662
1663         if (state_was_pending) {
1664                 save_state (_current_snapshot_name);
1665                 remove_pending_capture_state ();
1666                 state_was_pending = false;
1667         }
1668
1669         return 0;
1670
1671   out:
1672         /* we failed, re-enable state saving but don't actually save internal state */
1673         StateManager::allow_save (X_("ignored"), false);
1674         return ret;
1675 }
1676
1677 int
1678 Session::load_routes (const XMLNode& node)
1679 {
1680         XMLNodeList nlist;
1681         XMLNodeConstIterator niter;
1682         Route *route;
1683
1684         nlist = node.children();
1685
1686         set_dirty();
1687
1688         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1689
1690                 if ((route = XMLRouteFactory (**niter)) == 0) {
1691                         error << _("Session: cannot create Route from XML description.")                              << endmsg;
1692                         return -1;
1693                 }
1694
1695                 add_route (route);
1696         }
1697
1698         return 0;
1699 }
1700
1701 Route *
1702 Session::XMLRouteFactory (const XMLNode& node)
1703 {
1704         if (node.name() != "Route") {
1705                 return 0;
1706         }
1707
1708         if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1709                 return new AudioTrack (*this, node);
1710         } else {
1711                 return new Route (*this, node);
1712         }
1713 }
1714
1715 int
1716 Session::load_regions (const XMLNode& node)
1717 {
1718         XMLNodeList nlist;
1719         XMLNodeConstIterator niter;
1720         AudioRegion* region;
1721
1722         nlist = node.children();
1723
1724         set_dirty();
1725
1726         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1727
1728                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1729                         error << _("Session: cannot create Region from XML description.") << endmsg;
1730                 }
1731         }
1732
1733         return 0;
1734 }
1735
1736 AudioRegion *
1737 Session::XMLRegionFactory (const XMLNode& node, bool full)
1738 {
1739         const XMLProperty* prop;
1740         id_t s_id;
1741         Source* source;
1742         AudioRegion::SourceList sources;
1743         uint32_t nchans = 1;
1744         char buf[128];
1745         
1746         if (node.name() != X_("Region")) {
1747                 return 0;
1748         }
1749
1750         if ((prop = node.property (X_("channels"))) != 0) {
1751                 nchans = atoi (prop->value().c_str());
1752         }
1753
1754         
1755         if ((prop = node.property (X_("source-0"))) == 0) {
1756                 if ((prop = node.property ("source")) == 0) {
1757                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1758                         return 0;
1759                 }
1760         }
1761
1762         sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1763
1764         if ((source = get_source (s_id)) == 0) {
1765                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1766                 return 0;
1767         }
1768
1769         sources.push_back(source);
1770
1771         /* pickup other channels */
1772
1773         for (uint32_t n=1; n < nchans; ++n) {
1774                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1775                 if ((prop = node.property (buf)) != 0) {
1776                         sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
1777                         
1778                         if ((source = get_source (s_id)) == 0) {
1779                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1780                                 return 0;
1781                         }
1782                         sources.push_back(source);
1783                 }
1784         }
1785         
1786         
1787         try {
1788                 return new AudioRegion (sources, node);
1789         }
1790
1791         catch (failed_constructor& err) {
1792                 return 0;
1793         }
1794 }
1795
1796 XMLNode&
1797 Session::get_sources_as_xml ()
1798
1799 {
1800         XMLNode* node = new XMLNode (X_("Sources"));
1801         LockMonitor lm (source_lock, __LINE__, __FILE__);
1802
1803         for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
1804                 node->add_child_nocopy ((*i).second->get_state());
1805         }
1806
1807         return *node;
1808 }
1809
1810 string
1811 Session::path_from_region_name (string name, string identifier)
1812 {
1813         char buf[PATH_MAX+1];
1814         uint32_t n;
1815         string dir = discover_best_sound_dir ();
1816
1817         for (n = 0; n < 999999; ++n) {
1818                 if (identifier.length()) {
1819                         snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(), 
1820                                   identifier.c_str(), n);
1821                 } else {
1822                         snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1823                 }
1824                 if (access (buf, F_OK) != 0) {
1825                         return buf;
1826                 }
1827         }
1828
1829         return "";
1830 }
1831         
1832
1833 int
1834 Session::load_sources (const XMLNode& node)
1835 {
1836         XMLNodeList nlist;
1837         XMLNodeConstIterator niter;
1838         Source* source;
1839
1840         nlist = node.children();
1841
1842         set_dirty();
1843
1844         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1845
1846                 if ((source = XMLSourceFactory (**niter)) == 0) {
1847                         error << _("Session: cannot create Source from XML description.") << endmsg;
1848                 }
1849         }
1850
1851         return 0;
1852 }
1853
1854 Source *
1855 Session::XMLSourceFactory (const XMLNode& node)
1856 {
1857         Source *src = 0;
1858
1859         if (node.name() != "Source") {
1860                 return 0;
1861         }
1862
1863         try {
1864                 if (node.property (X_("destructive")) != 0) {
1865                         src = new DestructiveFileSource (node, frame_rate());
1866                 } else {
1867                         src = new FileSource (node, frame_rate());
1868                 }
1869         }
1870         
1871         catch (failed_constructor& err) {
1872
1873                 try {
1874                         src = ExternalSource::create (node);
1875                 }
1876
1877                 catch (failed_constructor& err) {
1878                         error << _("Found a sound file that cannot be used by Ardour. See the progammers.") << endmsg;
1879                         return 0;
1880                 } 
1881         }
1882
1883         return src;
1884 }
1885
1886 int
1887 Session::save_template (string template_name)
1888 {
1889         XMLTree tree;
1890         string xml_path, bak_path, template_path;
1891
1892         if (_state_of_the_state & CannotSave) {
1893                 return -1;
1894         }
1895
1896         DIR* dp;
1897         string dir = template_dir();
1898
1899         if ((dp = opendir (dir.c_str()))) {
1900                 closedir (dp);
1901         } else {
1902                 if (mkdir (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)<0) {
1903                         error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1904                         return -1;
1905                 }
1906         }
1907
1908         tree.set_root (&get_template());
1909
1910         xml_path = dir;
1911         xml_path += template_name;
1912         xml_path += _template_suffix;
1913
1914         ifstream in(xml_path.c_str());
1915         
1916         if (in) {
1917                 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1918                 return -1;
1919         } else {
1920                 in.close();
1921         }
1922
1923         if (!tree.write (xml_path)) {
1924                 error << _("mix template not saved") << endmsg;
1925                 return -1;
1926         }
1927
1928         return 0;
1929 }
1930
1931 int
1932 Session::rename_template (string old_name, string new_name) 
1933 {
1934         string old_path = template_dir() + old_name + _template_suffix;
1935         string new_path = template_dir() + new_name + _template_suffix;
1936
1937         return rename (old_path.c_str(), new_path.c_str());
1938 }
1939
1940 int
1941 Session::delete_template (string name) 
1942 {
1943         string template_path = template_dir();
1944         template_path += name;
1945         template_path += _template_suffix;
1946
1947         return remove (template_path.c_str());
1948 }
1949
1950 void
1951 Session::refresh_disk_space ()
1952 {
1953 #if HAVE_SYS_VFS_H
1954         struct statfs statfsbuf;
1955         vector<space_and_path>::iterator i;
1956         LockMonitor lm (space_lock, __LINE__, __FILE__);
1957         double scale;
1958
1959         /* get freespace on every FS that is part of the session path */
1960
1961         _total_free_4k_blocks = 0;
1962         
1963         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1964                 statfs ((*i).path.c_str(), &statfsbuf);
1965
1966                 scale = statfsbuf.f_bsize/4096.0;
1967
1968                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1969                 _total_free_4k_blocks += (*i).blocks;
1970         }
1971 #endif
1972 }
1973
1974 int
1975 Session::ensure_sound_dir (string path, string& result)
1976 {
1977         string dead;
1978         string peak;
1979
1980         /* Ensure that the parent directory exists */
1981         
1982         if (mkdir (path.c_str(), 0775)) {
1983                 if (errno != EEXIST) {
1984                         error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1985                         return -1;
1986                 }
1987         }
1988         
1989         /* Ensure that the sounds directory exists */
1990         
1991         result = path;
1992         result += '/';
1993         result += sound_dir_name;
1994         
1995         if (mkdir (result.c_str(), 0775)) {
1996                 if (errno != EEXIST) {
1997                         error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1998                         return -1;
1999                 }
2000         }
2001
2002         dead = path;
2003         dead += '/';
2004         dead += dead_sound_dir_name;
2005         
2006         if (mkdir (dead.c_str(), 0775)) {
2007                 if (errno != EEXIST) {
2008                         error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
2009                         return -1;
2010                 }
2011         }
2012
2013         peak = path;
2014         peak += '/';
2015         peak += peak_dir_name;
2016         
2017         if (mkdir (peak.c_str(), 0775)) {
2018                 if (errno != EEXIST) {
2019                         error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
2020                         return -1;
2021                 }
2022         }
2023         
2024         /* callers expect this to be terminated ... */
2025                         
2026         result += '/';
2027         return 0;
2028 }       
2029
2030 string
2031 Session::discover_best_sound_dir (bool destructive)
2032 {
2033         vector<space_and_path>::iterator i;
2034         string result;
2035
2036         /* destructive files all go into the same place */
2037
2038         if (destructive) {
2039                 return tape_dir();
2040         }
2041
2042         /* handle common case without system calls */
2043
2044         if (session_dirs.size() == 1) {
2045                 return sound_dir();
2046         }
2047
2048         /* OK, here's the algorithm we're following here:
2049            
2050         We want to select which directory to use for 
2051         the next file source to be created. Ideally,
2052         we'd like to use a round-robin process so as to
2053         get maximum performance benefits from splitting
2054         the files across multiple disks.
2055
2056         However, in situations without much diskspace, an
2057         RR approach may end up filling up a filesystem
2058         with new files while others still have space.
2059         Its therefore important to pay some attention to
2060         the freespace in the filesystem holding each
2061         directory as well. However, if we did that by
2062         itself, we'd keep creating new files in the file
2063         system with the most space until it was as full
2064         as all others, thus negating any performance
2065         benefits of this RAID-1 like approach.
2066
2067         So, we use a user-configurable space threshold. If
2068         there are at least 2 filesystems with more than this
2069         much space available, we use RR selection between them. 
2070         If not, then we pick the filesystem with the most space.
2071
2072         This gets a good balance between the two
2073         approaches.  
2074         */
2075         
2076         refresh_disk_space ();
2077         
2078         int free_enough = 0;
2079
2080         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2081                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2082                         free_enough++;
2083                 }
2084         }
2085
2086         if (free_enough >= 2) {
2087
2088                 bool found_it = false;
2089
2090                 /* use RR selection process, ensuring that the one
2091                    picked works OK.
2092                 */
2093
2094                 i = last_rr_session_dir;
2095
2096                 do {
2097                         if (++i == session_dirs.end()) {
2098                                 i = session_dirs.begin();
2099                         }
2100
2101                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2102                                 if (ensure_sound_dir ((*i).path, result) == 0) {
2103                                         last_rr_session_dir = i;
2104                                         found_it = true;
2105                                         break;
2106                                 }
2107                         }
2108
2109                 } while (i != last_rr_session_dir);
2110
2111                 if (!found_it) {
2112                         result = sound_dir();
2113                 }
2114
2115         } else {
2116
2117                 /* pick FS with the most freespace (and that
2118                    seems to actually work ...)
2119                 */
2120                 
2121                 vector<space_and_path> sorted;
2122                 space_and_path_ascending_cmp cmp;
2123
2124                 sorted = session_dirs;
2125                 sort (sorted.begin(), sorted.end(), cmp);
2126                 
2127                 for (i = sorted.begin(); i != sorted.end(); ++i) {
2128                         if (ensure_sound_dir ((*i).path, result) == 0) {
2129                                 last_rr_session_dir = i;
2130                                 break;
2131                         }
2132                 }
2133                 
2134                 /* if the above fails, fall back to the most simplistic solution */
2135                 
2136                 if (i == sorted.end()) {
2137                         return sound_dir();
2138                 } 
2139         }
2140
2141         return result;
2142 }
2143
2144 int
2145 Session::load_playlists (const XMLNode& node)
2146 {
2147         XMLNodeList nlist;
2148         XMLNodeConstIterator niter;
2149         Playlist *playlist;
2150
2151         nlist = node.children();
2152
2153         set_dirty();
2154
2155         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2156                 
2157                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2158                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
2159                 }
2160         }
2161
2162         return 0;
2163 }
2164
2165 int
2166 Session::load_unused_playlists (const XMLNode& node)
2167 {
2168         XMLNodeList nlist;
2169         XMLNodeConstIterator niter;
2170         Playlist *playlist;
2171
2172         nlist = node.children();
2173
2174         set_dirty();
2175
2176         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2177                 
2178                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2179                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
2180                         continue;
2181                 }
2182
2183                 // now manually untrack it
2184
2185                 track_playlist (playlist, false);
2186         }
2187
2188         return 0;
2189 }
2190
2191
2192 Playlist *
2193 Session::XMLPlaylistFactory (const XMLNode& node)
2194 {
2195         try {
2196                 return new AudioPlaylist (*this, node);
2197         }
2198
2199         catch (failed_constructor& err) {
2200                 return 0;
2201         }
2202 }
2203
2204 int
2205 Session::load_named_selections (const XMLNode& node)
2206 {
2207         XMLNodeList nlist;
2208         XMLNodeConstIterator niter;
2209         NamedSelection *ns;
2210
2211         nlist = node.children();
2212
2213         set_dirty();
2214
2215         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2216                 
2217                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2218                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2219                 }
2220         }
2221
2222         return 0;
2223 }
2224
2225 NamedSelection *
2226 Session::XMLNamedSelectionFactory (const XMLNode& node)
2227 {
2228         try {
2229                 return new NamedSelection (*this, node);
2230         }
2231
2232         catch (failed_constructor& err) {
2233                 return 0;
2234         }
2235 }
2236
2237 string
2238 Session::dead_sound_dir () const
2239 {
2240         string res = _path;
2241         res += dead_sound_dir_name;
2242         res += '/';
2243         return res;
2244 }
2245
2246 string
2247 Session::sound_dir () const
2248 {
2249         string res = _path;
2250         res += sound_dir_name;
2251         res += '/';
2252         return res;
2253 }
2254
2255 string
2256 Session::tape_dir () const
2257 {
2258         string res = _path;
2259         res += tape_dir_name;
2260         res += '/';
2261         return res;
2262 }
2263
2264 string
2265 Session::peak_dir () const
2266 {
2267         string res = _path;
2268         res += peak_dir_name;
2269         res += '/';
2270         return res;
2271 }
2272         
2273 string
2274 Session::automation_dir () const
2275 {
2276         string res = _path;
2277         res += "automation/";
2278         return res;
2279 }
2280
2281 string
2282 Session::template_dir ()
2283 {
2284         string path = get_user_ardour_path();
2285         path += "templates/";
2286
2287         return path;
2288 }
2289
2290 string
2291 Session::template_path ()
2292 {
2293         string path;
2294
2295         path += get_user_ardour_path();
2296         if (path[path.length()-1] != ':') {
2297                 path += ':';
2298         }
2299         path += get_system_ardour_path();
2300
2301         vector<string> split_path;
2302         
2303         split (path, split_path, ':');
2304         path = "";
2305
2306         for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2307                 path += *i;
2308                 path += "templates/";
2309                 
2310                 if (distance (i, split_path.end()) != 1) {
2311                         path += ':';
2312                 }
2313         }
2314                 
2315         return path;
2316 }
2317
2318 int
2319 Session::load_connections (const XMLNode& node)
2320 {
2321         XMLNodeList nlist = node.children();
2322         XMLNodeConstIterator niter;
2323
2324         set_dirty();
2325
2326         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2327                 if ((*niter)->name() == "InputConnection") {
2328                         add_connection (new ARDOUR::InputConnection (**niter));
2329                 } else if ((*niter)->name() == "OutputConnection") {
2330                         add_connection (new ARDOUR::OutputConnection (**niter));
2331                 } else {
2332                         error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2333                         return -1;
2334                 }
2335         }
2336
2337         return 0;
2338 }                               
2339
2340 int
2341 Session::load_edit_groups (const XMLNode& node)
2342 {
2343         return load_route_groups (node, true);
2344 }
2345
2346 int
2347 Session::load_mix_groups (const XMLNode& node)
2348 {
2349         return load_route_groups (node, false);
2350 }
2351
2352 int
2353 Session::load_route_groups (const XMLNode& node, bool edit)
2354 {
2355         XMLNodeList nlist = node.children();
2356         XMLNodeConstIterator niter;
2357         RouteGroup* route;
2358
2359         set_dirty();
2360
2361         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2362                 if ((*niter)->name() == "RouteGroup") {
2363                         if (edit) {
2364                                 route = add_edit_group ("");
2365                                 route->set_state (**niter);
2366                         } else {
2367                                 route = add_mix_group ("");
2368                                 route->set_state (**niter);
2369                         }
2370                 }
2371         }
2372         
2373         return 0;
2374 }                               
2375
2376 void
2377 Session::swap_configuration(Configuration** new_config)
2378 {
2379         RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
2380         Configuration* tmp = *new_config;
2381         *new_config = Config;
2382         Config = tmp;
2383         set_dirty();
2384 }
2385
2386 void
2387 Session::copy_configuration(Configuration* new_config)
2388 {
2389         RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
2390         new_config = new Configuration(*Config);
2391 }
2392
2393 static bool
2394 state_file_filter (const string &str, void *arg)
2395 {
2396         return (str.length() > strlen(Session::statefile_suffix()) &&
2397                 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2398 }
2399
2400 struct string_cmp {
2401         bool operator()(const string* a, const string* b) {
2402                 return *a < *b;
2403         }
2404 };
2405
2406 static string*
2407 remove_end(string* state)
2408 {
2409         string statename(*state);
2410         
2411         string::size_type start,end;
2412         if ((start = statename.find_last_of ('/')) != string::npos) {
2413                 statename = statename.substr (start+1);
2414         }
2415                 
2416         if ((end = statename.rfind(".ardour")) < 0) {
2417                 end = statename.length();
2418         }
2419
2420         return new string(statename.substr (0, end));
2421 }
2422
2423 vector<string *> *
2424 Session::possible_states (string path) 
2425 {
2426         PathScanner scanner;
2427         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2428         
2429         transform(states->begin(), states->end(), states->begin(), remove_end);
2430         
2431         string_cmp cmp;
2432         sort (states->begin(), states->end(), cmp);
2433         
2434         return states;
2435 }
2436
2437 vector<string *> *
2438 Session::possible_states () const
2439 {
2440         return possible_states(_path);
2441 }
2442
2443 void
2444 Session::auto_save()
2445 {
2446         save_state (_current_snapshot_name);
2447 }
2448
2449 RouteGroup *
2450 Session::add_edit_group (string name)
2451 {
2452         RouteGroup* rg = new RouteGroup (*this, name);
2453         edit_groups.push_back (rg);
2454         edit_group_added (rg); /* EMIT SIGNAL */
2455         set_dirty();
2456         return rg;
2457 }
2458
2459 RouteGroup *
2460 Session::add_mix_group (string name)
2461 {
2462         RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2463         mix_groups.push_back (rg);
2464         mix_group_added (rg); /* EMIT SIGNAL */
2465         set_dirty();
2466         return rg;
2467 }
2468
2469 void
2470 Session::remove_edit_group (RouteGroup& rg)
2471 {
2472         list<RouteGroup*>::iterator i;
2473
2474         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2475                 (*i)->apply (&Route::drop_edit_group, this);
2476                 edit_groups.erase (i);
2477                 edit_group_removed (); /* EMIT SIGNAL */
2478         }
2479
2480         delete &rg;
2481 }
2482
2483 void
2484 Session::remove_mix_group (RouteGroup& rg)
2485 {
2486         list<RouteGroup*>::iterator i;
2487
2488         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2489                 (*i)->apply (&Route::drop_mix_group, this);
2490                 mix_groups.erase (i);
2491                 mix_group_removed (); /* EMIT SIGNAL */
2492         }
2493
2494         delete &rg;
2495 }
2496
2497 RouteGroup *
2498 Session::mix_group_by_name (string name)
2499 {
2500         list<RouteGroup *>::iterator i;
2501
2502         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2503                 if ((*i)->name() == name) {
2504                         return* i;
2505                 }
2506         }
2507         return 0;
2508 }
2509
2510 RouteGroup *
2511 Session::edit_group_by_name (string name)
2512 {
2513         list<RouteGroup *>::iterator i;
2514
2515         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2516                 if ((*i)->name() == name) {
2517                         return* i;
2518                 }
2519         }
2520         return 0;
2521 }
2522
2523 void
2524 Session::set_meter_hold (float val)
2525 {
2526         _meter_hold = val;
2527         MeterHoldChanged(); // emit
2528 }
2529
2530 void
2531 Session::set_meter_falloff (float val)
2532 {
2533         _meter_falloff = val;
2534         MeterFalloffChanged(); // emit
2535 }
2536
2537
2538 void
2539 Session::begin_reversible_command (string name, UndoAction* private_undo)
2540 {
2541         current_cmd.clear ();
2542         current_cmd.set_name (name);
2543
2544         if (private_undo) {
2545                 current_cmd.add_undo (*private_undo);
2546         }
2547 }
2548
2549 void
2550 Session::commit_reversible_command (UndoAction* private_redo)
2551 {
2552         struct timeval now;
2553
2554         if (private_redo) {
2555                 current_cmd.add_redo_no_execute (*private_redo);
2556         }
2557
2558         gettimeofday (&now, 0);
2559         current_cmd.set_timestamp (now);
2560
2561         history.add (current_cmd);
2562 }
2563
2564 Session::GlobalRouteBooleanState 
2565 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2566 {
2567         GlobalRouteBooleanState s;
2568         RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2569
2570         for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2571                 if (!(*i)->hidden()) {
2572                         RouteBooleanState v;
2573                         
2574                         v.first =* i;
2575                         v.second = ((*i)->*method)();
2576                         
2577                         s.push_back (v);
2578                 }
2579         }
2580
2581         return s;
2582 }
2583
2584 Session::GlobalRouteMeterState
2585 Session::get_global_route_metering ()
2586 {
2587         GlobalRouteMeterState s;
2588         RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
2589
2590         for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2591                 if (!(*i)->hidden()) {
2592                         RouteMeterState v;
2593                         
2594                         v.first =* i;
2595                         v.second = (*i)->meter_point();
2596                         
2597                         s.push_back (v);
2598                 }
2599         }
2600
2601         return s;
2602 }
2603
2604 void
2605 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2606 {
2607         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2608                 i->first->set_meter_point (i->second, arg);
2609         }
2610 }
2611
2612 void
2613 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2614 {
2615         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2616                 (i->first->*method) (i->second, arg);
2617         }
2618 }
2619
2620 void
2621 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2622 {
2623         set_global_route_boolean (s, &Route::set_mute, src);
2624 }
2625
2626 void
2627 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2628 {
2629         set_global_route_boolean (s, &Route::set_solo, src);
2630 }
2631
2632 void
2633 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2634 {
2635         set_global_route_boolean (s, &Route::set_record_enable, src);
2636 }
2637
2638 UndoAction
2639 Session::global_mute_memento (void* src)
2640 {
2641         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2642 }
2643
2644 UndoAction
2645 Session::global_metering_memento (void* src)
2646 {
2647         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2648 }
2649
2650 UndoAction
2651 Session::global_solo_memento (void* src)
2652 {
2653         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2654 }
2655
2656 UndoAction
2657 Session::global_record_enable_memento (void* src)
2658 {
2659         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2660 }
2661
2662 static bool
2663 template_filter (const string &str, void *arg)
2664 {
2665         return (str.length() > strlen(Session::template_suffix()) &&
2666                 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2667 }
2668
2669 void
2670 Session::get_template_list (list<string> &template_names)
2671 {
2672         vector<string *> *templates;
2673         PathScanner scanner;
2674         string path;
2675
2676         path = template_path ();
2677
2678         templates = scanner (path, template_filter, 0, false, true);
2679         
2680         vector<string*>::iterator i;
2681         for (i = templates->begin(); i != templates->end(); ++i) {
2682                 string fullpath = *(*i);
2683                 int start, end;
2684
2685                 start = fullpath.find_last_of ('/') + 1;
2686                 if ((end = fullpath.find_last_of ('.')) <0) {
2687                         end = fullpath.length();
2688                 }
2689                 
2690                 template_names.push_back(fullpath.substr(start, (end-start)));
2691         }
2692 }
2693
2694 int
2695 Session::read_favorite_dirs (FavoriteDirs & favs)
2696 {
2697         string path = get_user_ardour_path();
2698         path += "/favorite_dirs";
2699
2700         ifstream fav (path.c_str());
2701
2702         favs.clear();
2703         
2704         if (!fav) {
2705                 if (errno != ENOENT) {
2706                         //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2707                         return -1;
2708                 } else {
2709                         return 1;
2710                 }
2711         }
2712
2713         while (true) {
2714
2715                 string newfav;
2716
2717                 getline(fav, newfav);
2718
2719                 if (!fav.good()) {
2720                         break;
2721                 }
2722
2723                 favs.push_back (newfav);
2724         }
2725
2726         return 0;
2727 }
2728
2729 int
2730 Session::write_favorite_dirs (FavoriteDirs & favs)
2731 {
2732         string path = get_user_ardour_path();
2733         path += "/favorite_dirs";
2734
2735         ofstream fav (path.c_str());
2736
2737         if (!fav) {
2738                 return -1;
2739         }
2740
2741         for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2742                 fav << (*i) << endl;
2743         }
2744         
2745         return 0;
2746 }
2747
2748 static bool
2749 accept_all_non_peak_files (const string& path, void *arg)
2750 {
2751         return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2752 }
2753
2754 static bool
2755 accept_all_state_files (const string& path, void *arg)
2756 {
2757         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2758 }
2759
2760 int 
2761 Session::find_all_sources (string path, set<string>& result)
2762 {
2763         XMLTree tree;
2764         XMLNode* node;
2765
2766         if (!tree.read (path)) {
2767                 return -1;
2768         }
2769
2770         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2771                 return -2;
2772         }
2773
2774         XMLNodeList nlist;
2775         XMLNodeConstIterator niter;
2776
2777         nlist = node->children();
2778
2779         set_dirty();
2780
2781         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2782                 
2783                 XMLProperty* prop;
2784
2785                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2786                         continue;
2787                 }
2788
2789                 if (prop->value()[0] == '/') {
2790                         /* external file, ignore */
2791                         continue;
2792                 }
2793
2794                 string path = _path; /* /-terminated */
2795                 path += sound_dir_name;
2796                 path += '/';
2797                 path += prop->value();
2798
2799                 result.insert (path);
2800         }
2801
2802         return 0;
2803 }
2804
2805 int
2806 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2807 {
2808         PathScanner scanner;
2809         vector<string*>* state_files;
2810         string ripped;
2811         string this_snapshot_path;
2812
2813         result.clear ();
2814
2815         ripped = _path;
2816
2817         if (ripped[ripped.length()-1] == '/') {
2818                 ripped = ripped.substr (0, ripped.length() - 1);
2819         }
2820
2821         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2822         
2823         if (state_files == 0) {
2824                 /* impossible! */
2825                 return 0;
2826         }
2827
2828         this_snapshot_path = _path;
2829         this_snapshot_path += _current_snapshot_name;
2830         this_snapshot_path += _statefile_suffix;
2831
2832         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2833
2834                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2835                         continue;
2836                 }
2837
2838                 if (find_all_sources (**i, result) < 0) {
2839                         return -1;
2840                 }
2841         }
2842
2843         return 0;
2844 }
2845
2846 int
2847 Session::cleanup_sources (Session::cleanup_report& rep)
2848 {
2849         vector<Source*> dead_sources;
2850         vector<Playlist*> playlists_tbd;
2851         PathScanner scanner;
2852         string sound_path;
2853         vector<space_and_path>::iterator i;
2854         vector<space_and_path>::iterator nexti;
2855         vector<string*>* soundfiles;
2856         vector<string> unused;
2857         set<string> all_sources;
2858         bool used;
2859         string spath;
2860         int ret = -1;
2861                 
2862         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2863         
2864         /* step 1: consider deleting all unused playlists */
2865
2866         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2867                 int status;
2868
2869                 status = AskAboutPlaylistDeletion (*x);
2870
2871                 switch (status) {
2872                 case -1:
2873                         ret = 0;
2874                         goto out;
2875                         break;
2876
2877                 case 0:
2878                         playlists_tbd.push_back (*x);
2879                         break;
2880
2881                 default:
2882                         /* leave it alone */
2883                         break;
2884                 }
2885         }
2886
2887         /* now delete any that were marked for deletion */
2888
2889         for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2890                 PlaylistList::iterator foo;
2891
2892                 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2893                         unused_playlists.erase (foo);
2894                 }
2895                 delete *x;
2896         }
2897
2898         /* step 2: clear the undo/redo history for all playlists */
2899
2900         for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2901                 (*x)->drop_all_states ();
2902         }
2903
2904         /* step 3: find all un-referenced sources */
2905
2906         rep.paths.clear ();
2907         rep.space = 0;
2908
2909         for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
2910
2911                 SourceList::iterator tmp;
2912
2913                 tmp = i;
2914                 ++tmp;
2915
2916                 /* only remove files that are not in use and have some size
2917                    to them. otherwise we remove the current "nascent"
2918                    capture files.
2919                 */
2920
2921                 if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
2922                         dead_sources.push_back (i->second);
2923
2924                         /* remove this source from our own list to avoid us
2925                            adding it to the list of all sources below
2926                         */
2927
2928                         sources.erase (i);
2929                 }
2930
2931                 i = tmp;
2932         }
2933
2934         /* Step 4: get rid of all regions in the region list that use any dead sources
2935            in case the sources themselves don't go away (they might be referenced in
2936            other snapshots).
2937         */
2938                 
2939         for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2940
2941                 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2942                         AudioRegionList::iterator tmp;
2943                         AudioRegion* ar;
2944
2945                         tmp = r;
2946                         ++tmp;
2947                         
2948                         ar = (*r).second;
2949
2950                         for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2951                                 if (&ar->source (n) == (*i)) {
2952                                         /* this region is dead */
2953                                         remove_region (ar);
2954                                 }
2955                         }
2956                         
2957                         r = tmp;
2958                 }
2959         }
2960
2961         /* build a list of all the possible sound directories for the session */
2962
2963         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2964
2965                 nexti = i;
2966                 ++nexti;
2967
2968                 sound_path += (*i).path;
2969                 sound_path += sound_dir_name;
2970
2971                 if (nexti != session_dirs.end()) {
2972                         sound_path += ':';
2973                 }
2974
2975                 i = nexti;
2976         }
2977         
2978         /* now do the same thing for the files that ended up in the sounds dir(s) 
2979            but are not referenced as sources in any snapshot.
2980         */
2981
2982         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2983
2984         if (soundfiles == 0) {
2985                 return 0;
2986         }
2987
2988         /* find all sources, but don't use this snapshot because the
2989            state file on disk still references sources we may have already
2990            dropped.
2991         */
2992
2993         find_all_sources_across_snapshots (all_sources, true);
2994
2995         /* add our current source list
2996          */
2997
2998         for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
2999                 FileSource* fs;
3000                 ExternalSource* sfs;
3001                 
3002                 if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
3003                         all_sources.insert (fs->path());
3004                 } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
3005                         all_sources.insert (sfs->path());
3006                 } 
3007         }
3008
3009         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3010
3011                 used = false;
3012                 spath = **x;
3013
3014                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3015
3016                         if (spath == *i) {
3017                                 used = true;
3018                                 break;
3019                         }
3020
3021                 }
3022
3023                 if (!used) {
3024                         unused.push_back (spath);
3025                 }
3026         }
3027
3028         /* now try to move all unused files into the "dead_sounds" directory(ies) */
3029
3030         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3031                 struct stat statbuf;
3032
3033                 rep.paths.push_back (*x);
3034                 if (stat ((*x).c_str(), &statbuf) == 0) {
3035                         rep.space += statbuf.st_size;
3036                 }
3037
3038                 string newpath;
3039                 
3040                 /* don't move the file across filesystems, just
3041                    stick it in the `dead_sound_dir_name' directory
3042                    on whichever filesystem it was already on.
3043                 */
3044
3045                 newpath = PBD::dirname (*x);
3046                 newpath = PBD::dirname (newpath);
3047
3048                 newpath += '/';
3049                 newpath += dead_sound_dir_name;
3050                 newpath += '/';
3051                 newpath += PBD::basename ((*x));
3052                 
3053                 if (access (newpath.c_str(), F_OK) == 0) {
3054                         
3055                         /* the new path already exists, try versioning */
3056                         
3057                         char buf[PATH_MAX+1];
3058                         int version = 1;
3059                         string newpath_v;
3060                         
3061                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3062                         newpath_v = buf;
3063
3064                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3065                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3066                                 newpath_v = buf;
3067                         }
3068                         
3069                         if (version == 999) {
3070                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3071                                                   newpath)
3072                                       << endmsg;
3073                         } else {
3074                                 newpath = newpath_v;
3075                         }
3076                         
3077                 } else {
3078                         
3079                         /* it doesn't exist, or we can't read it or something */
3080                         
3081                 }
3082
3083                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3084                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3085                                           (*x), newpath, strerror (errno))
3086                               << endmsg;
3087                         goto out;
3088                 }
3089                 
3090
3091                 /* see if there an easy to find peakfile for this file, and remove it.
3092                  */
3093
3094                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3095                 peakpath += ".peak";
3096
3097                 if (access (peakpath.c_str(), W_OK) == 0) {
3098                         if (::unlink (peakpath.c_str()) != 0) {
3099                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3100                                                   peakpath, _path, strerror (errno))
3101                                       << endmsg;
3102                                 /* try to back out */
3103                                 rename (newpath.c_str(), _path.c_str());
3104                                 goto out;
3105                         }
3106                 }
3107
3108         }
3109
3110         ret = 0;
3111
3112         /* dump the history list */
3113
3114         history.clear ();
3115
3116         /* save state so we don't end up a session file
3117            referring to non-existent sources.
3118         */
3119         
3120         save_state ("");
3121
3122   out:
3123         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
3124         return ret;
3125 }
3126
3127 int
3128 Session::cleanup_trash_sources (Session::cleanup_report& rep)
3129 {
3130         vector<space_and_path>::iterator i;
3131         string dead_sound_dir;
3132         struct dirent* dentry;
3133         struct stat statbuf;
3134         DIR* dead;
3135
3136         rep.paths.clear ();
3137         rep.space = 0;
3138
3139         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3140                 
3141                 dead_sound_dir = (*i).path;
3142                 dead_sound_dir += dead_sound_dir_name;
3143
3144                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
3145                         continue;
3146                 }
3147
3148                 while ((dentry = readdir (dead)) != 0) {
3149
3150                         /* avoid '.' and '..' */
3151                         
3152                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
3153                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3154                                 continue;
3155                         }
3156
3157                         string fullpath;
3158
3159                         fullpath = dead_sound_dir;
3160                         fullpath += '/';
3161                         fullpath += dentry->d_name;
3162
3163                         if (stat (fullpath.c_str(), &statbuf)) {
3164                                 continue;
3165                         }
3166
3167                         if (!S_ISREG (statbuf.st_mode)) {
3168                                 continue;
3169                         }
3170
3171                         if (unlink (fullpath.c_str())) {
3172                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3173                                                   fullpath, strerror (errno))
3174                                       << endmsg;
3175                         }
3176
3177                         rep.paths.push_back (dentry->d_name);
3178                         rep.space += statbuf.st_size;
3179                 }
3180
3181                 closedir (dead);
3182                 
3183         }
3184
3185         return 0;
3186 }
3187
3188 void
3189 Session::set_dirty ()
3190 {
3191         bool was_dirty = dirty();
3192         
3193         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3194
3195         if (!was_dirty) {
3196                 DirtyChanged(); /* EMIT SIGNAL */
3197         }
3198 }
3199
3200
3201 void
3202 Session::set_clean ()
3203 {
3204         bool was_dirty = dirty();
3205         
3206         _state_of_the_state = Clean;
3207
3208         if (was_dirty) {
3209                 DirtyChanged(); /* EMIT SIGNAL */
3210         }
3211 }
3212