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