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