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