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