save keybindings to file used at startup; allow keybindings file to be cmdline-specif...
[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
1222         if (state_was_pending) {
1223                 save_state (_current_snapshot_name);
1224                 remove_pending_capture_state ();
1225                 state_was_pending = false;
1226         }
1227
1228         return 0;
1229
1230   out:
1231         return ret;
1232 }
1233
1234 int
1235 Session::load_routes (const XMLNode& node)
1236 {
1237         XMLNodeList nlist;
1238         XMLNodeConstIterator niter;
1239         RouteList new_routes;
1240
1241         nlist = node.children();
1242
1243         set_dirty();
1244
1245         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1246
1247                 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1248
1249                 if (route == 0) {
1250                         error << _("Session: cannot create Route from XML description.")                              << endmsg;
1251                         return -1;
1252                 }
1253
1254                 new_routes.push_back (route);
1255         }
1256
1257         add_routes (new_routes);
1258
1259         return 0;
1260 }
1261
1262 boost::shared_ptr<Route>
1263 Session::XMLRouteFactory (const XMLNode& node)
1264 {
1265         if (node.name() != "Route") {
1266                 return boost::shared_ptr<Route> ((Route*) 0);
1267         }
1268
1269         if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1270                 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1271                 return x;
1272         } else {
1273                 boost::shared_ptr<Route> x (new Route (*this, node));
1274                 return x;
1275         }
1276 }
1277
1278 int
1279 Session::load_regions (const XMLNode& node)
1280 {
1281         XMLNodeList nlist;
1282         XMLNodeConstIterator niter;
1283         boost::shared_ptr<AudioRegion> region;
1284
1285         nlist = node.children();
1286
1287         set_dirty();
1288
1289         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1290                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1291                         error << _("Session: cannot create Region from XML description.") << endmsg;
1292                 }
1293         }
1294
1295         return 0;
1296 }
1297
1298 boost::shared_ptr<AudioRegion>
1299 Session::XMLRegionFactory (const XMLNode& node, bool full)
1300 {
1301         const XMLProperty* prop;
1302         boost::shared_ptr<Source> source;
1303         boost::shared_ptr<AudioSource> as;
1304         SourceList sources;
1305         uint32_t nchans = 1;
1306         char buf[128];
1307         
1308         if (node.name() != X_("Region")) {
1309                 return boost::shared_ptr<AudioRegion>();
1310         }
1311
1312         if ((prop = node.property (X_("channels"))) != 0) {
1313                 nchans = atoi (prop->value().c_str());
1314         }
1315
1316
1317         if ((prop = node.property ("name")) == 0) {
1318                 cerr << "no name for this region\n";
1319                 abort ();
1320         }
1321         
1322         if ((prop = node.property (X_("source-0"))) == 0) {
1323                 if ((prop = node.property ("source")) == 0) {
1324                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1325                         return boost::shared_ptr<AudioRegion>();
1326                 }
1327         }
1328
1329         PBD::ID s_id (prop->value());
1330
1331         if ((source = source_by_id (s_id)) == 0) {
1332                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1333                 return boost::shared_ptr<AudioRegion>();
1334         }
1335         
1336         as = boost::dynamic_pointer_cast<AudioSource>(source);
1337         if (!as) {
1338                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1339                 return boost::shared_ptr<AudioRegion>();
1340         }
1341
1342         sources.push_back (as);
1343
1344         /* pickup other channels */
1345
1346         for (uint32_t n=1; n < nchans; ++n) {
1347                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1348                 if ((prop = node.property (buf)) != 0) {
1349                         
1350                         PBD::ID id2 (prop->value());
1351                         
1352                         if ((source = source_by_id (id2)) == 0) {
1353                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1354                                 return boost::shared_ptr<AudioRegion>();
1355                         }
1356                         
1357                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1358                         if (!as) {
1359                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1360                                 return boost::shared_ptr<AudioRegion>();
1361                         }
1362                         sources.push_back (as);
1363                 }
1364         }
1365         
1366         try {
1367                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1368                 return region;
1369                                                        
1370         }
1371
1372         catch (failed_constructor& err) {
1373                 return boost::shared_ptr<AudioRegion>();
1374         }
1375 }
1376
1377 XMLNode&
1378 Session::get_sources_as_xml ()
1379
1380 {
1381         XMLNode* node = new XMLNode (X_("Sources"));
1382         Glib::Mutex::Lock lm (audio_source_lock);
1383
1384         for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1385                 node->add_child_nocopy (i->second->get_state());
1386         }
1387
1388         /* XXX get MIDI and other sources here */
1389
1390         return *node;
1391 }
1392
1393 string
1394 Session::path_from_region_name (string name, string identifier)
1395 {
1396         char buf[PATH_MAX+1];
1397         uint32_t n;
1398         string dir = discover_best_sound_dir ();
1399
1400         for (n = 0; n < 999999; ++n) {
1401                 if (identifier.length()) {
1402                         snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(), 
1403                                   identifier.c_str(), n);
1404                 } else {
1405                         snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1406                 }
1407                 if (access (buf, F_OK) != 0) {
1408                         return buf;
1409                 }
1410         }
1411
1412         return "";
1413 }
1414         
1415
1416 int
1417 Session::load_sources (const XMLNode& node)
1418 {
1419         XMLNodeList nlist;
1420         XMLNodeConstIterator niter;
1421         boost::shared_ptr<Source> source;
1422
1423         nlist = node.children();
1424
1425         set_dirty();
1426
1427         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1428
1429                 if ((source = XMLSourceFactory (**niter)) == 0) {
1430                         error << _("Session: cannot create Source from XML description.") << endmsg;
1431                 }
1432         }
1433
1434         return 0;
1435 }
1436
1437 boost::shared_ptr<Source>
1438 Session::XMLSourceFactory (const XMLNode& node)
1439 {
1440         if (node.name() != "Source") {
1441                 return boost::shared_ptr<Source>();
1442         }
1443
1444         try {
1445                 return SourceFactory::create (*this, node);
1446         }
1447         
1448         catch (failed_constructor& err) {
1449                 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1450                 return boost::shared_ptr<Source>();
1451         }
1452 }
1453
1454 int
1455 Session::save_template (string template_name)
1456 {
1457         XMLTree tree;
1458         string xml_path, bak_path, template_path;
1459
1460         if (_state_of_the_state & CannotSave) {
1461                 return -1;
1462         }
1463
1464         DIR* dp;
1465         string dir = template_dir();
1466
1467         if ((dp = opendir (dir.c_str()))) {
1468                 closedir (dp);
1469         } else {
1470                 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1471                         error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1472                         return -1;
1473                 }
1474         }
1475
1476         tree.set_root (&get_template());
1477
1478         xml_path = dir;
1479         xml_path += template_name;
1480         xml_path += _template_suffix;
1481
1482         ifstream in(xml_path.c_str());
1483         
1484         if (in) {
1485                 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1486                 return -1;
1487         } else {
1488                 in.close();
1489         }
1490
1491         if (!tree.write (xml_path)) {
1492                 error << _("mix template not saved") << endmsg;
1493                 return -1;
1494         }
1495
1496         return 0;
1497 }
1498
1499 int
1500 Session::rename_template (string old_name, string new_name) 
1501 {
1502         string old_path = template_dir() + old_name + _template_suffix;
1503         string new_path = template_dir() + new_name + _template_suffix;
1504
1505         return rename (old_path.c_str(), new_path.c_str());
1506 }
1507
1508 int
1509 Session::delete_template (string name) 
1510 {
1511         string template_path = template_dir();
1512         template_path += name;
1513         template_path += _template_suffix;
1514
1515         return remove (template_path.c_str());
1516 }
1517
1518 void
1519 Session::refresh_disk_space ()
1520 {
1521 #if HAVE_SYS_VFS_H
1522         struct statfs statfsbuf;
1523         vector<space_and_path>::iterator i;
1524         Glib::Mutex::Lock lm (space_lock);
1525         double scale;
1526
1527         /* get freespace on every FS that is part of the session path */
1528
1529         _total_free_4k_blocks = 0;
1530         
1531         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1532                 statfs ((*i).path.c_str(), &statfsbuf);
1533
1534                 scale = statfsbuf.f_bsize/4096.0;
1535
1536                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1537                 _total_free_4k_blocks += (*i).blocks;
1538         }
1539 #endif
1540 }
1541
1542 int
1543 Session::ensure_sound_dir (string path, string& result)
1544 {
1545         string dead;
1546         string peak;
1547
1548         /* Ensure that the parent directory exists */
1549         
1550         if (g_mkdir_with_parents (path.c_str(), 0775)) {
1551                 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1552                 return -1;
1553         }
1554         
1555         /* Ensure that the sounds directory exists */
1556         
1557         result = path;
1558         result += '/';
1559         result += sound_dir_name;
1560         
1561         if (g_mkdir_with_parents (result.c_str(), 0775)) {
1562                 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1563                 return -1;
1564         }
1565
1566         dead = path;
1567         dead += '/';
1568         dead += dead_sound_dir_name;
1569         
1570         if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1571                 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1572                 return -1;
1573         }
1574
1575         peak = path;
1576         peak += '/';
1577         peak += peak_dir_name;
1578         
1579         if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1580                 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1581                 return -1;
1582         }
1583         
1584         /* callers expect this to be terminated ... */
1585                         
1586         result += '/';
1587         return 0;
1588 }       
1589
1590 string
1591 Session::discover_best_sound_dir (bool destructive)
1592 {
1593         vector<space_and_path>::iterator i;
1594         string result;
1595
1596         /* handle common case without system calls */
1597
1598         if (session_dirs.size() == 1) {
1599                 return sound_dir();
1600         }
1601
1602         /* OK, here's the algorithm we're following here:
1603            
1604         We want to select which directory to use for 
1605         the next file source to be created. Ideally,
1606         we'd like to use a round-robin process so as to
1607         get maximum performance benefits from splitting
1608         the files across multiple disks.
1609
1610         However, in situations without much diskspace, an
1611         RR approach may end up filling up a filesystem
1612         with new files while others still have space.
1613         Its therefore important to pay some attention to
1614         the freespace in the filesystem holding each
1615         directory as well. However, if we did that by
1616         itself, we'd keep creating new files in the file
1617         system with the most space until it was as full
1618         as all others, thus negating any performance
1619         benefits of this RAID-1 like approach.
1620
1621         So, we use a user-configurable space threshold. If
1622         there are at least 2 filesystems with more than this
1623         much space available, we use RR selection between them. 
1624         If not, then we pick the filesystem with the most space.
1625
1626         This gets a good balance between the two
1627         approaches.  
1628         */
1629         
1630         refresh_disk_space ();
1631         
1632         int free_enough = 0;
1633
1634         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1635                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1636                         free_enough++;
1637                 }
1638         }
1639
1640         if (free_enough >= 2) {
1641
1642                 bool found_it = false;
1643
1644                 /* use RR selection process, ensuring that the one
1645                    picked works OK.
1646                 */
1647
1648                 i = last_rr_session_dir;
1649
1650                 do {
1651                         if (++i == session_dirs.end()) {
1652                                 i = session_dirs.begin();
1653                         }
1654
1655                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1656                                 if (ensure_sound_dir ((*i).path, result) == 0) {
1657                                         last_rr_session_dir = i;
1658                                         found_it = true;
1659                                         break;
1660                                 }
1661                         }
1662
1663                 } while (i != last_rr_session_dir);
1664
1665                 if (!found_it) {
1666                         result = sound_dir();
1667                 }
1668
1669         } else {
1670
1671                 /* pick FS with the most freespace (and that
1672                    seems to actually work ...)
1673                 */
1674                 
1675                 vector<space_and_path> sorted;
1676                 space_and_path_ascending_cmp cmp;
1677
1678                 sorted = session_dirs;
1679                 sort (sorted.begin(), sorted.end(), cmp);
1680                 
1681                 for (i = sorted.begin(); i != sorted.end(); ++i) {
1682                         if (ensure_sound_dir ((*i).path, result) == 0) {
1683                                 last_rr_session_dir = i;
1684                                 break;
1685                         }
1686                 }
1687                 
1688                 /* if the above fails, fall back to the most simplistic solution */
1689                 
1690                 if (i == sorted.end()) {
1691                         return sound_dir();
1692                 } 
1693         }
1694
1695         return result;
1696 }
1697
1698 int
1699 Session::load_playlists (const XMLNode& node)
1700 {
1701         XMLNodeList nlist;
1702         XMLNodeConstIterator niter;
1703         boost::shared_ptr<Playlist> playlist;
1704
1705         nlist = node.children();
1706
1707         set_dirty();
1708
1709         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1710                 
1711                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1712                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1713                 }
1714         }
1715
1716         return 0;
1717 }
1718
1719 int
1720 Session::load_unused_playlists (const XMLNode& node)
1721 {
1722         XMLNodeList nlist;
1723         XMLNodeConstIterator niter;
1724         boost::shared_ptr<Playlist> playlist;
1725
1726         nlist = node.children();
1727
1728         set_dirty();
1729
1730         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1731                 
1732                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1733                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1734                         continue;
1735                 }
1736
1737                 // now manually untrack it
1738
1739                 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1740         }
1741
1742         return 0;
1743 }
1744
1745
1746 boost::shared_ptr<Playlist>
1747 Session::XMLPlaylistFactory (const XMLNode& node)
1748 {
1749         try {
1750                 return PlaylistFactory::create (*this, node);
1751         }
1752
1753         catch (failed_constructor& err) {
1754                 return boost::shared_ptr<Playlist>();
1755         }
1756 }
1757
1758 int
1759 Session::load_named_selections (const XMLNode& node)
1760 {
1761         XMLNodeList nlist;
1762         XMLNodeConstIterator niter;
1763         NamedSelection *ns;
1764
1765         nlist = node.children();
1766
1767         set_dirty();
1768
1769         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1770                 
1771                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1772                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1773                 }
1774         }
1775
1776         return 0;
1777 }
1778
1779 NamedSelection *
1780 Session::XMLNamedSelectionFactory (const XMLNode& node)
1781 {
1782         try {
1783                 return new NamedSelection (*this, node);
1784         }
1785
1786         catch (failed_constructor& err) {
1787                 return 0;
1788         }
1789 }
1790
1791 string
1792 Session::dead_sound_dir () const
1793 {
1794         string res = _path;
1795         res += dead_sound_dir_name;
1796         res += '/';
1797         return res;
1798 }
1799
1800 string
1801 Session::sound_dir (bool with_path) const
1802 {
1803         /* support old session structure */
1804
1805         struct stat statbuf;
1806         string old_nopath;
1807         string old_withpath;
1808
1809         old_nopath += old_sound_dir_name;
1810         old_nopath += '/';
1811         
1812         old_withpath = _path;
1813         old_withpath += old_sound_dir_name;
1814
1815         if (stat (old_withpath.c_str(), &statbuf) == 0) {
1816                 if (with_path)
1817                         return old_withpath;
1818                 
1819                 return old_nopath;
1820         }
1821
1822         string res;
1823
1824         if (with_path) {
1825                 res = _path;
1826         }
1827
1828         res += interchange_dir_name;
1829         res += '/';
1830         res += legalize_for_path (_name);
1831         res += '/';
1832         res += sound_dir_name;
1833
1834         return res;
1835 }
1836
1837 string
1838 Session::peak_dir () const
1839 {
1840         string res = _path;
1841         res += peak_dir_name;
1842         res += '/';
1843         return res;
1844 }
1845         
1846 string
1847 Session::automation_dir () const
1848 {
1849         string res = _path;
1850         res += "automation/";
1851         return res;
1852 }
1853
1854 string
1855 Session::template_dir ()
1856 {
1857         string path = get_user_ardour_path();
1858         path += "templates/";
1859
1860         return path;
1861 }
1862
1863 string
1864 Session::suffixed_search_path (string suffix, bool data)
1865 {
1866         string path;
1867
1868         path += get_user_ardour_path();
1869         if (path[path.length()-1] != ':') {
1870                 path += ':';
1871         }
1872
1873         if (data) {
1874                 path += get_system_data_path();
1875         } else {
1876                 path += get_system_module_path();
1877         }
1878
1879         vector<string> split_path;
1880         
1881         split (path, split_path, ':');
1882         path = "";
1883
1884         for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1885                 path += *i;
1886                 path += suffix;
1887                 path += '/';
1888                 
1889                 if (distance (i, split_path.end()) != 1) {
1890                         path += ':';
1891                 }
1892         }
1893                 
1894         return path;
1895 }
1896
1897 string
1898 Session::template_path ()
1899 {
1900         return suffixed_search_path (X_("templates"), true);
1901 }
1902
1903 string
1904 Session::control_protocol_path ()
1905 {
1906         return suffixed_search_path (X_("surfaces"), false);
1907 }
1908
1909 int
1910 Session::load_connections (const XMLNode& node)
1911 {
1912         XMLNodeList nlist = node.children();
1913         XMLNodeConstIterator niter;
1914
1915         set_dirty();
1916
1917         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1918                 if ((*niter)->name() == "InputConnection") {
1919                         add_connection (new ARDOUR::InputConnection (**niter));
1920                 } else if ((*niter)->name() == "OutputConnection") {
1921                         add_connection (new ARDOUR::OutputConnection (**niter));
1922                 } else {
1923                         error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1924                         return -1;
1925                 }
1926         }
1927
1928         return 0;
1929 }                               
1930
1931 int
1932 Session::load_edit_groups (const XMLNode& node)
1933 {
1934         return load_route_groups (node, true);
1935 }
1936
1937 int
1938 Session::load_mix_groups (const XMLNode& node)
1939 {
1940         return load_route_groups (node, false);
1941 }
1942
1943 int
1944 Session::load_route_groups (const XMLNode& node, bool edit)
1945 {
1946         XMLNodeList nlist = node.children();
1947         XMLNodeConstIterator niter;
1948         RouteGroup* rg;
1949
1950         set_dirty();
1951
1952         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1953                 if ((*niter)->name() == "RouteGroup") {
1954                         if (edit) {
1955                                 rg = add_edit_group ("");
1956                                 rg->set_state (**niter);
1957                         } else {
1958                                 rg = add_mix_group ("");
1959                                 rg->set_state (**niter);
1960                         }
1961                 }
1962         }
1963         
1964         return 0;
1965 }                               
1966
1967 static bool
1968 state_file_filter (const string &str, void *arg)
1969 {
1970         return (str.length() > strlen(Session::statefile_suffix()) &&
1971                 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1972 }
1973
1974 struct string_cmp {
1975         bool operator()(const string* a, const string* b) {
1976                 return *a < *b;
1977         }
1978 };
1979
1980 static string*
1981 remove_end(string* state)
1982 {
1983         string statename(*state);
1984         
1985         string::size_type start,end;
1986         if ((start = statename.find_last_of ('/')) != string::npos) {
1987                 statename = statename.substr (start+1);
1988         }
1989                 
1990         if ((end = statename.rfind(".ardour")) == string::npos) {
1991                 end = statename.length();
1992         }
1993
1994         return new string(statename.substr (0, end));
1995 }
1996
1997 vector<string *> *
1998 Session::possible_states (string path) 
1999 {
2000         PathScanner scanner;
2001         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2002         
2003         transform(states->begin(), states->end(), states->begin(), remove_end);
2004         
2005         string_cmp cmp;
2006         sort (states->begin(), states->end(), cmp);
2007         
2008         return states;
2009 }
2010
2011 vector<string *> *
2012 Session::possible_states () const
2013 {
2014         return possible_states(_path);
2015 }
2016
2017 void
2018 Session::auto_save()
2019 {
2020         save_state (_current_snapshot_name);
2021 }
2022
2023 RouteGroup *
2024 Session::add_edit_group (string name)
2025 {
2026         RouteGroup* rg = new RouteGroup (*this, name);
2027         edit_groups.push_back (rg);
2028         edit_group_added (rg); /* EMIT SIGNAL */
2029         set_dirty();
2030         return rg;
2031 }
2032
2033 RouteGroup *
2034 Session::add_mix_group (string name)
2035 {
2036         RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2037         mix_groups.push_back (rg);
2038         mix_group_added (rg); /* EMIT SIGNAL */
2039         set_dirty();
2040         return rg;
2041 }
2042
2043 void
2044 Session::remove_edit_group (RouteGroup& rg)
2045 {
2046         list<RouteGroup*>::iterator i;
2047
2048         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2049                 (*i)->apply (&Route::drop_edit_group, this);
2050                 edit_groups.erase (i);
2051                 edit_group_removed (); /* EMIT SIGNAL */
2052         }
2053
2054         delete &rg;
2055 }
2056
2057 void
2058 Session::remove_mix_group (RouteGroup& rg)
2059 {
2060         list<RouteGroup*>::iterator i;
2061
2062         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2063                 (*i)->apply (&Route::drop_mix_group, this);
2064                 mix_groups.erase (i);
2065                 mix_group_removed (); /* EMIT SIGNAL */
2066         }
2067
2068         delete &rg;
2069 }
2070
2071 RouteGroup *
2072 Session::mix_group_by_name (string name)
2073 {
2074         list<RouteGroup *>::iterator i;
2075
2076         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2077                 if ((*i)->name() == name) {
2078                         return* i;
2079                 }
2080         }
2081         return 0;
2082 }
2083
2084 RouteGroup *
2085 Session::edit_group_by_name (string name)
2086 {
2087         list<RouteGroup *>::iterator i;
2088
2089         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2090                 if ((*i)->name() == name) {
2091                         return* i;
2092                 }
2093         }
2094         return 0;
2095 }
2096
2097 void
2098 Session::begin_reversible_command (string name)
2099 {
2100         current_trans = new UndoTransaction;
2101         current_trans->set_name (name);
2102 }
2103
2104 void
2105 Session::commit_reversible_command (Command *cmd)
2106 {
2107         struct timeval now;
2108
2109         if (cmd) {
2110                 current_trans->add_command (cmd);
2111         }
2112
2113         gettimeofday (&now, 0);
2114         current_trans->set_timestamp (now);
2115
2116         _history.add (current_trans);
2117 }
2118
2119 Session::GlobalRouteBooleanState 
2120 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2121 {
2122         GlobalRouteBooleanState s;
2123         boost::shared_ptr<RouteList> r = routes.reader ();
2124
2125         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2126                 if (!(*i)->hidden()) {
2127                         RouteBooleanState v;
2128                         
2129                         v.first =* i;
2130                         Route* r = (*i).get();
2131                         v.second = (r->*method)();
2132                         
2133                         s.push_back (v);
2134                 }
2135         }
2136
2137         return s;
2138 }
2139
2140 Session::GlobalRouteMeterState
2141 Session::get_global_route_metering ()
2142 {
2143         GlobalRouteMeterState s;
2144         boost::shared_ptr<RouteList> r = routes.reader ();
2145
2146         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2147                 if (!(*i)->hidden()) {
2148                         RouteMeterState v;
2149                         
2150                         v.first =* i;
2151                         v.second = (*i)->meter_point();
2152                         
2153                         s.push_back (v);
2154                 }
2155         }
2156
2157         return s;
2158 }
2159
2160 void
2161 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2162 {
2163         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2164                 i->first->set_meter_point (i->second, arg);
2165         }
2166 }
2167
2168 void
2169 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2170 {
2171         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2172                 Route* r = i->first.get();
2173                 (r->*method) (i->second, arg);
2174         }
2175 }
2176
2177 void
2178 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2179 {
2180         set_global_route_boolean (s, &Route::set_mute, src);
2181 }
2182
2183 void
2184 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2185 {
2186         set_global_route_boolean (s, &Route::set_solo, src);
2187 }
2188
2189 void
2190 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2191 {
2192         set_global_route_boolean (s, &Route::set_record_enable, src);
2193 }
2194
2195 #if 0
2196 UndoAction
2197 Session::global_mute_memento (void* src)
2198 {
2199         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2200 }
2201
2202 UndoAction
2203 Session::global_metering_memento (void* src)
2204 {
2205         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2206 }
2207
2208 UndoAction
2209 Session::global_solo_memento (void* src)
2210 {
2211         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2212 }
2213
2214 UndoAction
2215 Session::global_record_enable_memento (void* src)
2216 {
2217         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2218 }
2219 #endif
2220
2221 static bool
2222 template_filter (const string &str, void *arg)
2223 {
2224         return (str.length() > strlen(Session::template_suffix()) &&
2225                 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2226 }
2227
2228 void
2229 Session::get_template_list (list<string> &template_names)
2230 {
2231         vector<string *> *templates;
2232         PathScanner scanner;
2233         string path;
2234
2235         path = template_path ();
2236
2237         templates = scanner (path, template_filter, 0, false, true);
2238         
2239         vector<string*>::iterator i;
2240         for (i = templates->begin(); i != templates->end(); ++i) {
2241                 string fullpath = *(*i);
2242                 int start, end;
2243
2244                 start = fullpath.find_last_of ('/') + 1;
2245                 if ((end = fullpath.find_last_of ('.')) <0) {
2246                         end = fullpath.length();
2247                 }
2248                 
2249                 template_names.push_back(fullpath.substr(start, (end-start)));
2250         }
2251 }
2252
2253 int
2254 Session::read_favorite_dirs (FavoriteDirs & favs)
2255 {
2256         string path = get_user_ardour_path();
2257         path += "/favorite_dirs";
2258
2259         ifstream fav (path.c_str());
2260
2261         favs.clear();
2262         
2263         if (!fav) {
2264                 if (errno != ENOENT) {
2265                         //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2266                         return -1;
2267                 } else {
2268                         return 1;
2269                 }
2270         }
2271
2272         while (true) {
2273
2274                 string newfav;
2275
2276                 getline(fav, newfav);
2277
2278                 if (!fav.good()) {
2279                         break;
2280                 }
2281
2282                 favs.push_back (newfav);
2283         }
2284
2285         return 0;
2286 }
2287
2288 int
2289 Session::write_favorite_dirs (FavoriteDirs & favs)
2290 {
2291         string path = get_user_ardour_path();
2292         path += "/favorite_dirs";
2293
2294         ofstream fav (path.c_str());
2295
2296         if (!fav) {
2297                 return -1;
2298         }
2299
2300         for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2301                 fav << (*i) << endl;
2302         }
2303         
2304         return 0;
2305 }
2306
2307 static bool
2308 accept_all_non_peak_files (const string& path, void *arg)
2309 {
2310         return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2311 }
2312
2313 static bool
2314 accept_all_state_files (const string& path, void *arg)
2315 {
2316         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2317 }
2318
2319 int 
2320 Session::find_all_sources (string path, set<string>& result)
2321 {
2322         XMLTree tree;
2323         XMLNode* node;
2324
2325         if (!tree.read (path)) {
2326                 return -1;
2327         }
2328
2329         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2330                 return -2;
2331         }
2332
2333         XMLNodeList nlist;
2334         XMLNodeConstIterator niter;
2335
2336         nlist = node->children();
2337
2338         set_dirty();
2339
2340         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2341                 
2342                 XMLProperty* prop;
2343
2344                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2345                         continue;
2346                 }
2347
2348                 if (prop->value()[0] == '/') {
2349                         /* external file, ignore */
2350                         continue;
2351                 }
2352
2353                 string path = _path; /* /-terminated */
2354                 path += sound_dir_name;
2355                 path += '/';
2356                 path += prop->value();
2357
2358                 result.insert (path);
2359         }
2360
2361         return 0;
2362 }
2363
2364 int
2365 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2366 {
2367         PathScanner scanner;
2368         vector<string*>* state_files;
2369         string ripped;
2370         string this_snapshot_path;
2371
2372         result.clear ();
2373
2374         ripped = _path;
2375
2376         if (ripped[ripped.length()-1] == '/') {
2377                 ripped = ripped.substr (0, ripped.length() - 1);
2378         }
2379
2380         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2381         
2382         if (state_files == 0) {
2383                 /* impossible! */
2384                 return 0;
2385         }
2386
2387         this_snapshot_path = _path;
2388         this_snapshot_path += _current_snapshot_name;
2389         this_snapshot_path += _statefile_suffix;
2390
2391         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2392
2393                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2394                         continue;
2395                 }
2396
2397                 if (find_all_sources (**i, result) < 0) {
2398                         return -1;
2399                 }
2400         }
2401
2402         return 0;
2403 }
2404
2405 struct RegionCounter {
2406     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2407     AudioSourceList::iterator iter;
2408     boost::shared_ptr<Region> region;
2409     uint32_t count;
2410     
2411     RegionCounter() : count (0) {}
2412 };
2413
2414 int
2415 Session::cleanup_sources (Session::cleanup_report& rep)
2416 {
2417         typedef map<boost::shared_ptr<Source>, RegionCounter> SourceRegionMap;
2418         SourceRegionMap dead_sources;
2419
2420         vector<boost::shared_ptr<Playlist> > playlists_tbd;
2421         PathScanner scanner;
2422         string sound_path;
2423         vector<space_and_path>::iterator i;
2424         vector<space_and_path>::iterator nexti;
2425         vector<string*>* soundfiles;
2426         vector<string> unused;
2427         set<string> all_sources;
2428         bool used;
2429         string spath;
2430         int ret = -1;
2431                 
2432         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2433         
2434         /* step 1: consider deleting all unused playlists */
2435
2436         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2437                 int status;
2438
2439                 status = AskAboutPlaylistDeletion (*x);
2440
2441                 switch (status) {
2442                 case -1:
2443                         ret = 0;
2444                         goto out;
2445                         break;
2446
2447                 case 0:
2448                         playlists_tbd.push_back (*x);
2449                         break;
2450
2451                 default:
2452                         /* leave it alone */
2453                         break;
2454                 }
2455         }
2456
2457         /* now delete any that were marked for deletion */
2458
2459         for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2460                 (*x)->drop_references ();
2461         }
2462
2463         playlists_tbd.clear ();
2464
2465         /* step 2: find all un-referenced sources */
2466
2467         rep.paths.clear ();
2468         rep.space = 0;
2469
2470         for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2471                 
2472                 /* we expect the use_count() to be at least 2: one for the shared_ptr<> in the sources
2473                    list and one for the iterator. if its used by 1 region, we'd expect a value of 3.
2474
2475                    do not bother with files that are zero size, otherwise we remove the current "nascent"
2476                    capture files.
2477                 */
2478
2479                 if (i->second.use_count() <= 3 && i->second->length() > 0) {
2480
2481                         pair<boost::shared_ptr<Source>, RegionCounter> newpair;
2482
2483                         newpair.first = i->second;
2484                         newpair.second.iter = i;
2485
2486                         dead_sources.insert (newpair);
2487                 } 
2488         }
2489
2490         /* Search the region list to find out the state of the supposedly unreferenced regions 
2491          */
2492
2493         for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2494
2495                 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ++r) {
2496                         
2497                         boost::shared_ptr<AudioRegion> ar = r->second;
2498
2499                         for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2500
2501                                 if (ar->source (n) == i->first) {
2502                                         
2503                                         /* this region uses this source */
2504
2505                                         i->second.region = ar;
2506                                         i->second.count++;
2507
2508                                         if (i->second.count > 1) {
2509                                                 break;
2510                                         }
2511                                 }
2512                         }
2513                 }
2514         }
2515
2516         /* next, get rid of all regions in the region list that use any dead sources
2517            in case the sources themselves don't go away (they might be referenced in
2518            other snapshots).
2519
2520            this is also where we remove the apparently unused sources from our source
2521            list. this doesn't rename them or delete them, but it means they are
2522            potential candidates for renaming after we find all soundfiles
2523            and scan for use across all snapshots (including this one).
2524         */
2525         
2526         for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end(); ) {
2527
2528                 SourceRegionMap::iterator tmp;
2529
2530                 tmp = i;
2531                 ++tmp;
2532
2533                 if (i->second.count == 0) {
2534
2535                         /* no regions use this source */
2536
2537                         /* remove this source from our own list to avoid us
2538                            adding it to the list of all sources below
2539                         */
2540
2541                         audio_sources.erase (i->second.iter);
2542
2543                 } else if (i->second.count == 1) {
2544
2545                         /* the use_count for the source was 3. this means that there is only reference to it in addition to the source
2546                            list and an iterator used to traverse that list. since there is a single region using the source, that
2547                            must be the extra reference. this implies that its a whole-file region
2548                            with no children, so remove the region and the source.
2549                         */
2550
2551                         remove_region (i->second.region);
2552
2553                         /* remove this source from our own list to avoid us
2554                            adding it to the list of all sources below
2555                         */
2556
2557                         audio_sources.erase (i->second.iter);
2558
2559                 } else {
2560                         /* more than one region uses this source, do not remove it */
2561                         dead_sources.erase (i);
2562                 }
2563
2564                 i = tmp;
2565         }
2566
2567         /* build a list of all the possible sound directories for the session */
2568
2569         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2570
2571                 nexti = i;
2572                 ++nexti;
2573
2574                 sound_path += (*i).path;
2575                 sound_path += sound_dir (false);
2576
2577                 if (nexti != session_dirs.end()) {
2578                         sound_path += ':';
2579                 }
2580
2581                 i = nexti;
2582         }
2583
2584         /* now do the same thing for the files that ended up in the sounds dir(s) 
2585            but are not referenced as sources in any snapshot.
2586         */
2587
2588         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2589
2590         if (soundfiles == 0) {
2591                 return 0;
2592         }
2593
2594         /* find all sources, but don't use this snapshot because the
2595            state file on disk still references sources we may have already
2596            dropped.
2597         */
2598         
2599         find_all_sources_across_snapshots (all_sources, true);
2600
2601         /*  add our current source list
2602          */
2603         
2604         for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2605                 boost::shared_ptr<AudioFileSource> fs;
2606                 
2607                 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2608                         all_sources.insert (fs->path());
2609                 } 
2610         }
2611
2612         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2613
2614                 used = false;
2615                 spath = **x;
2616
2617                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2618
2619                         if (spath == *i) {
2620                                 used = true;
2621                                 break;
2622                         }
2623
2624                 }
2625
2626                 if (!used) {
2627                         unused.push_back (spath);
2628                 }
2629         }
2630
2631         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2632
2633         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2634                 struct stat statbuf;
2635
2636                 rep.paths.push_back (*x);
2637                 if (stat ((*x).c_str(), &statbuf) == 0) {
2638                         rep.space += statbuf.st_size;
2639                 }
2640
2641                 string newpath;
2642                 
2643                 /* don't move the file across filesystems, just
2644                    stick it in the `dead_sound_dir_name' directory
2645                    on whichever filesystem it was already on.
2646                 */
2647
2648                 /* XXX this is a hack ... go up 4 levels */
2649
2650                 newpath = Glib::path_get_dirname (*x);      // "audiofiles" 
2651                 newpath = Glib::path_get_dirname (newpath); // "session-name"
2652                 newpath = Glib::path_get_dirname (newpath); // "interchange"
2653                 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2654
2655                 newpath += '/';
2656                 newpath += dead_sound_dir_name;
2657                 newpath += '/';
2658                 newpath += Glib::path_get_basename ((*x));
2659                 
2660                 if (access (newpath.c_str(), F_OK) == 0) {
2661                         
2662                         /* the new path already exists, try versioning */
2663                         
2664                         char buf[PATH_MAX+1];
2665                         int version = 1;
2666                         string newpath_v;
2667                         
2668                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2669                         newpath_v = buf;
2670
2671                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2672                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2673                                 newpath_v = buf;
2674                         }
2675                         
2676                         if (version == 999) {
2677                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2678                                                   newpath)
2679                                       << endmsg;
2680                         } else {
2681                                 newpath = newpath_v;
2682                         }
2683                         
2684                 } else {
2685                         
2686                         /* it doesn't exist, or we can't read it or something */
2687                         
2688                 }
2689
2690                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2691                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2692                                           (*x), newpath, strerror (errno))
2693                               << endmsg;
2694                         goto out;
2695                 }
2696                 
2697
2698                 /* see if there an easy to find peakfile for this file, and remove it.
2699                  */
2700
2701                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2702                 peakpath += ".peak";
2703
2704                 if (access (peakpath.c_str(), W_OK) == 0) {
2705                         if (::unlink (peakpath.c_str()) != 0) {
2706                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2707                                                   peakpath, _path, strerror (errno))
2708                                       << endmsg;
2709                                 /* try to back out */
2710                                 rename (newpath.c_str(), _path.c_str());
2711                                 goto out;
2712                         }
2713                 }
2714         }
2715
2716         ret = 0;
2717
2718         /* dump the history list */
2719
2720         _history.clear ();
2721
2722         /* save state so we don't end up a session file
2723            referring to non-existent sources.
2724         */
2725         
2726         save_state ("");
2727
2728   out:
2729         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2730         return ret;
2731 }
2732
2733 int
2734 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2735 {
2736         vector<space_and_path>::iterator i;
2737         string dead_sound_dir;
2738         struct dirent* dentry;
2739         struct stat statbuf;
2740         DIR* dead;
2741
2742         rep.paths.clear ();
2743         rep.space = 0;
2744
2745         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2746                 
2747                 dead_sound_dir = (*i).path;
2748                 dead_sound_dir += dead_sound_dir_name;
2749
2750                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2751                         continue;
2752                 }
2753
2754                 while ((dentry = readdir (dead)) != 0) {
2755
2756                         /* avoid '.' and '..' */
2757                         
2758                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
2759                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2760                                 continue;
2761                         }
2762
2763                         string fullpath;
2764
2765                         fullpath = dead_sound_dir;
2766                         fullpath += '/';
2767                         fullpath += dentry->d_name;
2768
2769                         if (stat (fullpath.c_str(), &statbuf)) {
2770                                 continue;
2771                         }
2772
2773                         if (!S_ISREG (statbuf.st_mode)) {
2774                                 continue;
2775                         }
2776
2777                         if (unlink (fullpath.c_str())) {
2778                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2779                                                   fullpath, strerror (errno))
2780                                       << endmsg;
2781                         }
2782
2783                         rep.paths.push_back (dentry->d_name);
2784                         rep.space += statbuf.st_size;
2785                 }
2786
2787                 closedir (dead);
2788                 
2789         }
2790
2791         return 0;
2792 }
2793
2794 void
2795 Session::set_dirty ()
2796 {
2797         bool was_dirty = dirty();
2798
2799         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2800
2801         if (!was_dirty) {
2802                 DirtyChanged(); /* EMIT SIGNAL */
2803         }
2804 }
2805
2806
2807 void
2808 Session::set_clean ()
2809 {
2810         bool was_dirty = dirty();
2811         
2812         _state_of_the_state = Clean;
2813
2814         if (was_dirty) {
2815                 DirtyChanged(); /* EMIT SIGNAL */
2816         }
2817 }
2818
2819 void
2820 Session::set_deletion_in_progress ()
2821 {
2822         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2823 }
2824
2825 void
2826 Session::add_controllable (Controllable* c)
2827 {
2828         Glib::Mutex::Lock lm (controllables_lock);
2829         controllables.insert (c);
2830 }
2831
2832 void
2833 Session::remove_controllable (Controllable* c)
2834 {
2835         if (_state_of_the_state | Deletion) {
2836                 return;
2837         }
2838
2839         Glib::Mutex::Lock lm (controllables_lock);
2840
2841         Controllables::iterator x = controllables.find (c);
2842
2843         if (x != controllables.end()) {
2844                 controllables.erase (x);
2845         }
2846 }       
2847
2848 Controllable*
2849 Session::controllable_by_id (const PBD::ID& id)
2850 {
2851         Glib::Mutex::Lock lm (controllables_lock);
2852         
2853         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2854                 if ((*i)->id() == id) {
2855                         return *i;
2856                 }
2857         }
2858
2859         return 0;
2860 }
2861
2862 void 
2863 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2864 {
2865         Stateful::add_instant_xml (node, dir);
2866         Config->add_instant_xml (node, get_user_ardour_path());
2867 }
2868
2869
2870 int 
2871 Session::save_history (string snapshot_name)
2872 {
2873     XMLTree tree;
2874     string xml_path;
2875     string bak_path;
2876
2877     tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2878
2879     if (snapshot_name.empty()) {
2880         snapshot_name = _current_snapshot_name;
2881     }
2882
2883     xml_path = _path + snapshot_name + ".history"; 
2884
2885     bak_path = xml_path + ".bak";
2886
2887     if ((access (xml_path.c_str(), F_OK) == 0) &&
2888         (rename (xml_path.c_str(), bak_path.c_str())))
2889     {
2890         error << _("could not backup old history file, current history not saved.") << endmsg;
2891         return -1;
2892     }
2893
2894     cerr << "actually writing history\n";
2895
2896     if (!tree.write (xml_path))
2897     {
2898         error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2899
2900         /* don't leave a corrupt file lying around if it is
2901          * possible to fix.
2902          */
2903
2904         if (unlink (xml_path.c_str())) {
2905                 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2906         } else {
2907                 if (rename (bak_path.c_str(), xml_path.c_str())) 
2908                 {
2909                         error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2910                 }
2911         }
2912
2913         return -1;
2914     }
2915
2916     return 0;
2917 }
2918
2919 int
2920 Session::restore_history (string snapshot_name)
2921 {
2922     XMLTree tree;
2923     string xmlpath;
2924
2925     if (snapshot_name.empty()) {
2926             snapshot_name = _current_snapshot_name;
2927     }
2928
2929     /* read xml */
2930     xmlpath = _path + snapshot_name + ".history";
2931     cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2932
2933     if (access (xmlpath.c_str(), F_OK)) {
2934             info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2935             return 1;
2936     }
2937
2938     if (!tree.read (xmlpath)) {
2939             error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2940             return -1;
2941     }
2942
2943     /* replace history */
2944     _history.clear();
2945
2946     for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2947             
2948             XMLNode *t = *it;
2949             UndoTransaction* ut = new UndoTransaction ();
2950             struct timeval tv;
2951             
2952             ut->set_name(t->property("name")->value());
2953             stringstream ss(t->property("tv_sec")->value());
2954             ss >> tv.tv_sec;
2955             ss.str(t->property("tv_usec")->value());
2956             ss >> tv.tv_usec;
2957             ut->set_timestamp(tv);
2958             
2959             for (XMLNodeConstIterator child_it  = t->children().begin();
2960                  child_it != t->children().end();
2961                  child_it++)
2962             {
2963                     XMLNode *n = *child_it;
2964                     Command *c;
2965         
2966                     if (n->name() == "MementoCommand" ||
2967                         n->name() == "MementoUndoCommand" ||
2968                         n->name() == "MementoRedoCommand") {
2969
2970                             if ((c = memento_command_factory(n))) {
2971                                     ut->add_command(c);
2972                             }
2973                             
2974                     } else if (n->name() == "GlobalRecordEnableStateCommand" ||
2975                                n->name() == "GlobalSoloStateCommand" || 
2976                                n->name() == "GlobalMuteStateCommand") {
2977
2978                             if ((c = global_state_command_factory (n))) {
2979                                     ut->add_command (c);
2980                             }
2981                             
2982                     } else {
2983
2984                             error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2985                     }
2986             }
2987
2988             _history.add (ut);
2989     }
2990
2991     return 0;
2992 }
2993
2994 void
2995 Session::config_changed (const char* parameter_name)
2996 {
2997 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2998
2999         if (PARAM_IS ("seamless-loop")) {
3000                 
3001         } else if (PARAM_IS ("rf-speed")) {
3002                 
3003         } else if (PARAM_IS ("auto-loop")) {
3004                 
3005         } else if (PARAM_IS ("auto-input")) {
3006
3007                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3008                         /* auto-input only makes a difference if we're rolling */
3009                         
3010                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3011                         
3012                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3013                                 if ((*i)->record_enabled ()) {
3014                                         //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
3015                                         (*i)->monitor_input (!Config->get_auto_input());
3016                                 }
3017                         }
3018                 }
3019
3020         } else if (PARAM_IS ("punch-in")) {
3021
3022                 Location* location;
3023                 
3024                 if ((location = _locations.auto_punch_location()) != 0) {
3025                         
3026                         if (Config->get_punch_in ()) {
3027                                 replace_event (Event::PunchIn, location->start());
3028                         } else {
3029                                 remove_event (location->start(), Event::PunchIn);
3030                         }
3031                 }
3032                 
3033         } else if (PARAM_IS ("punch-out")) {
3034
3035                 Location* location;
3036                 
3037                 if ((location = _locations.auto_punch_location()) != 0) {
3038                         
3039                         if (Config->get_punch_out()) {
3040                                 replace_event (Event::PunchOut, location->end());
3041                         } else {
3042                                 clear_events (Event::PunchOut);
3043                         }
3044                 }
3045
3046         } else if (PARAM_IS ("edit-mode")) {
3047
3048                 Glib::Mutex::Lock lm (playlist_lock);
3049                 
3050                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3051                         (*i)->set_edit_mode (Config->get_edit_mode ());
3052                 }
3053
3054         } else if (PARAM_IS ("use-video-sync")) {
3055
3056                 if (transport_stopped()) {
3057                         if (Config->get_use_video_sync()) {
3058                                 waiting_for_sync_offset = true;
3059                         }
3060                 }
3061
3062         } else if (PARAM_IS ("mmc-control")) {
3063
3064                 poke_midi_thread ();
3065
3066         } else if (PARAM_IS ("midi-control")) {
3067                 
3068                 poke_midi_thread ();
3069
3070         } else if (PARAM_IS ("raid-path")) {
3071
3072                 setup_raid_path (Config->get_raid_path());
3073
3074         } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
3075
3076                 sync_time_vars ();
3077
3078         } else if (PARAM_IS ("video-pullup")) {
3079
3080                 sync_time_vars ();
3081
3082         } else if (PARAM_IS ("seamless-loop")) {
3083
3084                 if (play_loop && transport_rolling()) {
3085                         // to reset diskstreams etc
3086                         request_play_loop (true);
3087                 }
3088
3089         } else if (PARAM_IS ("rf-speed")) {
3090
3091                 cumulative_rf_motion = 0;
3092                 reset_rf_scale (0);
3093
3094         } else if (PARAM_IS ("click-sound")) {
3095
3096                 setup_click_sounds (1);
3097
3098         } else if (PARAM_IS ("click-emphasis-sound")) {
3099
3100                 setup_click_sounds (-1);
3101
3102         } else if (PARAM_IS ("clicking")) {
3103
3104                 if (Config->get_clicking()) {
3105                         if (_click_io && click_data) { // don't require emphasis data
3106                                 _clicking = true;
3107                         }
3108                 } else {
3109                         _clicking = false;
3110                 }
3111
3112         } else if (PARAM_IS ("send-mtc")) {
3113                 
3114                 /* only set the internal flag if we have
3115                    a port.
3116                 */
3117                 
3118                 if (_mtc_port != 0) {
3119                         session_send_mtc = Config->get_send_mtc();
3120                         if (session_send_mtc) {
3121                                 /* mark us ready to send */
3122                                 next_quarter_frame_to_send = 0;
3123                         }
3124                 }
3125
3126         } else if (PARAM_IS ("send-mmc")) {
3127                 
3128                 /* only set the internal flag if we have
3129                    a port.
3130                 */
3131                 
3132                 if (_mmc_port != 0) {
3133                         session_send_mmc = Config->get_send_mmc();
3134                 }
3135
3136         } else if (PARAM_IS ("midi-feedback")) {
3137                 
3138                 /* only set the internal flag if we have
3139                    a port.
3140                 */
3141                 
3142                 if (_mtc_port != 0) {
3143                         session_midi_feedback = Config->get_midi_feedback();
3144                 }
3145
3146         } else if (PARAM_IS ("jack-time-master")) {
3147
3148                 engine().reset_timebase ();
3149
3150         } else if (PARAM_IS ("native-file-header-format")) {
3151
3152                 if (!first_file_header_format_reset) {
3153                         reset_native_file_format ();
3154                 }
3155
3156                 first_file_header_format_reset = false;
3157
3158         } else if (PARAM_IS ("native-file-data-format")) {
3159
3160                 if (!first_file_data_format_reset) {
3161                         reset_native_file_format ();
3162                 }
3163
3164                 first_file_data_format_reset = false;
3165         }
3166                 
3167         set_dirty ();
3168                    
3169 #undef PARAM_IS
3170
3171 }