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