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