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