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