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