move all destructive functionality into SndFileSource as a mode, and drop Destructive...
[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         SndFileSource::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         AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
244
245         Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
246
247         IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
248
249         /* stop IO objects from doing stuff until we're ready for them */
250
251         IO::disable_panners ();
252         IO::disable_ports ();
253         IO::disable_connecting ();
254 }
255
256 int
257 Session::second_stage_init (bool new_session)
258 {
259         AudioFileSource::set_peak_dir (peak_dir());
260
261         if (!new_session) {
262                 if (load_state (_current_snapshot_name)) {
263                         return -1;
264                 }
265                 remove_empty_sounds ();
266         }
267
268         if (start_butler_thread()) {
269                 return -1;
270         }
271
272         if (start_midi_thread ()) {
273                 return -1;
274         }
275
276         // set_state() will call setup_raid_path(), but if it's a new session we need
277         // to call setup_raid_path() here.
278         if (state_tree) {
279                 if (set_state (*state_tree->root())) {
280                         return -1;
281                 }
282         } else {
283                 setup_raid_path(_path);
284         }
285
286         /* we can't save till after ::when_engine_running() is called,
287            because otherwise we save state with no connections made.
288            therefore, we reset _state_of_the_state because ::set_state()
289            will have cleared it.
290
291            we also have to include Loading so that any events that get
292            generated between here and the end of ::when_engine_running()
293            will be processed directly rather than queued.
294         */
295
296         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
297
298         // set_auto_input (true);
299         _locations.changed.connect (mem_fun (this, &Session::locations_changed));
300         _locations.added.connect (mem_fun (this, &Session::locations_added));
301         setup_click_sounds (0);
302         setup_midi_control ();
303
304         /* Pay attention ... */
305
306         _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
307         _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
308
309         if (_engine.running()) {
310                 when_engine_running();
311         } else {
312                 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
313         }
314
315         send_full_time_code ();
316         _engine.transport_locate (0);
317         deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
318         deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
319
320         ControlProtocolManager::instance().set_session (*this);
321
322         if (new_session) {
323                 _end_location_is_free = true;
324         } else {
325                 _end_location_is_free = false;
326         }
327         
328         return 0;
329 }
330
331 string
332 Session::raid_path () const
333 {
334         string path;
335
336         for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
337                 path += (*i).path;
338                 path += ':';
339         }
340         
341         return path.substr (0, path.length() - 1); // drop final colon
342 }
343
344 void
345 Session::setup_raid_path (string path)
346 {
347         string::size_type colon;
348         string remaining;
349         space_and_path sp;
350         string fspath;
351         string::size_type len = path.length();
352         int colons;
353
354         colons = 0;
355
356         if (path.length() == 0) {
357                 return;
358         }
359
360         session_dirs.clear ();
361
362         for (string::size_type n = 0; n < len; ++n) {
363                 if (path[n] == ':') {
364                         colons++;
365                 }
366         }
367
368         if (colons == 0) {
369
370                 /* no multiple search path, just one location (common case) */
371
372                 sp.path = path;
373                 sp.blocks = 0;
374                 session_dirs.push_back (sp);
375
376                 string fspath;
377
378                 /* sounds dir */
379
380                 fspath += sp.path;
381                 if (fspath[fspath.length()-1] != '/') {
382                         fspath += '/';
383                 }
384                 fspath += sound_dir (false);
385                 
386                 AudioFileSource::set_search_path (fspath);
387
388                 return;
389         }
390
391         remaining = path;
392
393         while ((colon = remaining.find_first_of (':')) != string::npos) {
394                 
395                 sp.blocks = 0;
396                 sp.path = remaining.substr (0, colon);
397                 session_dirs.push_back (sp);
398
399                 /* add sounds to file search path */
400
401                 fspath += sp.path;
402                 if (fspath[fspath.length()-1] != '/') {
403                         fspath += '/';
404                 }
405                 fspath += sound_dir (false);
406                 fspath += ':';
407
408                 remaining = remaining.substr (colon+1);
409         }
410
411         if (remaining.length()) {
412
413                 sp.blocks = 0;
414                 sp.path = remaining;
415
416                 fspath += ':';
417                 fspath += sp.path;
418                 if (fspath[fspath.length()-1] != '/') {
419                         fspath += '/';
420                 }
421                 fspath += sound_dir (false);
422                 fspath += ':';
423
424                 session_dirs.push_back (sp);
425         }
426
427         /* set the AudioFileSource search path */
428
429         AudioFileSource::set_search_path (fspath);
430
431         /* reset the round-robin soundfile path thingie */
432
433         last_rr_session_dir = session_dirs.begin();
434 }
435
436 int
437 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
438 {
439         string dir;
440
441         if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
442                 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
443                 return -1;
444         }
445
446         dir = peak_dir ();
447
448         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449                 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
450                 return -1;
451         }
452
453         dir = sound_dir ();
454
455         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456                 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457                 return -1;
458         }
459
460         dir = dead_sound_dir ();
461
462         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463                 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464                 return -1;
465         }
466
467         dir = automation_dir ();
468
469         if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470                 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471                 return -1;
472         }
473
474
475         /* check new_session so we don't overwrite an existing one */
476
477         if (mix_template) {
478                 std::string in_path = *mix_template;
479
480                 ifstream in(in_path.c_str());
481
482                 if (in){
483                         string out_path = _path;
484                         out_path += _name;
485                         out_path += _statefile_suffix;
486
487                         ofstream out(out_path.c_str());
488
489                         if (out){
490                                 out << in.rdbuf();
491
492                                 // okay, session is set up.  Treat like normal saved
493                                 // session from now on.
494
495                                 new_session = false;
496                                 return 0;
497
498                         } else {
499                                 error << string_compose (_("Could not open %1 for writing mix template"), out_path) 
500                                         << endmsg;
501                                 return -1;
502                         }
503
504                 } else {
505                         error << string_compose (_("Could not open mix template %1 for reading"), in_path) 
506                                 << endmsg;
507                         return -1;
508                 }
509
510         }
511
512         /* set initial start + end point */
513
514         start_location->set_end (0);
515         _locations.add (start_location);
516
517         end_location->set_end (initial_length);
518         _locations.add (end_location);
519
520         _state_of_the_state = Clean;
521
522         if (save_state (_current_snapshot_name)) {
523                 save_history (_current_snapshot_name);
524                 return -1;
525         }
526
527         return 0;
528 }
529
530 int
531 Session::load_diskstreams (const XMLNode& node)
532 {
533         XMLNodeList          clist;
534         XMLNodeConstIterator citer;
535         
536         clist = node.children();
537
538         for (citer = clist.begin(); citer != clist.end(); ++citer) {
539                 
540
541                 try {
542                         boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
543                         add_diskstream (dstream);
544                 } 
545                 
546                 catch (failed_constructor& err) {
547                         error << _("Session: could not load diskstream via XML state")                        << endmsg;
548                         return -1;
549                 }
550         }
551
552         return 0;
553 }
554
555 void
556 Session::remove_pending_capture_state ()
557 {
558         string xml_path;
559
560         xml_path = _path;
561         xml_path += _current_snapshot_name;
562         xml_path += _pending_suffix;
563
564         unlink (xml_path.c_str());
565 }
566
567 int
568 Session::save_state (string snapshot_name, bool pending)
569 {
570         XMLTree tree;
571         string xml_path;
572         string bak_path;
573
574         if (_state_of_the_state & CannotSave) {
575                 return 1;
576         }
577
578         tree.set_root (&get_state());
579
580         if (snapshot_name.empty()) {
581                 snapshot_name = _current_snapshot_name;
582         }
583
584         if (!pending) {
585
586                 xml_path = _path;
587                 xml_path += snapshot_name;
588                 xml_path += _statefile_suffix;
589                 bak_path = xml_path;
590                 bak_path += ".bak";
591                 
592                 // Make backup of state file
593                 
594                 if ((access (xml_path.c_str(), F_OK) == 0) &&
595                     (rename(xml_path.c_str(), bak_path.c_str()))) {
596                         error << _("could not backup old state file, current state not saved.") << endmsg;
597                         return -1;
598                 }
599
600         } else {
601
602                 xml_path = _path;
603                 xml_path += snapshot_name;
604                 xml_path += _pending_suffix;
605
606         }
607
608         cerr << "actually writing state\n";
609
610         if (!tree.write (xml_path)) {
611                 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
612
613                 /* don't leave a corrupt file lying around if it is
614                    possible to fix.
615                 */
616
617                 if (unlink (xml_path.c_str())) {
618                         error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
619                 } else {
620                         if (!pending) {
621                                 if (rename (bak_path.c_str(), xml_path.c_str())) {
622                                         error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
623                                 }
624                         }
625                 }
626
627                 return -1;
628         }
629
630         if (!pending) {
631                 save_history(snapshot_name);
632
633                 bool was_dirty = dirty();
634
635                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
636                 
637                 if (was_dirty) {
638                         DirtyChanged (); /* EMIT SIGNAL */
639                 }
640                 
641                 StateSaved (snapshot_name); /* EMIT SIGNAL */
642         }
643
644         return 0;
645 }
646
647 int
648 Session::restore_state (string snapshot_name)
649 {
650         if (load_state (snapshot_name) == 0) {
651                 set_state (*state_tree->root());
652         }
653         
654         return 0;
655 }
656
657 int
658 Session::load_state (string snapshot_name)
659 {
660         if (state_tree) {
661                 delete state_tree;
662                 state_tree = 0;
663         }
664
665         string xmlpath;
666         
667         state_was_pending = false;
668
669         /* check for leftover pending state from a crashed capture attempt */
670
671         xmlpath = _path;
672         xmlpath += snapshot_name;
673         xmlpath += _pending_suffix;
674
675         if (!access (xmlpath.c_str(), F_OK)) {
676
677                 /* there is pending state from a crashed capture attempt */
678
679                 if (AskAboutPendingState()) {
680                         state_was_pending = true;
681                 } 
682         } 
683
684         if (!state_was_pending) {
685
686                 xmlpath = _path;
687                 xmlpath += snapshot_name;
688                 xmlpath += _statefile_suffix;
689         }
690
691         if (access (xmlpath.c_str(), F_OK)) {
692                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
693                 return 1;
694         }
695
696         state_tree = new XMLTree;
697
698         set_dirty();
699
700         if (state_tree->read (xmlpath)) {
701                 return 0;
702         } else {
703                 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
704         }
705
706         delete state_tree;
707         state_tree = 0;
708         return -1;
709 }
710
711 int
712 Session::load_options (const XMLNode& node)
713 {
714         XMLNode* child;
715         XMLProperty* prop;
716         LocaleGuard lg (X_("POSIX"));
717
718         Config->set_variables (node, ConfigVariableBase::Session);
719
720         if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
721                 if ((prop = child->property ("val")) != 0) {
722                         _end_location_is_free = (prop->value() == "yes");
723                 }
724         }
725
726         return 0;
727 }
728
729 bool
730 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
731 {
732         const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
733                 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
734
735         return owner & modified_by_session_or_user;
736 }
737
738 XMLNode&
739 Session::get_options () const
740 {
741         XMLNode* child;
742         LocaleGuard lg (X_("POSIX"));
743
744         XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
745
746         child = option_root.add_child ("end-marker-is-free");
747         child->add_property ("val", _end_location_is_free ? "yes" : "no");
748
749         return option_root;
750 }
751
752 XMLNode&
753 Session::get_state()
754 {
755         return state(true);
756 }
757
758 XMLNode&
759 Session::get_template()
760 {
761         /* if we don't disable rec-enable, diskstreams
762            will believe they need to store their capture
763            sources in their state node. 
764         */
765         
766         disable_record (false);
767
768         return state(false);
769 }
770
771 XMLNode&
772 Session::state(bool full_state)
773 {
774         XMLNode* node = new XMLNode("Session");
775         XMLNode* child;
776
777         // store libardour version, just in case
778         char buf[16];
779         snprintf(buf, sizeof(buf)-1, "%d.%d.%d", 
780                  libardour_major_version, libardour_minor_version, libardour_micro_version);
781         node->add_property("version", string(buf));
782                 
783         /* store configuration settings */
784
785         if (full_state) {
786         
787                 /* store the name */
788                 node->add_property ("name", _name);
789
790                 if (session_dirs.size() > 1) {
791
792                         string p;
793
794                         vector<space_and_path>::iterator i = session_dirs.begin();
795                         vector<space_and_path>::iterator next;
796
797                         ++i; /* skip the first one */
798                         next = i;
799                         ++next;
800
801                         while (i != session_dirs.end()) {
802
803                                 p += (*i).path;
804
805                                 if (next != session_dirs.end()) {
806                                         p += ':';
807                                 } else {
808                                         break;
809                                 }
810
811                                 ++next;
812                                 ++i;
813                         }
814                         
815                         child = node->add_child ("Path");
816                         child->add_content (p);
817                 }
818         }
819
820         /* save the ID counter */
821         
822         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
823         node->add_property ("id-counter", buf);
824
825         /* various options */
826
827         node->add_child_nocopy (get_options());
828
829         child = node->add_child ("Sources");
830
831         if (full_state) {
832                 Glib::Mutex::Lock sl (audio_source_lock);
833
834                 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
835                         
836                         /* Don't save information about AudioFileSources that are empty */
837                         
838                         boost::shared_ptr<AudioFileSource> fs;
839
840                         if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
841
842                                 /* destructive file sources are OK if they are empty, because
843                                    we will re-use them every time.
844                                 */
845
846                                 if (!fs->destructive()) {
847                                         if (fs->length() == 0) {
848                                                 continue;
849                                         }
850                                 }
851                         }
852                         
853                         child->add_child_nocopy (siter->second->get_state());
854                 }
855         }
856
857         child = node->add_child ("Regions");
858
859         if (full_state) { 
860                 Glib::Mutex::Lock rl (region_lock);
861
862                 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
863                         
864                         /* only store regions not attached to playlists */
865
866                         if (i->second->playlist() == 0) {
867                                 child->add_child_nocopy (i->second->state (true));
868                         }
869                 }
870         }
871
872         child = node->add_child ("DiskStreams");
873
874         { 
875                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
876                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
877                         if (!(*i)->hidden()) {
878                                 child->add_child_nocopy ((*i)->get_state());
879                         }
880                 }
881         }
882
883         node->add_child_nocopy (_locations.get_state());
884         
885         child = node->add_child ("Connections");
886         {
887                 Glib::Mutex::Lock lm (connection_lock);
888                 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
889                         if (!(*i)->system_dependent()) {
890                                 child->add_child_nocopy ((*i)->get_state());
891                         }
892                 }
893         }
894
895         child = node->add_child ("Routes");
896         {
897                 boost::shared_ptr<RouteList> r = routes.reader ();
898                 
899                 RoutePublicOrderSorter cmp;
900                 RouteList public_order (*r);
901                 public_order.sort (cmp);
902                 
903                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
904                         if (!(*i)->hidden()) {
905                                 if (full_state) {
906                                         child->add_child_nocopy ((*i)->get_state());
907                                 } else {
908                                         child->add_child_nocopy ((*i)->get_template());
909                                 }
910                         }
911                 }
912         }
913
914         
915         child = node->add_child ("EditGroups");
916         for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
917                 child->add_child_nocopy ((*i)->get_state());
918         }
919
920         child = node->add_child ("MixGroups");
921         for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
922                 child->add_child_nocopy ((*i)->get_state());
923         }
924
925         child = node->add_child ("Playlists");
926         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
927                 if (!(*i)->hidden()) {
928                         if (!(*i)->empty()) {
929                                 if (full_state) {
930                                         child->add_child_nocopy ((*i)->get_state());
931                                 } else {
932                                         child->add_child_nocopy ((*i)->get_template());
933                                 }
934                         }
935                 }
936         }
937
938         child = node->add_child ("UnusedPlaylists");
939         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
940                 if (!(*i)->hidden()) {
941                         if (!(*i)->empty()) {
942                                 if (full_state) {
943                                         child->add_child_nocopy ((*i)->get_state());
944                                 } else {
945                                         child->add_child_nocopy ((*i)->get_template());
946                                 }
947                         }
948                 }
949         }
950         
951         
952         if (_click_io) {
953                 child = node->add_child ("Click");
954                 child->add_child_nocopy (_click_io->state (full_state));
955         }
956
957         if (full_state) {
958                 child = node->add_child ("NamedSelections");
959                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
960                         if (full_state) {
961                                 child->add_child_nocopy ((*i)->get_state());
962                         } 
963                 }
964         }
965
966         node->add_child_nocopy (_tempo_map->get_state());
967
968         node->add_child_nocopy (get_control_protocol_state());
969
970         if (_extra_xml) {
971                 node->add_child_copy (*_extra_xml);
972         }
973
974         return *node;
975 }
976
977 XMLNode&
978 Session::get_control_protocol_state ()
979 {
980         ControlProtocolManager& cpm (ControlProtocolManager::instance());
981         XMLNode* node = new XMLNode (X_("ControlProtocols"));
982
983         cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
984         
985         return *node;
986 }
987
988 void
989 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
990 {
991         if (cpi->protocol) {
992                 node->add_child_nocopy (cpi->protocol->get_state());
993         }
994 }
995
996 int
997 Session::set_state (const XMLNode& node)
998 {
999         XMLNodeList nlist;
1000         XMLNode* child;
1001         const XMLProperty* prop;
1002         int ret = -1;
1003
1004         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1005         
1006         if (node.name() != X_("Session")){
1007                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1008                 return -1;
1009         }
1010
1011         if ((prop = node.property ("name")) != 0) {
1012                 _name = prop->value ();
1013         }
1014
1015         setup_raid_path(_path);
1016
1017         if ((prop = node.property (X_("id-counter"))) != 0) {
1018                 uint64_t x;
1019                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1020                 ID::init_counter (x);
1021         } else {
1022                 /* old sessions used a timebased counter, so fake
1023                    the startup ID counter based on a standard
1024                    timestamp.
1025                 */
1026                 time_t now;
1027                 time (&now);
1028                 ID::init_counter (now);
1029         }
1030
1031         
1032         IO::disable_ports ();
1033         IO::disable_connecting ();
1034
1035         /* Object loading order:
1036
1037         MIDI
1038         Path
1039         extra
1040         Options/Config
1041         Locations
1042         Sources
1043         AudioRegions
1044         AudioDiskstreams
1045         Connections
1046         Routes
1047         EditGroups
1048         MixGroups
1049         Click
1050         ControlProtocols
1051         */
1052
1053         if (use_config_midi_ports ()) {
1054         }
1055
1056         if ((child = find_named_node (node, "extra")) != 0) {
1057                 _extra_xml = new XMLNode (*child);
1058         }
1059
1060         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1061                 load_options (*child);
1062         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1063                 load_options (*child);
1064         } else {
1065                 error << _("Session: XML state has no options section") << endmsg;
1066         }
1067
1068         if ((child = find_named_node (node, "Locations")) == 0) {
1069                 error << _("Session: XML state has no locations section") << endmsg;
1070                 goto out;
1071         } else if (_locations.set_state (*child)) {
1072                 goto out;
1073         }
1074
1075         Location* location;
1076
1077         if ((location = _locations.auto_loop_location()) != 0) {
1078                 set_auto_loop_location (location);
1079         }
1080
1081         if ((location = _locations.auto_punch_location()) != 0) {
1082                 set_auto_punch_location (location);
1083         }
1084
1085         if ((location = _locations.end_location()) == 0) {
1086                 _locations.add (end_location);
1087         } else {
1088                 delete end_location;
1089                 end_location = location;
1090         }
1091
1092         if ((location = _locations.start_location()) == 0) {
1093                 _locations.add (start_location);
1094         } else {
1095                 delete start_location;
1096                 start_location = location;
1097         }
1098
1099         AudioFileSource::set_header_position_offset (start_location->start());
1100
1101         if ((child = find_named_node (node, "Sources")) == 0) {
1102                 error << _("Session: XML state has no sources section") << endmsg;
1103                 goto out;
1104         } else if (load_sources (*child)) {
1105                 goto out;
1106         }
1107
1108         if ((child = find_named_node (node, "Regions")) == 0) {
1109                 error << _("Session: XML state has no Regions section") << endmsg;
1110                 goto out;
1111         } else if (load_regions (*child)) {
1112                 goto out;
1113         }
1114
1115         if ((child = find_named_node (node, "Playlists")) == 0) {
1116                 error << _("Session: XML state has no playlists section") << endmsg;
1117                 goto out;
1118         } else if (load_playlists (*child)) {
1119                 goto out;
1120         }
1121
1122         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1123                 // this is OK
1124         } else if (load_unused_playlists (*child)) {
1125                 goto out;
1126         }
1127         
1128         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1129                 if (load_named_selections (*child)) {
1130                         goto out;
1131                 }
1132         }
1133
1134         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1135                 error << _("Session: XML state has no diskstreams section") << endmsg;
1136                 goto out;
1137         } else if (load_diskstreams (*child)) {
1138                 goto out;
1139         }
1140
1141         if ((child = find_named_node (node, "Connections")) == 0) {
1142                 error << _("Session: XML state has no connections section") << endmsg;
1143                 goto out;
1144         } else if (load_connections (*child)) {
1145                 goto out;
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 }