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