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