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