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