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