Merged with trunk R795
[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         AudioDiskstream::allocate_working_buffers();
198
199         /* default short fade = 15ms */
200
201         Crossfade::set_short_xfade_length ((jack_nframes_t) floor ((15.0 * frame_rate()) / 1000.0));
202         DestructiveFileSource::setup_standard_crossfades (frame_rate());
203
204         last_mmc_step.tv_sec = 0;
205         last_mmc_step.tv_usec = 0;
206         step_speed = 0.0;
207
208         preroll.type = AnyTime::Frames;
209         preroll.frames = 0;
210         postroll.type = AnyTime::Frames;
211         postroll.frames = 0;
212
213         /* click sounds are unset by default, which causes us to internal
214            waveforms for clicks.
215         */
216         
217         _clicking = false;
218         click_requested = false;
219         click_data = 0;
220         click_emphasis_data = 0;
221         click_length = 0;
222         click_emphasis_length = 0;
223
224         process_function = &Session::process_with_events;
225
226         last_smpte_when = 0;
227         _smpte_offset = 0;
228         _smpte_offset_negative = true;
229         last_smpte_valid = false;
230
231         last_rr_session_dir = session_dirs.begin();
232         refresh_disk_space ();
233
234         // set_default_fade (0.2, 5.0); /* steepness, millisecs */
235
236         /* default configuration */
237
238         do_not_record_plugins = false;
239         over_length_short = 2;
240         over_length_long = 10;
241         send_midi_timecode = false;
242         send_midi_machine_control = false;
243         shuttle_speed_factor = 1.0;
244         shuttle_speed_threshold = 5;
245         rf_speed = 2.0;
246         _meter_hold = 100; // XXX unknown units: number of calls to meter::set()
247         _meter_falloff = 1.5f; // XXX unknown units: refresh_rate
248         max_level = 0;
249         min_level = 0;
250
251         /* slave stuff */
252
253         average_slave_delta = 1800;
254         have_first_delta_accumulator = false;
255         delta_accumulator_cnt = 0;
256         slave_state = Stopped;
257
258         /* default SMPTE type is 30 FPS, non-drop */
259
260         set_smpte_type (30.0, false);
261
262         _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
263
264         /* These are all static "per-class" signals */
265
266         Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
267         AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
268         Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
269         Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
270         Diskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
271         NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
272
273         Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
274         Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
275
276         IO::MoreChannels.connect (mem_fun (*this, &Session::ensure_buffers));
277
278         /* stop IO objects from doing stuff until we're ready for them */
279
280         IO::disable_panners ();
281         IO::disable_ports ();
282         IO::disable_connecting ();
283 }
284
285 int
286 Session::second_stage_init (bool new_session)
287 {
288         AudioFileSource::set_peak_dir (peak_dir());
289
290         if (!new_session) {
291                 if (load_state (_current_snapshot_name)) {
292                         return -1;
293                 }
294                 remove_empty_sounds ();
295         }
296
297         if (start_butler_thread()) {
298                 return -1;
299         }
300
301         /*if (start_midi_thread ()) {
302                 return -1;
303         }*/
304
305         if (state_tree) {
306                 if (set_state (*state_tree->root())) {
307                         return -1;
308                 }
309         }
310
311         /* we can't save till after ::when_engine_running() is called,
312            because otherwise we save state with no connections made.
313            therefore, we reset _state_of_the_state because ::set_state()
314            will have cleared it.
315
316            we also have to include Loading so that any events that get
317            generated between here and the end of ::when_engine_running()
318            will be processed directly rather than queued.
319         */
320
321         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
322
323         // set_auto_input (true);
324         _locations.changed.connect (mem_fun (this, &Session::locations_changed));
325         _locations.added.connect (mem_fun (this, &Session::locations_added));
326         setup_click_sounds (0);
327         setup_midi_control ();
328
329         /* Pay attention ... */
330
331         _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
332         _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
333
334         if (_engine.running()) {
335                 when_engine_running();
336         } else {
337                 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
338         }
339
340         //send_full_time_code ();
341         _engine.transport_locate (0);
342         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
343         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
344
345         ControlProtocolManager::instance().set_session (*this);
346
347         if (new_session) {
348                 _end_location_is_free = true;
349         } else {
350                 _end_location_is_free = false;
351         }
352         
353         return 0;
354 }
355
356 string
357 Session::raid_path () const
358 {
359         string path;
360
361         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
362                 path += (*i).path;
363                 path += ':';
364         }
365         
366         return path.substr (0, path.length() - 1); // drop final colon
367 }
368
369 void
370 Session::set_raid_path (string path)
371 {
372         /* public-access to setup_raid_path() */
373
374         setup_raid_path (path);
375 }
376
377 void
378 Session::setup_raid_path (string path)
379 {
380         string::size_type colon;
381         string remaining;
382         space_and_path sp;
383         string fspath;
384         string::size_type len = path.length();
385         int colons;
386
387         colons = 0;
388
389         if (path.length() == 0) {
390                 return;
391         }
392
393         session_dirs.clear ();
394
395         for (string::size_type n = 0; n < len; ++n) {
396                 if (path[n] == ':') {
397                         colons++;
398                 }
399         }
400
401         if (colons == 0) {
402
403                 /* no multiple search path, just one location (common case) */
404
405                 sp.path = path;
406                 sp.blocks = 0;
407                 session_dirs.push_back (sp);
408
409                 string fspath;
410
411                 /* sounds dir */
412
413                 fspath += sp.path;
414                 if (fspath[fspath.length()-1] != '/') {
415                         fspath += '/';
416                 }
417                 fspath += sound_dir_name;
418                 fspath += ':';
419
420                 /* tape dir */
421
422                 fspath += sp.path;
423                 if (fspath[fspath.length()-1] != '/') {
424                         fspath += '/';
425                 }
426                 fspath += tape_dir_name;
427                 
428                 AudioFileSource::set_search_path (fspath);
429
430                 return;
431         }
432
433         remaining = path;
434
435         while ((colon = remaining.find_first_of (':')) != string::npos) {
436                 
437                 sp.blocks = 0;
438                 sp.path = remaining.substr (0, colon);
439                 session_dirs.push_back (sp);
440
441                 /* add sounds to file search path */
442
443                 fspath += sp.path;
444                 if (fspath[fspath.length()-1] != '/') {
445                         fspath += '/';
446                 }
447                 fspath += sound_dir_name;
448                 fspath += ':';
449
450                 /* add tape dir to file search path */
451
452                 fspath += sp.path;
453                 if (fspath[fspath.length()-1] != '/') {
454                         fspath += '/';
455                 }
456                 fspath += tape_dir_name;
457                 fspath += ':';
458
459                 remaining = remaining.substr (colon+1);
460         }
461
462         if (remaining.length()) {
463
464                 sp.blocks = 0;
465                 sp.path = remaining;
466
467                 fspath += ':';
468                 fspath += sp.path;
469                 if (fspath[fspath.length()-1] != '/') {
470                         fspath += '/';
471                 }
472                 fspath += sound_dir_name;
473                 fspath += ':';
474
475                 fspath += sp.path;
476                 if (fspath[fspath.length()-1] != '/') {
477                         fspath += '/';
478                 }
479                 fspath += tape_dir_name;
480
481                 session_dirs.push_back (sp);
482         }
483
484         /* set the AudioFileSource search path */
485
486         AudioFileSource::set_search_path (fspath);
487
488         /* reset the round-robin soundfile path thingie */
489
490         last_rr_session_dir = session_dirs.begin();
491 }
492
493 int
494 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
495 {
496         string dir;
497         
498         if (mkdir (_path.c_str(), 0755) < 0) {
499                 if (errno == EEXIST) {
500                         new_session = false;
501                 } else {
502                         error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
503                         return -1;
504                 }
505         } else {
506                 new_session = true;
507         }
508
509         dir = peak_dir ();
510
511         if (mkdir (dir.c_str(), 0755) < 0) {
512                 if (errno != EEXIST) {
513                         error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
514                         return -1;
515                 }
516         }
517
518         dir = sound_dir ();
519
520         if (mkdir (dir.c_str(), 0755) < 0) {
521                 if (errno != EEXIST) {
522                         error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
523                         return -1;
524                 }
525         }
526
527         dir = tape_dir ();
528
529         if (mkdir (dir.c_str(), 0755) < 0) {
530                 if (errno != EEXIST) {
531                         error << string_compose(_("Session: cannot create session tape dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
532                         return -1;
533                 }
534         }
535
536         dir = dead_sound_dir ();
537
538         if (mkdir (dir.c_str(), 0755) < 0) {
539                 if (errno != EEXIST) {
540                         error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
541                         return -1;
542                 }
543         }
544
545         dir = automation_dir ();
546
547         if (mkdir (dir.c_str(), 0755) < 0) {
548                 if (errno != EEXIST) {
549                         error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
550                         return -1;
551                 }
552         }
553
554         
555         /* check new_session so we don't overwrite an existing one */
556         
557         if (mix_template) {
558                 if (new_session){
559                         std::string in_path = *mix_template;
560
561                         ifstream in(in_path.c_str());
562                         
563                         if (in){
564                                 string out_path = _path;
565                                 out_path += _name;
566                                 out_path += _statefile_suffix;
567                                 
568                                 ofstream out(out_path.c_str());
569
570                                 if (out){
571                                         out << in.rdbuf();
572                                         
573                                         // okay, session is set up.  Treat like normal saved
574                                         // session from now on.
575                                         
576                                         new_session = false;
577                                         return 0;
578                                         
579                                 } else {
580                                         error << string_compose (_("Could not open %1 for writing mix template"), out_path) 
581                                               << endmsg;
582                                         return -1;
583                                 }
584                                 
585                         } else {
586                                 error << string_compose (_("Could not open mix template %1 for reading"), in_path) 
587                                       << endmsg;
588                                 return -1;
589                         }
590                         
591                         
592                 } else {
593                         warning << _("Session already exists.  Not overwriting") << endmsg;
594                         return -1;
595                 }
596         }
597
598         if (new_session) {
599
600                 /* set initial start + end point */
601
602                 start_location->set_end (0);
603                 _locations.add (start_location);
604
605                 end_location->set_end (initial_length);
606                 _locations.add (end_location);
607                 
608                 _state_of_the_state = Clean;
609
610                 if (save_state (_current_snapshot_name)) {
611                         save_history (_current_snapshot_name);
612                         return -1;
613                 }
614         }
615
616         return 0;
617 }
618
619 int
620 Session::load_diskstreams (const XMLNode& node)
621 {
622         XMLNodeList          clist;
623         XMLNodeConstIterator citer;
624         
625         clist = node.children();
626
627         for (citer = clist.begin(); citer != clist.end(); ++citer) {
628                 Diskstream* dstream = 0;
629
630                 try {
631                         /* diskstreams added automatically by DiskstreamCreated handler */
632                         if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
633                                 dstream = new AudioDiskstream (*this, **citer);
634                         } else if ((*citer)->name() == "MidiDiskstream") {
635                                 dstream = new MidiDiskstream (*this, **citer);
636                         } else {
637                                 error << _("Session: unknown diskstream type in XML") << endmsg;
638                         }
639                 } 
640                 
641                 catch (failed_constructor& err) {
642                         error << _("Session: could not load diskstream via XML state") << endmsg;
643                         return -1;
644                 }
645         }
646
647         return 0;
648 }
649
650 void
651 Session::remove_pending_capture_state ()
652 {
653         string xml_path;
654
655         xml_path = _path;
656         xml_path += _current_snapshot_name;
657         xml_path += _pending_suffix;
658
659         unlink (xml_path.c_str());
660 }
661
662 int
663 Session::save_state (string snapshot_name, bool pending)
664 {
665         XMLTree tree;
666         string xml_path;
667         string bak_path;
668
669         if (_state_of_the_state & CannotSave) {
670                 return 1;
671         }
672
673         tree.set_root (&get_state());
674
675         if (snapshot_name.empty()) {
676                 snapshot_name = _current_snapshot_name;
677         }
678
679         if (!pending) {
680
681                 xml_path = _path;
682                 xml_path += snapshot_name;
683                 xml_path += _statefile_suffix;
684                 bak_path = xml_path;
685                 bak_path += ".bak";
686                 
687                 // Make backup of state file
688                 
689                 if ((access (xml_path.c_str(), F_OK) == 0) &&
690                     (rename(xml_path.c_str(), bak_path.c_str()))) {
691                         error << _("could not backup old state file, current state not saved.") << endmsg;
692                         return -1;
693                 }
694
695         } else {
696
697                 xml_path = _path;
698                 xml_path += snapshot_name;
699                 xml_path += _pending_suffix;
700
701         }
702
703         if (!tree.write (xml_path)) {
704                 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
705
706                 /* don't leave a corrupt file lying around if it is
707                    possible to fix.
708                 */
709
710                 if (unlink (xml_path.c_str())) {
711                         error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
712                 } else {
713                         if (!pending) {
714                                 if (rename (bak_path.c_str(), xml_path.c_str())) {
715                                         error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
716                                 }
717                         }
718                 }
719
720                 return -1;
721         }
722
723         if (!pending) {
724
725                 bool was_dirty = dirty();
726
727                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
728                 
729                 if (was_dirty) {
730                         DirtyChanged (); /* EMIT SIGNAL */
731                 }
732                 
733                 StateSaved (snapshot_name); /* EMIT SIGNAL */
734         }
735
736         return 0;
737 }
738
739 int
740 Session::restore_state (string snapshot_name)
741 {
742         if (load_state (snapshot_name) == 0) {
743                 set_state (*state_tree->root());
744         }
745         
746         return 0;
747 }
748
749 int
750 Session::load_state (string snapshot_name)
751 {
752         if (state_tree) {
753                 delete state_tree;
754                 state_tree = 0;
755         }
756
757         string xmlpath;
758         
759         state_was_pending = false;
760
761         /* check for leftover pending state from a crashed capture attempt */
762
763         xmlpath = _path;
764         xmlpath += snapshot_name;
765         xmlpath += _pending_suffix;
766
767         if (!access (xmlpath.c_str(), F_OK)) {
768
769                 /* there is pending state from a crashed capture attempt */
770
771                 if (AskAboutPendingState()) {
772                         state_was_pending = true;
773                 } 
774         } 
775
776         if (!state_was_pending) {
777
778                 xmlpath = _path;
779                 xmlpath += snapshot_name;
780                 xmlpath += _statefile_suffix;
781         }
782
783         if (access (xmlpath.c_str(), F_OK)) {
784                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
785                 return 1;
786         }
787
788         state_tree = new XMLTree;
789
790         set_dirty();
791
792         if (state_tree->read (xmlpath)) {
793                 return 0;
794         } else {
795                 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
796         }
797
798         delete state_tree;
799         state_tree = 0;
800         return -1;
801 }
802
803 int
804 Session::load_options (const XMLNode& node)
805 {
806         XMLNode* child;
807         XMLProperty* prop;
808         bool have_fade_msecs = false;
809         bool have_fade_steepness = false;
810         float fade_msecs = 0;
811         float fade_steepness = 0;
812         SlaveSource slave_src = None;
813         int x;
814         LocaleGuard lg (X_("POSIX"));
815         
816         if ((child = find_named_node (node, "input-auto-connect")) != 0) {
817                 if ((prop = child->property ("val")) != 0) {
818                         sscanf (prop->value().c_str(), "%x", &x);
819                         input_auto_connect = AutoConnectOption (x);
820                 }
821         }
822
823         if ((child = find_named_node (node, "output-auto-connect")) != 0) {
824                 if ((prop = child->property ("val")) != 0) {
825                         sscanf (prop->value().c_str(), "%x", &x);
826                         output_auto_connect = AutoConnectOption (x);
827                 }
828         }
829                                 
830         if ((child = find_named_node (node, "slave")) != 0) {
831                 if ((prop = child->property ("type")) != 0) {
832                         if (prop->value() == "none") {
833                                 slave_src = None;
834                         } else if (prop->value() == "mtc") {
835                                 slave_src = MTC;
836                         } else if (prop->value() == "jack") {
837                                 slave_src = JACK;
838                         }
839                         set_slave_source (slave_src, 0);
840                 }
841         }
842
843         /* we cannot set edit mode if we are loading a session,
844            because it might destroy the playlist's positioning
845         */
846
847         if ((child = find_named_node (node, "edit-mode")) != 0) {
848                 if ((prop = child->property ("val")) != 0) {
849                         if (prop->value() == "slide") {
850                                 pending_edit_mode = Slide;
851                         } else if (prop->value() == "splice") {
852                                 pending_edit_mode = Splice;
853                         } 
854                 }
855         }
856                                 
857         if ((child = find_named_node (node, "send-midi-timecode")) != 0) {
858                 if ((prop = child->property ("val")) != 0) {
859                         bool x = (prop->value() == "yes");
860                         send_mtc = !x; /* force change in value */
861                         set_send_mtc (x);
862                 }
863         }
864         if ((child = find_named_node (node, "send-midi-machine-control")) != 0) {
865                 if ((prop = child->property ("val")) != 0) {
866                         bool x = (prop->value() == "yes");
867                         send_mmc = !x; /* force change in value */
868                         set_send_mmc (prop->value() == "yes");
869                 }
870         }
871         if ((child = find_named_node (node, "max-level")) != 0) {
872                 if ((prop = child->property ("val")) != 0) {
873                         max_level = atoi (prop->value().c_str());
874                 }
875         }
876         if ((child = find_named_node (node, "min-level")) != 0) {
877                 if ((prop = child->property ("val")) != 0) {
878                         min_level = atoi (prop->value().c_str());
879                 }
880         }
881         if ((child = find_named_node (node, "meter-hold")) != 0) {
882                 if ((prop = child->property ("val")) != 0) {
883                         _meter_hold = atof (prop->value().c_str());
884                 }
885         }
886         if ((child = find_named_node (node, "meter-falloff")) != 0) {
887                 if ((prop = child->property ("val")) != 0) {
888                         _meter_falloff = atof (prop->value().c_str());
889                 }
890         }
891         if ((child = find_named_node (node, "long-over-length")) != 0) {
892                 if ((prop = child->property ("val")) != 0) {
893                         over_length_long = atoi (prop->value().c_str());
894                 }
895         }
896         if ((child = find_named_node (node, "short-over-length")) != 0) {
897                 if ((prop = child->property ("val")) != 0) {
898                         over_length_short = atoi (prop->value().c_str());
899                 }
900         }
901         if ((child = find_named_node (node, "shuttle-speed-factor")) != 0) {
902                 if ((prop = child->property ("val")) != 0) {
903                         shuttle_speed_factor = atof (prop->value().c_str());
904                 }
905         }
906         if ((child = find_named_node (node, "shuttle-speed-threshold")) != 0) {
907                 if ((prop = child->property ("val")) != 0) {
908                         shuttle_speed_threshold = atof (prop->value().c_str());
909                 }
910         }
911         if ((child = find_named_node (node, "rf-speed")) != 0) {
912                 if ((prop = child->property ("val")) != 0) {
913                         rf_speed = atof (prop->value().c_str());
914                 }
915         }
916         if ((child = find_named_node (node, "smpte-frames-per-second")) != 0) {
917                 if ((prop = child->property ("val")) != 0) {
918                         set_smpte_type( atof (prop->value().c_str()), smpte_drop_frames );
919                 }
920         }
921         if ((child = find_named_node (node, "smpte-drop-frames")) != 0) {
922                 if ((prop = child->property ("val")) != 0) {
923                         set_smpte_type( smpte_frames_per_second, (prop->value() == "yes") );
924                 }
925         }
926         if ((child = find_named_node (node, "smpte-offset")) != 0) {
927                 if ((prop = child->property ("val")) != 0) {
928                         set_smpte_offset( atoi (prop->value().c_str()) );
929                 }
930         }
931         if ((child = find_named_node (node, "smpte-offset-negative")) != 0) {
932                 if ((prop = child->property ("val")) != 0) {
933                         set_smpte_offset_negative( (prop->value() == "yes") );
934                 }
935         }
936         if ((child = find_named_node (node, "click-sound")) != 0) {
937                 if ((prop = child->property ("val")) != 0) {
938                         click_sound = prop->value();
939                 }
940         }
941         if ((child = find_named_node (node, "click-emphasis-sound")) != 0) {
942                 if ((prop = child->property ("val")) != 0) {
943                         click_emphasis_sound = prop->value();
944                 }
945         }
946
947         if ((child = find_named_node (node, "solo-model")) != 0) {
948                 if ((prop = child->property ("val")) != 0) {
949                         if (prop->value() == "SoloBus")
950                                 _solo_model = SoloBus;
951                         else
952                                 _solo_model = InverseMute;
953                 }
954         }
955
956         /* BOOLEAN OPTIONS */
957
958         if ((child = find_named_node (node, "auto-play")) != 0) {
959                 if ((prop = child->property ("val")) != 0) {
960                         set_auto_play (prop->value() == "yes");
961                 }
962         }
963         if ((child = find_named_node (node, "auto-input")) != 0) {
964                 if ((prop = child->property ("val")) != 0) {
965                         set_auto_input (prop->value() == "yes");
966                 }
967         }
968         if ((child = find_named_node (node, "seamless-loop")) != 0) {
969                 if ((prop = child->property ("val")) != 0) {
970                         set_seamless_loop (prop->value() == "yes");
971                 }
972         }
973         if ((child = find_named_node (node, "punch-in")) != 0) {
974                 if ((prop = child->property ("val")) != 0) {
975                         set_punch_in (prop->value() == "yes");
976                 }
977         }
978         if ((child = find_named_node (node, "punch-out")) != 0) {
979                 if ((prop = child->property ("val")) != 0) {
980                         set_punch_out (prop->value() == "yes");
981                 }
982         }
983         if ((child = find_named_node (node, "auto-return")) != 0) {
984                 if ((prop = child->property ("val")) != 0) {
985                         set_auto_return (prop->value() == "yes");
986                 }
987         }
988         if ((child = find_named_node (node, "send-mtc")) != 0) {
989                 if ((prop = child->property ("val")) != 0) {
990                         set_send_mtc (prop->value() == "yes");
991                 }
992         }
993         if ((child = find_named_node (node, "mmc-control")) != 0) {
994                 if ((prop = child->property ("val")) != 0) {
995                         set_mmc_control (prop->value() == "yes");
996                 }
997         }
998         if ((child = find_named_node (node, "midi-control")) != 0) {
999                 if ((prop = child->property ("val")) != 0) {
1000                         set_midi_control (prop->value() == "yes");
1001                 }
1002         }
1003         if ((child = find_named_node (node, "midi-feedback")) != 0) {
1004                 if ((prop = child->property ("val")) != 0) {
1005                         set_midi_feedback (prop->value() == "yes");
1006                 }
1007         }
1008         // Legacy support for <recording-plugins>
1009         if ((child = find_named_node (node, "recording-plugins")) != 0) {
1010                 if ((prop = child->property ("val")) != 0) {
1011                         set_do_not_record_plugins (prop->value() == "no");
1012                 }
1013         }
1014         if ((child = find_named_node (node, "do-not-record-plugins")) != 0) {
1015                 if ((prop = child->property ("val")) != 0) {
1016                         set_do_not_record_plugins (prop->value() == "yes");
1017                 }
1018         }
1019         if ((child = find_named_node (node, "crossfades-active")) != 0) {
1020                 if ((prop = child->property ("val")) != 0) {
1021                         set_crossfades_active (prop->value() == "yes");
1022                 }
1023         }
1024         if ((child = find_named_node (node, "audible-click")) != 0) {
1025                 if ((prop = child->property ("val")) != 0) {
1026                         set_clicking (prop->value() == "yes");
1027                 }
1028         }
1029
1030         if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
1031                 if ((prop = child->property ("val")) != 0) {
1032                         _end_location_is_free = (prop->value() == "yes");
1033                 }
1034         }
1035
1036         if ((child = find_named_node (node, "layer-model")) != 0) {
1037                 if ((prop = child->property ("val")) != 0) {
1038                         if (prop->value() == X_("LaterHigher")) {
1039                                 set_layer_model (LaterHigher);
1040                         } else if (prop->value() == X_("AddHigher")) {
1041                                 set_layer_model (AddHigher);
1042                         } else {
1043                                 set_layer_model (MoveAddHigher);
1044                         }
1045                 }
1046         }
1047
1048         if ((child = find_named_node (node, "xfade-model")) != 0) {
1049                 if ((prop = child->property ("val")) != 0) {
1050                         if (prop->value() == X_("Short")) {
1051                                 set_xfade_model (ShortCrossfade);
1052                         } else {
1053                                 set_xfade_model (FullCrossfade);
1054                         }
1055                 }
1056         }
1057
1058         if ((child = find_named_node (node, "short-xfade-length")) != 0) {
1059                 if ((prop = child->property ("val")) != 0) {
1060                         /* value is stored as a fractional seconds */
1061                         float secs = atof (prop->value().c_str());
1062                         Crossfade::set_short_xfade_length ((jack_nframes_t) floor (secs * frame_rate()));
1063                 } 
1064         }
1065
1066         if ((child = find_named_node (node, "full-xfades-unmuted")) != 0) {
1067                 if ((prop = child->property ("val")) != 0) {
1068                         crossfades_active = (prop->value() == "yes");
1069                 }
1070         } 
1071
1072         /* TIED OPTIONS */
1073
1074         if ((child = find_named_node (node, "default-fade-steepness")) != 0) {
1075                 if ((prop = child->property ("val")) != 0) {
1076                         fade_steepness = atof (prop->value().c_str());
1077                         have_fade_steepness = true;
1078                 }
1079         }
1080         if ((child = find_named_node (node, "default-fade-msec")) != 0) {
1081                 if ((prop = child->property ("val")) != 0) {
1082                         fade_msecs = atof (prop->value().c_str());
1083                         have_fade_msecs = true;
1084                 }
1085         }
1086
1087         if (have_fade_steepness || have_fade_msecs) {
1088                 // set_default_fade (fade_steepness, fade_msecs);
1089         }
1090
1091         return 0;
1092 }
1093
1094 XMLNode&
1095 Session::get_options () const
1096 {
1097         XMLNode* opthead;
1098         XMLNode* child;
1099         char buf[32];
1100         LocaleGuard lg (X_("POSIX"));
1101
1102         opthead = new XMLNode ("Options");
1103
1104         SlaveSource src = slave_source ();
1105         string src_string;
1106         switch (src) {
1107         case None:
1108                 src_string = "none";
1109                 break;
1110         case MTC:
1111                 src_string = "mtc";
1112                 break;
1113         case JACK:
1114                 src_string = "jack";
1115                 break;
1116         }
1117         child = opthead->add_child ("slave");
1118         child->add_property ("type", src_string);
1119         
1120         child = opthead->add_child ("send-midi-timecode");
1121         child->add_property ("val", send_midi_timecode?"yes":"no");
1122
1123         child = opthead->add_child ("send-midi-machine-control");
1124         child->add_property ("val", send_midi_machine_control?"yes":"no");
1125
1126         snprintf (buf, sizeof(buf)-1, "%x", (int) input_auto_connect);
1127         child = opthead->add_child ("input-auto-connect");
1128         child->add_property ("val", buf);
1129
1130         snprintf (buf, sizeof(buf)-1, "%x", (int) output_auto_connect);
1131         child = opthead->add_child ("output-auto-connect");
1132         child->add_property ("val", buf);
1133
1134         snprintf (buf, sizeof(buf)-1, "%d", max_level);
1135         child = opthead->add_child ("max-level");
1136         child->add_property ("val", buf);
1137
1138         snprintf (buf, sizeof(buf)-1, "%d", min_level);
1139         child = opthead->add_child ("min-level");
1140         child->add_property ("val", buf);
1141
1142         snprintf (buf, sizeof(buf)-1, "%f", _meter_hold);
1143         child = opthead->add_child ("meter-hold");
1144         child->add_property ("val", buf);
1145
1146         snprintf (buf, sizeof(buf)-1, "%f", _meter_falloff);
1147         child = opthead->add_child ("meter-falloff");
1148         child->add_property ("val", buf);
1149         
1150         snprintf (buf, sizeof(buf)-1, "%u", over_length_long);
1151         child = opthead->add_child ("long-over-length");
1152         child->add_property ("val", buf);
1153
1154         snprintf (buf, sizeof(buf)-1, "%u", over_length_short);
1155         child = opthead->add_child ("short-over-length");
1156         child->add_property ("val", buf);
1157
1158         snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_factor);
1159         child = opthead->add_child ("shuttle-speed-factor");
1160         child->add_property ("val", buf);
1161
1162         snprintf (buf, sizeof(buf)-1, "%f", shuttle_speed_threshold);
1163         child = opthead->add_child ("shuttle-speed-threshold");
1164         child->add_property ("val", buf);
1165
1166         snprintf (buf, sizeof(buf)-1, "%f", rf_speed);
1167         child = opthead->add_child ("rf-speed");
1168         child->add_property ("val", buf);
1169
1170         snprintf (buf, sizeof(buf)-1, "%.2f", smpte_frames_per_second);
1171         child = opthead->add_child ("smpte-frames-per-second");
1172         child->add_property ("val", buf);
1173         
1174         child = opthead->add_child ("smpte-drop-frames");
1175         child->add_property ("val", smpte_drop_frames ? "yes" : "no");
1176         
1177         snprintf (buf, sizeof(buf)-1, "%u", smpte_offset ());
1178         child = opthead->add_child ("smpte-offset");
1179         child->add_property ("val", buf);
1180         
1181         child = opthead->add_child ("smpte-offset-negative");
1182         child->add_property ("val", smpte_offset_negative () ? "yes" : "no");
1183         
1184         child = opthead->add_child ("edit-mode");
1185         switch (_edit_mode) {
1186         case Splice:
1187                 child->add_property ("val", "splice");
1188                 break;
1189
1190         case Slide:
1191                 child->add_property ("val", "slide");
1192                 break;
1193         }
1194
1195         child = opthead->add_child ("auto-play");
1196         child->add_property ("val", get_auto_play () ? "yes" : "no");
1197         child = opthead->add_child ("auto-input");
1198         child->add_property ("val", get_auto_input () ? "yes" : "no");
1199         child = opthead->add_child ("seamless-loop");
1200         child->add_property ("val", get_seamless_loop () ? "yes" : "no");
1201         child = opthead->add_child ("punch-in");
1202         child->add_property ("val", get_punch_in () ? "yes" : "no");
1203         child = opthead->add_child ("punch-out");
1204         child->add_property ("val", get_punch_out () ? "yes" : "no");
1205         child = opthead->add_child ("all-safe");
1206         child->add_property ("val", get_all_safe () ? "yes" : "no");
1207         child = opthead->add_child ("auto-return");
1208         child->add_property ("val", get_auto_return () ? "yes" : "no");
1209         child = opthead->add_child ("mmc-control");
1210         child->add_property ("val", get_mmc_control () ? "yes" : "no");
1211         child = opthead->add_child ("midi-control");
1212         child->add_property ("val", get_midi_control () ? "yes" : "no");
1213         child = opthead->add_child ("midi-feedback");
1214         child->add_property ("val", get_midi_feedback () ? "yes" : "no");
1215         child = opthead->add_child ("do-not-record-plugins");
1216         child->add_property ("val", get_do_not_record_plugins () ? "yes" : "no");
1217         child = opthead->add_child ("auto-crossfade");
1218         child->add_property ("val", get_crossfades_active () ? "yes" : "no");
1219         child = opthead->add_child ("audible-click");
1220         child->add_property ("val", get_clicking () ? "yes" : "no");
1221         child = opthead->add_child ("end-marker-is-free");
1222         child->add_property ("val", _end_location_is_free ? "yes" : "no");
1223
1224         if (click_sound.length()) {
1225                 child = opthead->add_child ("click-sound");
1226                 child->add_property ("val", click_sound);
1227         }
1228
1229         if (click_emphasis_sound.length()) {
1230                 child = opthead->add_child ("click-emphasis-sound");
1231                 child->add_property ("val", click_emphasis_sound);
1232         }
1233
1234         child = opthead->add_child ("solo-model");
1235         child->add_property ("val", _solo_model == SoloBus ? "SoloBus" : "InverseMute");
1236
1237         child = opthead->add_child ("layer-model");
1238         switch (layer_model) {
1239         case LaterHigher:
1240                 child->add_property ("val", X_("LaterHigher"));
1241                 break;
1242         case MoveAddHigher:
1243                 child->add_property ("val", X_("MoveAddHigher"));
1244                 break;
1245         case AddHigher:
1246                 child->add_property ("val", X_("AddHigher"));
1247                 break;
1248         }
1249
1250         child = opthead->add_child ("xfade-model");
1251         switch (xfade_model) {
1252         case FullCrossfade:
1253                 child->add_property ("val", X_("Full"));
1254                 break;
1255         case ShortCrossfade:
1256                 child->add_property ("val", X_("Short"));
1257         }
1258
1259         child = opthead->add_child ("short-xfade-length");
1260         /* store as fractions of a second */
1261         snprintf (buf, sizeof(buf)-1, "%f", 
1262                   (float) Crossfade::short_xfade_length() / frame_rate());
1263         child->add_property ("val", buf);
1264
1265         child = opthead->add_child ("full-xfades-unmuted");
1266         child->add_property ("val", crossfades_active ? "yes" : "no");
1267
1268         return *opthead;
1269 }
1270
1271 XMLNode&
1272 Session::get_state()
1273 {
1274         return state(true);
1275 }
1276
1277 XMLNode&
1278 Session::get_template()
1279 {
1280         /* if we don't disable rec-enable, diskstreams
1281            will believe they need to store their capture
1282            sources in their state node. 
1283         */
1284         
1285         disable_record (false);
1286
1287         return state(false);
1288 }
1289
1290 XMLNode&
1291 Session::state(bool full_state)
1292 {
1293         XMLNode* node = new XMLNode("Session");
1294         XMLNode* child;
1295
1296         // store libardour version, just in case
1297         char buf[16];
1298         snprintf(buf, sizeof(buf)-1, "%d.%d.%d", 
1299                  libardour_major_version, libardour_minor_version, libardour_micro_version);
1300         node->add_property("version", string(buf));
1301                 
1302         /* store configuration settings */
1303
1304         if (full_state) {
1305         
1306                 /* store the name */
1307                 node->add_property ("name", _name);
1308
1309                 if (session_dirs.size() > 1) {
1310
1311                         string p;
1312
1313                         vector<space_and_path>::iterator i = session_dirs.begin();
1314                         vector<space_and_path>::iterator next;
1315
1316                         ++i; /* skip the first one */
1317                         next = i;
1318                         ++next;
1319
1320                         while (i != session_dirs.end()) {
1321
1322                                 p += (*i).path;
1323
1324                                 if (next != session_dirs.end()) {
1325                                         p += ':';
1326                                 } else {
1327                                         break;
1328                                 }
1329
1330                                 ++next;
1331                                 ++i;
1332                         }
1333                         
1334                         child = node->add_child ("Path");
1335                         child->add_content (p);
1336                 }
1337         }
1338
1339         /* save the ID counter */
1340         
1341         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1342         node->add_property ("id-counter", buf);
1343
1344         /* various options */
1345
1346         node->add_child_nocopy (get_options());
1347
1348         child = node->add_child ("Sources");
1349
1350         if (full_state) {
1351                 Glib::Mutex::Lock sl (audio_source_lock);
1352
1353                 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
1354                         
1355                         /* Don't save information about AudioFileSources that are empty */
1356                         
1357                         AudioFileSource* fs;
1358
1359                         if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
1360                                 DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
1361
1362                                 /* destructive file sources are OK if they are empty, because
1363                                    we will re-use them every time.
1364                                 */
1365
1366                                 if (!dfs) {
1367                                         if (fs->length() == 0) {
1368                                                 continue;
1369                                         }
1370                                 }
1371                         }
1372                         
1373                         child->add_child_nocopy (siter->second->get_state());
1374                 }
1375         }
1376
1377         child = node->add_child ("Regions");
1378
1379         if (full_state) { 
1380                 Glib::Mutex::Lock rl (region_lock);
1381
1382                 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1383                         
1384                         /* only store regions not attached to playlists */
1385
1386                         if (i->second->playlist() == 0) {
1387                                 child->add_child_nocopy (i->second->state (true));
1388                         }
1389                 }
1390         }
1391
1392         child = node->add_child ("DiskStreams");
1393
1394         { 
1395                 Glib::RWLock::ReaderLock dl (diskstream_lock);
1396                 for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
1397                         if (!(*i)->hidden()) {
1398                                 child->add_child_nocopy ((*i)->get_state());
1399                         }
1400                 }
1401         }
1402
1403         node->add_child_nocopy (_locations.get_state());
1404         
1405         child = node->add_child ("Connections");
1406         {
1407                 Glib::Mutex::Lock lm (connection_lock);
1408                 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1409                         if (!(*i)->system_dependent()) {
1410                                 child->add_child_nocopy ((*i)->get_state());
1411                         }
1412                 }
1413         }
1414
1415         child = node->add_child ("Routes");
1416         {
1417                 boost::shared_ptr<RouteList> r = routes.reader ();
1418                 
1419                 RoutePublicOrderSorter cmp;
1420                 RouteList public_order (*r);
1421                 public_order.sort (cmp);
1422                 
1423                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1424                         if (!(*i)->hidden()) {
1425                                 if (full_state) {
1426                                         child->add_child_nocopy ((*i)->get_state());
1427                                 } else {
1428                                         child->add_child_nocopy ((*i)->get_template());
1429                                 }
1430                         }
1431                 }
1432         }
1433
1434         
1435         child = node->add_child ("EditGroups");
1436         for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1437                 child->add_child_nocopy ((*i)->get_state());
1438         }
1439
1440         child = node->add_child ("MixGroups");
1441         for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1442                 child->add_child_nocopy ((*i)->get_state());
1443         }
1444
1445         child = node->add_child ("Playlists");
1446         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1447                 if (!(*i)->hidden()) {
1448                         if (!(*i)->empty()) {
1449                                 if (full_state) {
1450                                         child->add_child_nocopy ((*i)->get_state());
1451                                 } else {
1452                                         child->add_child_nocopy ((*i)->get_template());
1453                                 }
1454                         }
1455                 }
1456         }
1457
1458         child = node->add_child ("UnusedPlaylists");
1459         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1460                 if (!(*i)->hidden()) {
1461                         if (!(*i)->empty()) {
1462                                 if (full_state) {
1463                                         child->add_child_nocopy ((*i)->get_state());
1464                                 } else {
1465                                         child->add_child_nocopy ((*i)->get_template());
1466                                 }
1467                         }
1468                 }
1469         }
1470         
1471         
1472         if (_click_io) {
1473                 child = node->add_child ("Click");
1474                 child->add_child_nocopy (_click_io->state (full_state));
1475         }
1476
1477         if (full_state) {
1478                 child = node->add_child ("NamedSelections");
1479                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1480                         if (full_state) {
1481                                 child->add_child_nocopy ((*i)->get_state());
1482                         } 
1483                 }
1484         }
1485
1486         node->add_child_nocopy (_tempo_map->get_state());
1487
1488         if (_extra_xml) {
1489                 node->add_child_copy (*_extra_xml);
1490         }
1491
1492         return *node;
1493 }
1494
1495 int
1496 Session::set_state (const XMLNode& node)
1497 {
1498         XMLNodeList nlist;
1499         XMLNode* child;
1500         const XMLProperty* prop;
1501         int ret = -1;
1502
1503         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1504         
1505         if (node.name() != X_("Session")){
1506                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1507                 return -1;
1508         }
1509
1510         StateManager::prohibit_save ();
1511
1512         if ((prop = node.property ("name")) != 0) {
1513                 _name = prop->value ();
1514         }
1515
1516         if ((prop = node.property (X_("id-counter"))) != 0) {
1517                 uint64_t x;
1518                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1519                 ID::init_counter (x);
1520         } else {
1521                 /* old sessions used a timebased counter, so fake
1522                    the startup ID counter based on a standard
1523                    timestamp.
1524                 */
1525                 time_t now;
1526                 time (&now);
1527                 ID::init_counter (now);
1528         }
1529
1530         
1531         IO::disable_ports ();
1532         IO::disable_connecting ();
1533
1534         /* Object loading order:
1535
1536         MIDI
1537         Path
1538         extra
1539         Options
1540         Sources
1541         AudioRegions
1542         AudioDiskstreams
1543         Connections
1544         Locations
1545         Routes
1546         EditGroups
1547         MixGroups
1548         Click
1549         */
1550
1551         if (use_config_midi_ports ()) {
1552         }
1553
1554         if ((child = find_named_node (node, "Path")) != 0) {
1555                 /* XXX this XML content stuff horrible API design */
1556                 string raid_path = _path + ':' + child->children().front()->content();
1557                 setup_raid_path (raid_path);
1558         } else {
1559                 /* the path is already set */
1560         }
1561
1562         if ((child = find_named_node (node, "extra")) != 0) {
1563                 _extra_xml = new XMLNode (*child);
1564         }
1565
1566         if ((child = find_named_node (node, "Options")) == 0) {
1567                 error << _("Session: XML state has no options section") << endmsg;
1568         } else if (load_options (*child)) {
1569         }
1570
1571         if ((child = find_named_node (node, "Sources")) == 0) {
1572                 error << _("Session: XML state has no sources section") << endmsg;
1573                 goto out;
1574         } else if (load_sources (*child)) {
1575                 goto out;
1576         }
1577
1578         if ((child = find_named_node (node, "Regions")) == 0) {
1579                 error << _("Session: XML state has no Regions section") << endmsg;
1580                 goto out;
1581         } else if (load_regions (*child)) {
1582                 goto out;
1583         }
1584
1585         if ((child = find_named_node (node, "Playlists")) == 0) {
1586                 error << _("Session: XML state has no playlists section") << endmsg;
1587                 goto out;
1588         } else if (load_playlists (*child)) {
1589                 goto out;
1590         }
1591
1592         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1593                 // this is OK
1594         } else if (load_unused_playlists (*child)) {
1595                 goto out;
1596         }
1597         
1598         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1599                 if (load_named_selections (*child)) {
1600                         goto out;
1601                 }
1602         }
1603
1604         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1605                 error << _("Session: XML state has no diskstreams section") << endmsg;
1606                 goto out;
1607         } else if (load_diskstreams (*child)) {
1608                 goto out;
1609         }
1610
1611         if ((child = find_named_node (node, "Connections")) == 0) {
1612                 error << _("Session: XML state has no connections section") << endmsg;
1613                 goto out;
1614         } else if (load_connections (*child)) {
1615                 goto out;
1616         }
1617
1618         if ((child = find_named_node (node, "Locations")) == 0) {
1619                 error << _("Session: XML state has no locations section") << endmsg;
1620                 goto out;
1621         } else if (_locations.set_state (*child)) {
1622                 goto out;
1623         }
1624
1625         Location* location;
1626
1627         if ((location = _locations.auto_loop_location()) != 0) {
1628                 set_auto_loop_location (location);
1629         }
1630
1631         if ((location = _locations.auto_punch_location()) != 0) {
1632                 set_auto_punch_location (location);
1633         }
1634
1635         if ((location = _locations.end_location()) == 0) {
1636                 _locations.add (end_location);
1637         } else {
1638                 delete end_location;
1639                 end_location = location;
1640         }
1641
1642         if ((location = _locations.start_location()) == 0) {
1643                 _locations.add (start_location);
1644         } else {
1645                 delete start_location;
1646                 start_location = location;
1647         }
1648
1649         _locations.save_state (_("initial state"));
1650
1651         if ((child = find_named_node (node, "EditGroups")) == 0) {
1652                 error << _("Session: XML state has no edit groups section") << endmsg;
1653                 goto out;
1654         } else if (load_edit_groups (*child)) {
1655                 goto out;
1656         }
1657
1658         if ((child = find_named_node (node, "MixGroups")) == 0) {
1659                 error << _("Session: XML state has no mix groups section") << endmsg;
1660                 goto out;
1661         } else if (load_mix_groups (*child)) {
1662                 goto out;
1663         }
1664
1665         if ((child = find_named_node (node, "TempoMap")) == 0) {
1666                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1667                 goto out;
1668         } else if (_tempo_map->set_state (*child)) {
1669                 goto out;
1670         }
1671
1672         if ((child = find_named_node (node, "Routes")) == 0) {
1673                 error << _("Session: XML state has no routes section") << endmsg;
1674                 goto out;
1675         } else if (load_routes (*child)) {
1676                 goto out;
1677         }
1678
1679         if ((child = find_named_node (node, "Click")) == 0) {
1680                 warning << _("Session: XML state has no click section") << endmsg;
1681         } else if (_click_io) {
1682                 _click_io->set_state (*child);
1683         }
1684         
1685         /* OK, now we can set edit mode */
1686
1687         set_edit_mode (pending_edit_mode);
1688
1689         /* here beginneth the second phase ... */
1690
1691         StateReady (); /* EMIT SIGNAL */
1692
1693         _state_of_the_state = Clean;
1694
1695         StateManager::allow_save (_("initial state"), true);
1696
1697         if (state_was_pending) {
1698                 save_state (_current_snapshot_name);
1699                 save_history (_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         save_history (_current_snapshot_name);
2502 }
2503
2504 RouteGroup *
2505 Session::add_edit_group (string name)
2506 {
2507         RouteGroup* rg = new RouteGroup (*this, name);
2508         edit_groups.push_back (rg);
2509         edit_group_added (rg); /* EMIT SIGNAL */
2510         set_dirty();
2511         return rg;
2512 }
2513
2514 RouteGroup *
2515 Session::add_mix_group (string name)
2516 {
2517         RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2518         mix_groups.push_back (rg);
2519         mix_group_added (rg); /* EMIT SIGNAL */
2520         set_dirty();
2521         return rg;
2522 }
2523
2524 void
2525 Session::remove_edit_group (RouteGroup& rg)
2526 {
2527         list<RouteGroup*>::iterator i;
2528
2529         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2530                 (*i)->apply (&Route::drop_edit_group, this);
2531                 edit_groups.erase (i);
2532                 edit_group_removed (); /* EMIT SIGNAL */
2533         }
2534
2535         delete &rg;
2536 }
2537
2538 void
2539 Session::remove_mix_group (RouteGroup& rg)
2540 {
2541         list<RouteGroup*>::iterator i;
2542
2543         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2544                 (*i)->apply (&Route::drop_mix_group, this);
2545                 mix_groups.erase (i);
2546                 mix_group_removed (); /* EMIT SIGNAL */
2547         }
2548
2549         delete &rg;
2550 }
2551
2552 RouteGroup *
2553 Session::mix_group_by_name (string name)
2554 {
2555         list<RouteGroup *>::iterator i;
2556
2557         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2558                 if ((*i)->name() == name) {
2559                         return* i;
2560                 }
2561         }
2562         return 0;
2563 }
2564
2565 RouteGroup *
2566 Session::edit_group_by_name (string name)
2567 {
2568         list<RouteGroup *>::iterator i;
2569
2570         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2571                 if ((*i)->name() == name) {
2572                         return* i;
2573                 }
2574         }
2575         return 0;
2576 }
2577
2578 void
2579 Session::set_meter_hold (float val)
2580 {
2581         _meter_hold = val;
2582         MeterHoldChanged(); // emit
2583 }
2584
2585 void
2586 Session::set_meter_falloff (float val)
2587 {
2588         _meter_falloff = val;
2589         MeterFalloffChanged(); // emit
2590 }
2591
2592
2593 void
2594 Session::begin_reversible_command (string name)
2595 {
2596         current_trans.clear ();
2597         current_trans.set_name (name);
2598 }
2599
2600 void
2601 Session::commit_reversible_command (Command *cmd)
2602 {
2603         struct timeval now;
2604
2605         if (cmd) {
2606                 current_trans.add_command (cmd);
2607         }
2608
2609         gettimeofday (&now, 0);
2610         current_trans.set_timestamp (now);
2611
2612         history.add (current_trans);
2613 }
2614
2615 Session::GlobalRouteBooleanState 
2616 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2617 {
2618         GlobalRouteBooleanState s;
2619         boost::shared_ptr<RouteList> r = routes.reader ();
2620
2621         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2622                 if (!(*i)->hidden()) {
2623                         RouteBooleanState v;
2624                         
2625                         v.first =* i;
2626                         Route* r = (*i).get();
2627                         v.second = (r->*method)();
2628                         
2629                         s.push_back (v);
2630                 }
2631         }
2632
2633         return s;
2634 }
2635
2636 Session::GlobalRouteMeterState
2637 Session::get_global_route_metering ()
2638 {
2639         GlobalRouteMeterState s;
2640         boost::shared_ptr<RouteList> r = routes.reader ();
2641
2642         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2643                 if (!(*i)->hidden()) {
2644                         RouteMeterState v;
2645                         
2646                         v.first =* i;
2647                         v.second = (*i)->meter_point();
2648                         
2649                         s.push_back (v);
2650                 }
2651         }
2652
2653         return s;
2654 }
2655
2656 void
2657 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2658 {
2659         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2660                 i->first->set_meter_point (i->second, arg);
2661         }
2662 }
2663
2664 void
2665 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2666 {
2667         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2668                 Route* r = i->first.get();
2669                 (r->*method) (i->second, arg);
2670         }
2671 }
2672
2673 void
2674 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2675 {
2676         set_global_route_boolean (s, &Route::set_mute, src);
2677 }
2678
2679 void
2680 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2681 {
2682         set_global_route_boolean (s, &Route::set_solo, src);
2683 }
2684
2685 void
2686 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2687 {
2688         set_global_route_boolean (s, &Route::set_record_enable, src);
2689 }
2690
2691 #if 0
2692 UndoAction
2693 Session::global_mute_memento (void* src)
2694 {
2695         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2696 }
2697
2698 UndoAction
2699 Session::global_metering_memento (void* src)
2700 {
2701         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2702 }
2703
2704 UndoAction
2705 Session::global_solo_memento (void* src)
2706 {
2707         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2708 }
2709
2710 UndoAction
2711 Session::global_record_enable_memento (void* src)
2712 {
2713         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2714 }
2715 #endif
2716
2717 static bool
2718 template_filter (const string &str, void *arg)
2719 {
2720         return (str.length() > strlen(Session::template_suffix()) &&
2721                 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2722 }
2723
2724 void
2725 Session::get_template_list (list<string> &template_names)
2726 {
2727         vector<string *> *templates;
2728         PathScanner scanner;
2729         string path;
2730
2731         path = template_path ();
2732
2733         templates = scanner (path, template_filter, 0, false, true);
2734         
2735         vector<string*>::iterator i;
2736         for (i = templates->begin(); i != templates->end(); ++i) {
2737                 string fullpath = *(*i);
2738                 int start, end;
2739
2740                 start = fullpath.find_last_of ('/') + 1;
2741                 if ((end = fullpath.find_last_of ('.')) <0) {
2742                         end = fullpath.length();
2743                 }
2744                 
2745                 template_names.push_back(fullpath.substr(start, (end-start)));
2746         }
2747 }
2748
2749 int
2750 Session::read_favorite_dirs (FavoriteDirs & favs)
2751 {
2752         string path = get_user_ardour_path();
2753         path += "/favorite_dirs";
2754
2755         ifstream fav (path.c_str());
2756
2757         favs.clear();
2758         
2759         if (!fav) {
2760                 if (errno != ENOENT) {
2761                         //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2762                         return -1;
2763                 } else {
2764                         return 1;
2765                 }
2766         }
2767
2768         while (true) {
2769
2770                 string newfav;
2771
2772                 getline(fav, newfav);
2773
2774                 if (!fav.good()) {
2775                         break;
2776                 }
2777
2778                 favs.push_back (newfav);
2779         }
2780
2781         return 0;
2782 }
2783
2784 int
2785 Session::write_favorite_dirs (FavoriteDirs & favs)
2786 {
2787         string path = get_user_ardour_path();
2788         path += "/favorite_dirs";
2789
2790         ofstream fav (path.c_str());
2791
2792         if (!fav) {
2793                 return -1;
2794         }
2795
2796         for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2797                 fav << (*i) << endl;
2798         }
2799         
2800         return 0;
2801 }
2802
2803 static bool
2804 accept_all_non_peak_files (const string& path, void *arg)
2805 {
2806         return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2807 }
2808
2809 static bool
2810 accept_all_state_files (const string& path, void *arg)
2811 {
2812         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2813 }
2814
2815 int 
2816 Session::find_all_sources (string path, set<string>& result)
2817 {
2818         XMLTree tree;
2819         XMLNode* node;
2820
2821         if (!tree.read (path)) {
2822                 return -1;
2823         }
2824
2825         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2826                 return -2;
2827         }
2828
2829         XMLNodeList nlist;
2830         XMLNodeConstIterator niter;
2831
2832         nlist = node->children();
2833
2834         set_dirty();
2835
2836         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2837                 
2838                 XMLProperty* prop;
2839
2840                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2841                         continue;
2842                 }
2843
2844                 if (prop->value()[0] == '/') {
2845                         /* external file, ignore */
2846                         continue;
2847                 }
2848
2849                 string path = _path; /* /-terminated */
2850                 path += sound_dir_name;
2851                 path += '/';
2852                 path += prop->value();
2853
2854                 result.insert (path);
2855         }
2856
2857         return 0;
2858 }
2859
2860 int
2861 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2862 {
2863         PathScanner scanner;
2864         vector<string*>* state_files;
2865         string ripped;
2866         string this_snapshot_path;
2867
2868         result.clear ();
2869
2870         ripped = _path;
2871
2872         if (ripped[ripped.length()-1] == '/') {
2873                 ripped = ripped.substr (0, ripped.length() - 1);
2874         }
2875
2876         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2877         
2878         if (state_files == 0) {
2879                 /* impossible! */
2880                 return 0;
2881         }
2882
2883         this_snapshot_path = _path;
2884         this_snapshot_path += _current_snapshot_name;
2885         this_snapshot_path += _statefile_suffix;
2886
2887         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2888
2889                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2890                         continue;
2891                 }
2892
2893                 if (find_all_sources (**i, result) < 0) {
2894                         return -1;
2895                 }
2896         }
2897
2898         return 0;
2899 }
2900
2901 int
2902 Session::cleanup_sources (Session::cleanup_report& rep)
2903 {
2904         vector<Source*> dead_sources;
2905         vector<Playlist*> playlists_tbd;
2906         PathScanner scanner;
2907         string sound_path;
2908         vector<space_and_path>::iterator i;
2909         vector<space_and_path>::iterator nexti;
2910         vector<string*>* soundfiles;
2911         vector<string> unused;
2912         set<string> all_sources;
2913         bool used;
2914         string spath;
2915         int ret = -1;
2916                 
2917         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2918         
2919         /* step 1: consider deleting all unused playlists */
2920
2921         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2922                 int status;
2923
2924                 status = AskAboutPlaylistDeletion (*x);
2925
2926                 switch (status) {
2927                 case -1:
2928                         ret = 0;
2929                         goto out;
2930                         break;
2931
2932                 case 0:
2933                         playlists_tbd.push_back (*x);
2934                         break;
2935
2936                 default:
2937                         /* leave it alone */
2938                         break;
2939                 }
2940         }
2941
2942         /* now delete any that were marked for deletion */
2943
2944         for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2945                 PlaylistList::iterator foo;
2946
2947                 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2948                         unused_playlists.erase (foo);
2949                 }
2950                 delete *x;
2951         }
2952
2953         /* step 2: clear the undo/redo history for all playlists */
2954
2955         for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2956                 (*x)->drop_all_states ();
2957         }
2958
2959         /* step 3: find all un-referenced sources */
2960
2961         rep.paths.clear ();
2962         rep.space = 0;
2963
2964         for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2965
2966                 AudioSourceList::iterator tmp;
2967
2968                 tmp = i;
2969                 ++tmp;
2970
2971                 /* only remove files that are not in use and have some size
2972                    to them. otherwise we remove the current "nascent"
2973                    capture files.
2974                 */
2975
2976                 if (i->second->use_cnt() == 0 && i->second->length() > 0) {
2977                         dead_sources.push_back (i->second);
2978
2979                         /* remove this source from our own list to avoid us
2980                            adding it to the list of all sources below
2981                         */
2982
2983                         audio_sources.erase (i);
2984                 }
2985
2986                 i = tmp;
2987         }
2988
2989         /* Step 4: get rid of all regions in the region list that use any dead sources
2990            in case the sources themselves don't go away (they might be referenced in
2991            other snapshots).
2992         */
2993                 
2994         for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2995
2996                 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2997                         AudioRegionList::iterator tmp;
2998                         AudioRegion* ar;
2999
3000                         tmp = r;
3001                         ++tmp;
3002                         
3003                         ar = r->second;
3004
3005                         for (uint32_t n = 0; n < ar->n_channels(); ++n) {
3006                                 if (&ar->source (n) == (*i)) {
3007                                         /* this region is dead */
3008                                         remove_region (ar);
3009                                 }
3010                         }
3011                         
3012                         r = tmp;
3013                 }
3014         }
3015
3016         /* build a list of all the possible sound directories for the session */
3017
3018         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
3019
3020                 nexti = i;
3021                 ++nexti;
3022
3023                 sound_path += (*i).path;
3024                 sound_path += sound_dir_name;
3025
3026                 if (nexti != session_dirs.end()) {
3027                         sound_path += ':';
3028                 }
3029
3030                 i = nexti;
3031         }
3032         
3033         /* now do the same thing for the files that ended up in the sounds dir(s) 
3034            but are not referenced as sources in any snapshot.
3035         */
3036
3037         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
3038
3039         if (soundfiles == 0) {
3040                 return 0;
3041         }
3042
3043         /* find all sources, but don't use this snapshot because the
3044            state file on disk still references sources we may have already
3045            dropped.
3046         */
3047         
3048         find_all_sources_across_snapshots (all_sources, true);
3049
3050         /*  add our current source list
3051          */
3052         
3053         for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
3054                 AudioFileSource* fs;
3055                 
3056                 if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
3057                         all_sources.insert (fs->path());
3058                 } 
3059         }
3060
3061         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
3062
3063                 used = false;
3064                 spath = **x;
3065
3066                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
3067
3068                         if (spath == *i) {
3069                                 used = true;
3070                                 break;
3071                         }
3072
3073                 }
3074
3075                 if (!used) {
3076                         unused.push_back (spath);
3077                 }
3078         }
3079
3080         /* now try to move all unused files into the "dead_sounds" directory(ies) */
3081
3082         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
3083                 struct stat statbuf;
3084
3085                 rep.paths.push_back (*x);
3086                 if (stat ((*x).c_str(), &statbuf) == 0) {
3087                         rep.space += statbuf.st_size;
3088                 }
3089
3090                 string newpath;
3091                 
3092                 /* don't move the file across filesystems, just
3093                    stick it in the `dead_sound_dir_name' directory
3094                    on whichever filesystem it was already on.
3095                 */
3096
3097                 newpath = Glib::path_get_dirname (*x);
3098                 newpath = Glib::path_get_dirname (newpath);
3099
3100                 newpath += '/';
3101                 newpath += dead_sound_dir_name;
3102                 newpath += '/';
3103                 newpath += Glib::path_get_basename ((*x));
3104                 
3105                 if (access (newpath.c_str(), F_OK) == 0) {
3106                         
3107                         /* the new path already exists, try versioning */
3108                         
3109                         char buf[PATH_MAX+1];
3110                         int version = 1;
3111                         string newpath_v;
3112                         
3113                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
3114                         newpath_v = buf;
3115
3116                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
3117                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
3118                                 newpath_v = buf;
3119                         }
3120                         
3121                         if (version == 999) {
3122                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
3123                                                   newpath)
3124                                       << endmsg;
3125                         } else {
3126                                 newpath = newpath_v;
3127                         }
3128                         
3129                 } else {
3130                         
3131                         /* it doesn't exist, or we can't read it or something */
3132                         
3133                 }
3134
3135                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
3136                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
3137                                           (*x), newpath, strerror (errno))
3138                               << endmsg;
3139                         goto out;
3140                 }
3141                 
3142
3143                 /* see if there an easy to find peakfile for this file, and remove it.
3144                  */
3145
3146                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
3147                 peakpath += ".peak";
3148
3149                 if (access (peakpath.c_str(), W_OK) == 0) {
3150                         if (::unlink (peakpath.c_str()) != 0) {
3151                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
3152                                                   peakpath, _path, strerror (errno))
3153                                       << endmsg;
3154                                 /* try to back out */
3155                                 rename (newpath.c_str(), _path.c_str());
3156                                 goto out;
3157                         }
3158                 }
3159
3160         }
3161
3162         ret = 0;
3163
3164         /* dump the history list */
3165
3166         history.clear ();
3167
3168         /* save state so we don't end up a session file
3169            referring to non-existent sources.
3170         */
3171         
3172         save_state ("");
3173         save_history ("");
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 }
3304
3305
3306 int 
3307 Session::save_history (string snapshot_name)
3308 {
3309     XMLTree tree;
3310     string xml_path;
3311     string bak_path;
3312
3313     tree.set_root (&history.get_state());
3314
3315     if (snapshot_name.empty()) {
3316         snapshot_name = _current_snapshot_name;
3317     }
3318
3319     xml_path = _path + snapshot_name + ".history"; 
3320
3321     bak_path = xml_path + ".bak";
3322
3323     if ((access (xml_path.c_str(), F_OK) == 0) &&
3324         (rename (xml_path.c_str(), bak_path.c_str())))
3325     {
3326         error << _("could not backup old history file, current history not saved.") << endmsg;
3327         return -1;
3328     }
3329
3330     if (!tree.write (xml_path))
3331     {
3332         error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3333
3334         /* don't leave a corrupt file lying around if it is
3335          * possible to fix.
3336          */
3337
3338         if (unlink (xml_path.c_str())) 
3339         {
3340             error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3341         } else {
3342             if (rename (bak_path.c_str(), xml_path.c_str())) 
3343             {
3344                 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3345             }
3346         }
3347
3348         return -1;
3349     }
3350
3351     return 0;
3352 }