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