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