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