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