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