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