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