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