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