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