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