Use sys::path and SessionDirectory classes in Session::load_state for portability
[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         state_was_pending = false;
657
658         /* check for leftover pending state from a crashed capture attempt */
659
660         sys::path xmlpath(_session_dir->root_path());
661         xmlpath /= snapshot_name + pending_suffix;
662
663         if (sys::exists (xmlpath)) {
664
665                 /* there is pending state from a crashed capture attempt */
666
667                 if (AskAboutPendingState()) {
668                         state_was_pending = true;
669                 } 
670         } 
671
672         if (!state_was_pending) {
673                 xmlpath = _session_dir->root_path();
674                 xmlpath /= snapshot_name + statefile_suffix;
675         }
676         
677         if (!sys::exists (xmlpath)) {
678                 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
679                 return 1;
680         }
681
682         state_tree = new XMLTree;
683
684         set_dirty();
685
686         if (!state_tree->read (xmlpath.to_string())) {
687                 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
688                 delete state_tree;
689                 state_tree = 0;
690                 return -1;
691         }
692
693         XMLNode& root (*state_tree->root());
694         
695         if (root.name() != X_("Session")) {
696                 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
697                 delete state_tree;
698                 state_tree = 0;
699                 return -1;
700         }
701
702         const XMLProperty* prop;
703         bool is_old = false;
704
705         if ((prop = root.property ("version")) == 0) {
706                 /* no version implies very old version of Ardour */
707                 is_old = true;
708         } else {
709                 int major_version;
710                 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
711                 if (major_version < 2) {
712                         is_old = true;
713                 }
714         }
715
716         if (is_old) {
717
718                 sys::path backup_path(_session_dir->root_path());
719
720                 backup_path /= snapshot_name + "-1" + statefile_suffix;
721
722                 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
723                                         xmlpath.to_string(), backup_path.to_string()) 
724                      << endmsg;
725
726                 copy_file (xmlpath.to_string(), backup_path.to_string());
727
728                 /* if it fails, don't worry. right? */
729         }
730
731         return 0;
732 }
733
734 int
735 Session::load_options (const XMLNode& node)
736 {
737         XMLNode* child;
738         XMLProperty* prop;
739         LocaleGuard lg (X_("POSIX"));
740
741         Config->set_variables (node, ConfigVariableBase::Session);
742
743         if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
744                 if ((prop = child->property ("val")) != 0) {
745                         _end_location_is_free = (prop->value() == "yes");
746                 }
747         }
748
749         return 0;
750 }
751
752 bool
753 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
754 {
755         const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
756                 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
757
758         return owner & modified_by_session_or_user;
759 }
760
761 XMLNode&
762 Session::get_options () const
763 {
764         XMLNode* child;
765         LocaleGuard lg (X_("POSIX"));
766
767         XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
768
769         child = option_root.add_child ("end-marker-is-free");
770         child->add_property ("val", _end_location_is_free ? "yes" : "no");
771
772         return option_root;
773 }
774
775 XMLNode&
776 Session::get_state()
777 {
778         return state(true);
779 }
780
781 XMLNode&
782 Session::get_template()
783 {
784         /* if we don't disable rec-enable, diskstreams
785            will believe they need to store their capture
786            sources in their state node. 
787         */
788         
789         disable_record (false);
790
791         return state(false);
792 }
793
794 XMLNode&
795 Session::state(bool full_state)
796 {
797         XMLNode* node = new XMLNode("Session");
798         XMLNode* child;
799
800         // store libardour version, just in case
801         char buf[16];
802         snprintf(buf, sizeof(buf)-1, "%d.%d.%d", 
803                  libardour_major_version, libardour_minor_version, libardour_micro_version);
804         node->add_property("version", string(buf));
805                 
806         /* store configuration settings */
807
808         if (full_state) {
809         
810                 /* store the name */
811                 node->add_property ("name", _name);
812
813                 if (session_dirs.size() > 1) {
814
815                         string p;
816
817                         vector<space_and_path>::iterator i = session_dirs.begin();
818                         vector<space_and_path>::iterator next;
819
820                         ++i; /* skip the first one */
821                         next = i;
822                         ++next;
823
824                         while (i != session_dirs.end()) {
825
826                                 p += (*i).path;
827
828                                 if (next != session_dirs.end()) {
829                                         p += ':';
830                                 } else {
831                                         break;
832                                 }
833
834                                 ++next;
835                                 ++i;
836                         }
837                         
838                         child = node->add_child ("Path");
839                         child->add_content (p);
840                 }
841         }
842
843         /* save the ID counter */
844         
845         snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
846         node->add_property ("id-counter", buf);
847
848         /* various options */
849
850         node->add_child_nocopy (get_options());
851
852         child = node->add_child ("Sources");
853
854         if (full_state) {
855                 Glib::Mutex::Lock sl (source_lock);
856
857                 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
858                         
859                         /* Don't save information about AudioFileSources that are empty */
860                         
861                         boost::shared_ptr<AudioFileSource> fs;
862
863                         if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
864
865                                 /* Don't save sources that are empty, unless they're destructive (which are OK
866                                    if they are empty, because we will re-use them every time.)
867                                 */
868
869                                 if (!fs->destructive()) {
870                                         if (fs->length() == 0) {
871                                                 continue;
872                                         }
873                                 }
874                         }
875                         
876                         child->add_child_nocopy (siter->second->get_state());
877                 }
878         }
879
880         child = node->add_child ("Regions");
881
882         if (full_state) { 
883                 Glib::Mutex::Lock rl (region_lock);
884
885                 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
886                         
887                         /* only store regions not attached to playlists */
888
889                         if (i->second->playlist() == 0) {
890                                 child->add_child_nocopy (i->second->state (true));
891                         }
892                 }
893         }
894
895         child = node->add_child ("DiskStreams");
896
897         { 
898                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
899                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
900                         if (!(*i)->hidden()) {
901                                 child->add_child_nocopy ((*i)->get_state());
902                         }
903                 }
904         }
905
906         if (full_state) {
907                 node->add_child_nocopy (_locations.get_state());
908         } else {
909                 // for a template, just create a new Locations, populate it
910                 // with the default start and end, and get the state for that.
911                 Locations loc;
912                 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
913                 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
914                 start->set_end(0);
915                 loc.add (start);
916                 end->set_end(compute_initial_length());
917                 loc.add (end);
918                 node->add_child_nocopy (loc.get_state());
919         }
920         
921         child = node->add_child ("Connections");
922         {
923                 Glib::Mutex::Lock lm (bundle_lock);
924                 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
925                         if (!(*i)->dynamic()) {
926                                 child->add_child_nocopy ((*i)->get_state());
927                         }
928                 }
929         }
930
931         child = node->add_child ("Routes");
932         {
933                 boost::shared_ptr<RouteList> r = routes.reader ();
934                 
935                 RoutePublicOrderSorter cmp;
936                 RouteList public_order (*r);
937                 public_order.sort (cmp);
938                 
939                 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
940                         if (!(*i)->is_hidden()) {
941                                 if (full_state) {
942                                         child->add_child_nocopy ((*i)->get_state());
943                                 } else {
944                                         child->add_child_nocopy ((*i)->get_template());
945                                 }
946                         }
947                 }
948         }
949
950         
951         child = node->add_child ("EditGroups");
952         for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
953                 child->add_child_nocopy ((*i)->get_state());
954         }
955
956         child = node->add_child ("MixGroups");
957         for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
958                 child->add_child_nocopy ((*i)->get_state());
959         }
960
961         child = node->add_child ("Playlists");
962         for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
963                 if (!(*i)->hidden()) {
964                         if (!(*i)->empty()) {
965                                 if (full_state) {
966                                         child->add_child_nocopy ((*i)->get_state());
967                                 } else {
968                                         child->add_child_nocopy ((*i)->get_template());
969                                 }
970                         }
971                 }
972         }
973
974         child = node->add_child ("UnusedPlaylists");
975         for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
976                 if (!(*i)->hidden()) {
977                         if (!(*i)->empty()) {
978                                 if (full_state) {
979                                         child->add_child_nocopy ((*i)->get_state());
980                                 } else {
981                                         child->add_child_nocopy ((*i)->get_template());
982                                 }
983                         }
984                 }
985         }
986         
987         
988         if (_click_io) {
989                 child = node->add_child ("Click");
990                 child->add_child_nocopy (_click_io->state (full_state));
991         }
992
993         if (full_state) {
994                 child = node->add_child ("NamedSelections");
995                 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
996                         if (full_state) {
997                                 child->add_child_nocopy ((*i)->get_state());
998                         } 
999                 }
1000         }
1001
1002         node->add_child_nocopy (_tempo_map->get_state());
1003
1004         node->add_child_nocopy (get_control_protocol_state());
1005
1006         if (_extra_xml) {
1007                 node->add_child_copy (*_extra_xml);
1008         }
1009
1010         return *node;
1011 }
1012
1013 XMLNode&
1014 Session::get_control_protocol_state ()
1015 {
1016         ControlProtocolManager& cpm (ControlProtocolManager::instance());
1017         return cpm.get_state();
1018 }
1019
1020 int
1021 Session::set_state (const XMLNode& node)
1022 {
1023         XMLNodeList nlist;
1024         XMLNode* child;
1025         const XMLProperty* prop;
1026         int ret = -1;
1027
1028         _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1029         
1030         if (node.name() != X_("Session")){
1031                 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1032                 return -1;
1033         }
1034
1035         if ((prop = node.property ("name")) != 0) {
1036                 _name = prop->value ();
1037         }
1038
1039         setup_raid_path(_path);
1040
1041         if ((prop = node.property (X_("id-counter"))) != 0) {
1042                 uint64_t x;
1043                 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1044                 ID::init_counter (x);
1045         } else {
1046                 /* old sessions used a timebased counter, so fake
1047                    the startup ID counter based on a standard
1048                    timestamp.
1049                 */
1050                 time_t now;
1051                 time (&now);
1052                 ID::init_counter (now);
1053         }
1054
1055         
1056         IO::disable_ports ();
1057         IO::disable_connecting ();
1058
1059         /* Object loading order:
1060
1061         MIDI Control
1062         Path
1063         extra
1064         Options/Config
1065         Locations
1066         Sources
1067         AudioRegions
1068         AudioDiskstreams
1069         Connections
1070         Routes
1071         EditGroups
1072         MixGroups
1073         Click
1074         ControlProtocols
1075         */
1076
1077         if (use_config_midi_ports ()) {
1078         }
1079
1080         if ((child = find_named_node (node, "extra")) != 0) {
1081                 _extra_xml = new XMLNode (*child);
1082         }
1083
1084         if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1085                 load_options (*child);
1086         } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1087                 load_options (*child);
1088         } else {
1089                 error << _("Session: XML state has no options section") << endmsg;
1090         }
1091
1092         if ((child = find_named_node (node, "Locations")) == 0) {
1093                 error << _("Session: XML state has no locations section") << endmsg;
1094                 goto out;
1095         } else if (_locations.set_state (*child)) {
1096                 goto out;
1097         }
1098
1099         Location* location;
1100
1101         if ((location = _locations.auto_loop_location()) != 0) {
1102                 set_auto_loop_location (location);
1103         }
1104
1105         if ((location = _locations.auto_punch_location()) != 0) {
1106                 set_auto_punch_location (location);
1107         }
1108
1109         if ((location = _locations.end_location()) == 0) {
1110                 _locations.add (end_location);
1111         } else {
1112                 delete end_location;
1113                 end_location = location;
1114         }
1115
1116         if ((location = _locations.start_location()) == 0) {
1117                 _locations.add (start_location);
1118         } else {
1119                 delete start_location;
1120                 start_location = location;
1121         }
1122
1123         AudioFileSource::set_header_position_offset (start_location->start());
1124
1125         if ((child = find_named_node (node, "Sources")) == 0) {
1126                 error << _("Session: XML state has no sources section") << endmsg;
1127                 goto out;
1128         } else if (load_sources (*child)) {
1129                 goto out;
1130         }
1131
1132         if ((child = find_named_node (node, "Regions")) == 0) {
1133                 error << _("Session: XML state has no Regions section") << endmsg;
1134                 goto out;
1135         } else if (load_regions (*child)) {
1136                 goto out;
1137         }
1138
1139         if ((child = find_named_node (node, "Playlists")) == 0) {
1140                 error << _("Session: XML state has no playlists section") << endmsg;
1141                 goto out;
1142         } else if (load_playlists (*child)) {
1143                 goto out;
1144         }
1145
1146         if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1147                 // this is OK
1148         } else if (load_unused_playlists (*child)) {
1149                 goto out;
1150         }
1151         
1152         if ((child = find_named_node (node, "NamedSelections")) != 0) {
1153                 if (load_named_selections (*child)) {
1154                         goto out;
1155                 }
1156         }
1157
1158         if ((child = find_named_node (node, "DiskStreams")) == 0) {
1159                 error << _("Session: XML state has no diskstreams section") << endmsg;
1160                 goto out;
1161         } else if (load_diskstreams (*child)) {
1162                 goto out;
1163         }
1164
1165         if ((child = find_named_node (node, "Connections")) == 0) {
1166                 error << _("Session: XML state has no connections section") << endmsg;
1167                 goto out;
1168         } else if (load_bundles (*child)) {
1169                 goto out;
1170         }
1171
1172         if ((child = find_named_node (node, "EditGroups")) == 0) {
1173                 error << _("Session: XML state has no edit groups section") << endmsg;
1174                 goto out;
1175         } else if (load_edit_groups (*child)) {
1176                 goto out;
1177         }
1178
1179         if ((child = find_named_node (node, "MixGroups")) == 0) {
1180                 error << _("Session: XML state has no mix groups section") << endmsg;
1181                 goto out;
1182         } else if (load_mix_groups (*child)) {
1183                 goto out;
1184         }
1185
1186         if ((child = find_named_node (node, "TempoMap")) == 0) {
1187                 error << _("Session: XML state has no Tempo Map section") << endmsg;
1188                 goto out;
1189         } else if (_tempo_map->set_state (*child)) {
1190                 goto out;
1191         }
1192
1193         if ((child = find_named_node (node, "Routes")) == 0) {
1194                 error << _("Session: XML state has no routes section") << endmsg;
1195                 goto out;
1196         } else if (load_routes (*child)) {
1197                 goto out;
1198         }
1199
1200         if ((child = find_named_node (node, "Click")) == 0) {
1201                 warning << _("Session: XML state has no click section") << endmsg;
1202         } else if (_click_io) {
1203                 _click_io->set_state (*child);
1204         }
1205         
1206         if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1207                 ControlProtocolManager::instance().set_protocol_states (*child);
1208         }
1209
1210         /* here beginneth the second phase ... */
1211
1212         StateReady (); /* EMIT SIGNAL */
1213
1214         _state_of_the_state = Clean;
1215
1216         if (state_was_pending) {
1217                 save_state (_current_snapshot_name);
1218                 remove_pending_capture_state ();
1219                 state_was_pending = false;
1220         }
1221
1222         return 0;
1223
1224   out:
1225         return ret;
1226 }
1227
1228 int
1229 Session::load_routes (const XMLNode& node)
1230 {
1231         XMLNodeList nlist;
1232         XMLNodeConstIterator niter;
1233         RouteList new_routes;
1234
1235         nlist = node.children();
1236
1237         set_dirty();
1238
1239         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1240
1241                 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1242
1243                 if (route == 0) {
1244                         error << _("Session: cannot create Route from XML description.")                              << endmsg;
1245                         return -1;
1246                 }
1247
1248                 new_routes.push_back (route);
1249         }
1250
1251         add_routes (new_routes);
1252
1253         return 0;
1254 }
1255
1256 boost::shared_ptr<Route>
1257 Session::XMLRouteFactory (const XMLNode& node)
1258 {
1259         if (node.name() != "Route") {
1260                 return boost::shared_ptr<Route> ((Route*) 0);
1261         }
1262
1263         bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1264         
1265         DataType type = DataType::AUDIO;
1266         const XMLProperty* prop = node.property("default-type");
1267         if (prop)
1268                 type = DataType(prop->value());
1269         
1270         assert(type != DataType::NIL);
1271
1272         if (has_diskstream) {
1273                 if (type == DataType::AUDIO) {
1274                         boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1275                         return ret;
1276                 } else {
1277                         boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1278                         return ret;
1279                 }
1280         } else {
1281                 boost::shared_ptr<Route> ret (new Route (*this, node));
1282                 return ret;
1283         }
1284 }
1285
1286 int
1287 Session::load_regions (const XMLNode& node)
1288 {
1289         XMLNodeList nlist;
1290         XMLNodeConstIterator niter;
1291         boost::shared_ptr<Region> region;
1292
1293         nlist = node.children();
1294
1295         set_dirty();
1296
1297         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1298                 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1299                         error << _("Session: cannot create Region from XML description.") << endmsg;
1300                 }
1301         }
1302
1303         return 0;
1304 }
1305
1306 boost::shared_ptr<Region>
1307 Session::XMLRegionFactory (const XMLNode& node, bool full)
1308 {
1309         const XMLProperty* type = node.property("type");
1310
1311         try {
1312         
1313         if ( !type || type->value() == "audio" ) {
1314
1315                 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1316         
1317         } else if (type->value() == "midi") {
1318                 
1319                 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1320
1321         }
1322         
1323         } catch (failed_constructor& err) {
1324                 return boost::shared_ptr<Region> ();
1325         }
1326
1327         return boost::shared_ptr<Region> ();
1328 }
1329
1330 boost::shared_ptr<AudioRegion>
1331 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1332 {
1333         const XMLProperty* prop;
1334         boost::shared_ptr<Source> source;
1335         boost::shared_ptr<AudioSource> as;
1336         SourceList sources;
1337         uint32_t nchans = 1;
1338         char buf[128];
1339         
1340         if (node.name() != X_("Region")) {
1341                 return boost::shared_ptr<AudioRegion>();
1342         }
1343
1344         if ((prop = node.property (X_("channels"))) != 0) {
1345                 nchans = atoi (prop->value().c_str());
1346         }
1347
1348         if ((prop = node.property ("name")) == 0) {
1349                 cerr << "no name for this region\n";
1350                 abort ();
1351         }
1352         
1353         if ((prop = node.property (X_("source-0"))) == 0) {
1354                 if ((prop = node.property ("source")) == 0) {
1355                         error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1356                         return boost::shared_ptr<AudioRegion>();
1357                 }
1358         }
1359
1360         PBD::ID s_id (prop->value());
1361
1362         if ((source = source_by_id (s_id)) == 0) {
1363                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1364                 return boost::shared_ptr<AudioRegion>();
1365         }
1366         
1367         as = boost::dynamic_pointer_cast<AudioSource>(source);
1368         if (!as) {
1369                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1370                 return boost::shared_ptr<AudioRegion>();
1371         }
1372
1373         sources.push_back (as);
1374
1375         /* pickup other channels */
1376
1377         for (uint32_t n=1; n < nchans; ++n) {
1378                 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1379                 if ((prop = node.property (buf)) != 0) {
1380                         
1381                         PBD::ID id2 (prop->value());
1382                         
1383                         if ((source = source_by_id (id2)) == 0) {
1384                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1385                                 return boost::shared_ptr<AudioRegion>();
1386                         }
1387                         
1388                         as = boost::dynamic_pointer_cast<AudioSource>(source);
1389                         if (!as) {
1390                                 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1391                                 return boost::shared_ptr<AudioRegion>();
1392                         }
1393                         sources.push_back (as);
1394                 }
1395         }
1396         
1397         try {
1398                 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1399
1400                 /* a final detail: this is the one and only place that we know how long missing files are */
1401
1402                 if (region->whole_file()) {
1403                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1404                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1405                                 if (sfp) {
1406                                         sfp->set_length (region->length());
1407                                 }
1408                         }
1409                 }
1410
1411                 return region;
1412                                                        
1413         }
1414
1415         catch (failed_constructor& err) {
1416                 return boost::shared_ptr<AudioRegion>();
1417         }
1418 }
1419
1420 boost::shared_ptr<MidiRegion>
1421 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1422 {
1423         const XMLProperty* prop;
1424         boost::shared_ptr<Source> source;
1425         boost::shared_ptr<MidiSource> ms;
1426         SourceList sources;
1427         uint32_t nchans = 1;
1428         
1429         if (node.name() != X_("Region")) {
1430                 return boost::shared_ptr<MidiRegion>();
1431         }
1432
1433         if ((prop = node.property (X_("channels"))) != 0) {
1434                 nchans = atoi (prop->value().c_str());
1435         }
1436         
1437         if ((prop = node.property ("name")) == 0) {
1438                 cerr << "no name for this region\n";
1439                 abort ();
1440         }
1441
1442         // Multiple midi channels?  that's just crazy talk
1443         assert(nchans == 1);
1444
1445         if ((prop = node.property (X_("source-0"))) == 0) {
1446                 if ((prop = node.property ("source")) == 0) {
1447                         error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1448                         return boost::shared_ptr<MidiRegion>();
1449                 }
1450         }
1451
1452         PBD::ID s_id (prop->value());
1453
1454         if ((source = source_by_id (s_id)) == 0) {
1455                 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1456                 return boost::shared_ptr<MidiRegion>();
1457         }
1458
1459         ms = boost::dynamic_pointer_cast<MidiSource>(source);
1460         if (!ms) {
1461                 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1462                 return boost::shared_ptr<MidiRegion>();
1463         }
1464
1465         sources.push_back (ms);
1466
1467         try {
1468                 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1469                 /* a final detail: this is the one and only place that we know how long missing files are */
1470
1471                 if (region->whole_file()) {
1472                         for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1473                                 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1474                                 if (sfp) {
1475                                         sfp->set_length (region->length());
1476                                 }
1477                         }
1478                 }
1479
1480                 return region;
1481         }
1482
1483         catch (failed_constructor& err) {
1484                 return boost::shared_ptr<MidiRegion>();
1485         }
1486 }
1487
1488 XMLNode&
1489 Session::get_sources_as_xml ()
1490
1491 {
1492         XMLNode* node = new XMLNode (X_("Sources"));
1493         Glib::Mutex::Lock lm (source_lock);
1494
1495         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1496                 node->add_child_nocopy (i->second->get_state());
1497         }
1498
1499         return *node;
1500 }
1501
1502 string
1503 Session::path_from_region_name (DataType type, string name, string identifier)
1504 {
1505         char buf[PATH_MAX+1];
1506         uint32_t n;
1507         SessionDirectory sdir(get_best_session_directory_for_new_source());
1508         string sound_dir = ((type == DataType::AUDIO)
1509                 ? sdir.sound_path().to_string()
1510                 : sdir.midi_path().to_string());
1511
1512         string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1513
1514         for (n = 0; n < 999999; ++n) {
1515                 if (identifier.length()) {
1516                         snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 "%s", sound_dir.c_str(), name.c_str(), 
1517                                   identifier.c_str(), n, ext.c_str());
1518                 } else {
1519                         snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 "%s", sound_dir.c_str(), name.c_str(),
1520                                         n, ext.c_str());
1521                 }
1522
1523                 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1524                         return buf;
1525                 }
1526         }
1527
1528         error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1529                                  name, identifier)
1530               << endmsg;
1531
1532         return "";
1533 }
1534         
1535
1536 int
1537 Session::load_sources (const XMLNode& node)
1538 {
1539         XMLNodeList nlist;
1540         XMLNodeConstIterator niter;
1541         boost::shared_ptr<Source> source;
1542
1543         nlist = node.children();
1544
1545         set_dirty();
1546
1547         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1548
1549                 try {
1550                         if ((source = XMLSourceFactory (**niter)) == 0) {
1551                                 error << _("Session: cannot create Source from XML description.") << endmsg;
1552                         }
1553                 }
1554
1555                 catch (non_existent_source& err) {
1556                         warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1557                         source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1558                 }
1559         }
1560
1561         return 0;
1562 }
1563
1564 boost::shared_ptr<Source>
1565 Session::XMLSourceFactory (const XMLNode& node)
1566 {
1567         if (node.name() != "Source") {
1568                 return boost::shared_ptr<Source>();
1569         }
1570
1571         try {
1572                 return SourceFactory::create (*this, node);
1573         }
1574
1575         catch (failed_constructor& err) {
1576                 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1577                 return boost::shared_ptr<Source>();
1578         }
1579 }
1580
1581 int
1582 Session::save_template (string template_name)
1583 {
1584         XMLTree tree;
1585         string xml_path, bak_path, template_path;
1586
1587         if (_state_of_the_state & CannotSave) {
1588                 return -1;
1589         }
1590
1591         sys::path user_template_dir(user_template_directory());
1592
1593         try
1594         {
1595                 sys::create_directories (user_template_dir);
1596         }
1597         catch(sys::filesystem_error& ex)
1598         {
1599                 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1600                                 user_template_dir.to_string(), ex.what()) << endmsg;
1601                 return -1;
1602         }
1603
1604         tree.set_root (&get_template());
1605
1606         sys::path template_file_path(user_template_dir);
1607         template_file_path /= template_name + template_suffix;
1608
1609         if (sys::exists (template_file_path))
1610         {
1611                 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1612                                 template_file_path.to_string()) << endmsg;
1613                 return -1;
1614         }
1615
1616         if (!tree.write (template_file_path.to_string())) {
1617                 error << _("mix template not saved") << endmsg;
1618                 return -1;
1619         }
1620
1621         return 0;
1622 }
1623
1624 void
1625 Session::refresh_disk_space ()
1626 {
1627 #if HAVE_SYS_VFS_H
1628         struct statfs statfsbuf;
1629         vector<space_and_path>::iterator i;
1630         Glib::Mutex::Lock lm (space_lock);
1631         double scale;
1632
1633         /* get freespace on every FS that is part of the session path */
1634
1635         _total_free_4k_blocks = 0;
1636         
1637         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1638                 statfs ((*i).path.c_str(), &statfsbuf);
1639
1640                 scale = statfsbuf.f_bsize/4096.0;
1641
1642                 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1643                 _total_free_4k_blocks += (*i).blocks;
1644         }
1645 #endif
1646 }
1647
1648 string
1649 Session::get_best_session_directory_for_new_source ()
1650 {
1651         vector<space_and_path>::iterator i;
1652         string result = _session_dir->root_path().to_string();
1653
1654         /* handle common case without system calls */
1655
1656         if (session_dirs.size() == 1) {
1657                 return result;
1658         }
1659
1660         /* OK, here's the algorithm we're following here:
1661            
1662         We want to select which directory to use for 
1663         the next file source to be created. Ideally,
1664         we'd like to use a round-robin process so as to
1665         get maximum performance benefits from splitting
1666         the files across multiple disks.
1667
1668         However, in situations without much diskspace, an
1669         RR approach may end up filling up a filesystem
1670         with new files while others still have space.
1671         Its therefore important to pay some attention to
1672         the freespace in the filesystem holding each
1673         directory as well. However, if we did that by
1674         itself, we'd keep creating new files in the file
1675         system with the most space until it was as full
1676         as all others, thus negating any performance
1677         benefits of this RAID-1 like approach.
1678
1679         So, we use a user-configurable space threshold. If
1680         there are at least 2 filesystems with more than this
1681         much space available, we use RR selection between them. 
1682         If not, then we pick the filesystem with the most space.
1683
1684         This gets a good balance between the two
1685         approaches.  
1686         */
1687         
1688         refresh_disk_space ();
1689         
1690         int free_enough = 0;
1691
1692         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1693                 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1694                         free_enough++;
1695                 }
1696         }
1697
1698         if (free_enough >= 2) {
1699                 /* use RR selection process, ensuring that the one
1700                    picked works OK.
1701                 */
1702
1703                 i = last_rr_session_dir;
1704
1705                 do {
1706                         if (++i == session_dirs.end()) {
1707                                 i = session_dirs.begin();
1708                         }
1709
1710                         if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1711                                 if (create_session_directory ((*i).path)) {
1712                                         result = (*i).path;
1713                                         last_rr_session_dir = i;
1714                                         return result;
1715                                 }
1716                         }
1717
1718                 } while (i != last_rr_session_dir);
1719
1720         } else {
1721
1722                 /* pick FS with the most freespace (and that
1723                    seems to actually work ...)
1724                 */
1725                 
1726                 vector<space_and_path> sorted;
1727                 space_and_path_ascending_cmp cmp;
1728
1729                 sorted = session_dirs;
1730                 sort (sorted.begin(), sorted.end(), cmp);
1731                 
1732                 for (i = sorted.begin(); i != sorted.end(); ++i) {
1733                         if (create_session_directory ((*i).path)) {
1734                                 result = (*i).path;
1735                                 last_rr_session_dir = i;
1736                                 return result;
1737                         }
1738                 }
1739         }
1740
1741         return result;
1742 }
1743
1744 int
1745 Session::load_playlists (const XMLNode& node)
1746 {
1747         XMLNodeList nlist;
1748         XMLNodeConstIterator niter;
1749         boost::shared_ptr<Playlist> playlist;
1750
1751         nlist = node.children();
1752
1753         set_dirty();
1754
1755         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1756                 
1757                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1758                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1759                 }
1760         }
1761
1762         return 0;
1763 }
1764
1765 int
1766 Session::load_unused_playlists (const XMLNode& node)
1767 {
1768         XMLNodeList nlist;
1769         XMLNodeConstIterator niter;
1770         boost::shared_ptr<Playlist> playlist;
1771
1772         nlist = node.children();
1773
1774         set_dirty();
1775
1776         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1777                 
1778                 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1779                         error << _("Session: cannot create Playlist from XML description.") << endmsg;
1780                         continue;
1781                 }
1782
1783                 // now manually untrack it
1784
1785                 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1786         }
1787
1788         return 0;
1789 }
1790
1791 boost::shared_ptr<Playlist>
1792 Session::XMLPlaylistFactory (const XMLNode& node)
1793 {
1794         try {
1795                 return PlaylistFactory::create (*this, node);
1796         }
1797
1798         catch (failed_constructor& err) {
1799                 return boost::shared_ptr<Playlist>();
1800         }
1801 }
1802
1803 int
1804 Session::load_named_selections (const XMLNode& node)
1805 {
1806         XMLNodeList nlist;
1807         XMLNodeConstIterator niter;
1808         NamedSelection *ns;
1809
1810         nlist = node.children();
1811
1812         set_dirty();
1813
1814         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1815                 
1816                 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1817                         error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1818                 }
1819         }
1820
1821         return 0;
1822 }
1823
1824 NamedSelection *
1825 Session::XMLNamedSelectionFactory (const XMLNode& node)
1826 {
1827         try {
1828                 return new NamedSelection (*this, node);
1829         }
1830
1831         catch (failed_constructor& err) {
1832                 return 0;
1833         }
1834 }
1835
1836 string
1837 Session::automation_dir () const
1838 {
1839         string res = _path;
1840         res += "automation/";
1841         return res;
1842 }
1843
1844 int
1845 Session::load_bundles (const XMLNode& node)
1846 {
1847         XMLNodeList nlist = node.children();
1848         XMLNodeConstIterator niter;
1849
1850         set_dirty();
1851
1852         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1853                 if ((*niter)->name() == "InputConnection") {
1854                         add_bundle (new ARDOUR::InputBundle (**niter));
1855                 } else if ((*niter)->name() == "OutputConnection") {
1856                         add_bundle (new ARDOUR::OutputBundle (**niter));
1857                 } else {
1858                         error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1859                         return -1;
1860                 }
1861         }
1862
1863         return 0;
1864 }                               
1865
1866 int
1867 Session::load_edit_groups (const XMLNode& node)
1868 {
1869         return load_route_groups (node, true);
1870 }
1871
1872 int
1873 Session::load_mix_groups (const XMLNode& node)
1874 {
1875         return load_route_groups (node, false);
1876 }
1877
1878 int
1879 Session::load_route_groups (const XMLNode& node, bool edit)
1880 {
1881         XMLNodeList nlist = node.children();
1882         XMLNodeConstIterator niter;
1883         RouteGroup* rg;
1884
1885         set_dirty();
1886
1887         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1888                 if ((*niter)->name() == "RouteGroup") {
1889                         if (edit) {
1890                                 rg = add_edit_group ("");
1891                                 rg->set_state (**niter);
1892                         } else {
1893                                 rg = add_mix_group ("");
1894                                 rg->set_state (**niter);
1895                         }
1896                 }
1897         }
1898         
1899         return 0;
1900 }                               
1901
1902 static bool
1903 state_file_filter (const string &str, void *arg)
1904 {
1905         return (str.length() > strlen(statefile_suffix) &&
1906                 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
1907 }
1908
1909 struct string_cmp {
1910         bool operator()(const string* a, const string* b) {
1911                 return *a < *b;
1912         }
1913 };
1914
1915 static string*
1916 remove_end(string* state)
1917 {
1918         string statename(*state);
1919         
1920         string::size_type start,end;
1921         if ((start = statename.find_last_of ('/')) != string::npos) {
1922                 statename = statename.substr (start+1);
1923         }
1924                 
1925         if ((end = statename.rfind(".ardour")) == string::npos) {
1926                 end = statename.length();
1927         }
1928
1929         return new string(statename.substr (0, end));
1930 }
1931
1932 vector<string *> *
1933 Session::possible_states (string path) 
1934 {
1935         PathScanner scanner;
1936         vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1937         
1938         transform(states->begin(), states->end(), states->begin(), remove_end);
1939         
1940         string_cmp cmp;
1941         sort (states->begin(), states->end(), cmp);
1942         
1943         return states;
1944 }
1945
1946 vector<string *> *
1947 Session::possible_states () const
1948 {
1949         return possible_states(_path);
1950 }
1951
1952 void
1953 Session::auto_save()
1954 {
1955         save_state (_current_snapshot_name);
1956 }
1957
1958 RouteGroup *
1959 Session::add_edit_group (string name)
1960 {
1961         RouteGroup* rg = new RouteGroup (*this, name);
1962         edit_groups.push_back (rg);
1963         edit_group_added (rg); /* EMIT SIGNAL */
1964         set_dirty();
1965         return rg;
1966 }
1967
1968 RouteGroup *
1969 Session::add_mix_group (string name)
1970 {
1971         RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1972         mix_groups.push_back (rg);
1973         mix_group_added (rg); /* EMIT SIGNAL */
1974         set_dirty();
1975         return rg;
1976 }
1977
1978 void
1979 Session::remove_edit_group (RouteGroup& rg)
1980 {
1981         list<RouteGroup*>::iterator i;
1982
1983         if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1984                 (*i)->apply (&Route::drop_edit_group, this);
1985                 edit_groups.erase (i);
1986                 edit_group_removed (); /* EMIT SIGNAL */
1987         }
1988
1989         delete &rg;
1990 }
1991
1992 void
1993 Session::remove_mix_group (RouteGroup& rg)
1994 {
1995         list<RouteGroup*>::iterator i;
1996
1997         if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
1998                 (*i)->apply (&Route::drop_mix_group, this);
1999                 mix_groups.erase (i);
2000                 mix_group_removed (); /* EMIT SIGNAL */
2001         }
2002
2003         delete &rg;
2004 }
2005
2006 RouteGroup *
2007 Session::mix_group_by_name (string name)
2008 {
2009         list<RouteGroup *>::iterator i;
2010
2011         for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2012                 if ((*i)->name() == name) {
2013                         return* i;
2014                 }
2015         }
2016         return 0;
2017 }
2018
2019 RouteGroup *
2020 Session::edit_group_by_name (string name)
2021 {
2022         list<RouteGroup *>::iterator i;
2023
2024         for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2025                 if ((*i)->name() == name) {
2026                         return* i;
2027                 }
2028         }
2029         return 0;
2030 }
2031
2032 void
2033 Session::begin_reversible_command (const string& name)
2034 {
2035         current_trans = new UndoTransaction;
2036         current_trans->set_name (name);
2037 }
2038
2039 void
2040 Session::commit_reversible_command (Command *cmd)
2041 {
2042         struct timeval now;
2043
2044         if (cmd) {
2045                 current_trans->add_command (cmd);
2046         }
2047
2048         gettimeofday (&now, 0);
2049         current_trans->set_timestamp (now);
2050
2051         _history.add (current_trans);
2052 }
2053
2054 Session::GlobalRouteBooleanState 
2055 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2056 {
2057         GlobalRouteBooleanState s;
2058         boost::shared_ptr<RouteList> r = routes.reader ();
2059
2060         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2061                 if (!(*i)->is_hidden()) {
2062                         RouteBooleanState v;
2063                         
2064                         v.first =* i;
2065                         Route* r = (*i).get();
2066                         v.second = (r->*method)();
2067                         
2068                         s.push_back (v);
2069                 }
2070         }
2071
2072         return s;
2073 }
2074
2075 Session::GlobalRouteMeterState
2076 Session::get_global_route_metering ()
2077 {
2078         GlobalRouteMeterState s;
2079         boost::shared_ptr<RouteList> r = routes.reader ();
2080
2081         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2082                 if (!(*i)->is_hidden()) {
2083                         RouteMeterState v;
2084                         
2085                         v.first =* i;
2086                         v.second = (*i)->meter_point();
2087                         
2088                         s.push_back (v);
2089                 }
2090         }
2091
2092         return s;
2093 }
2094
2095 void
2096 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) 
2097 {
2098         for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2099
2100                 boost::shared_ptr<Route> r = (i->first.lock());
2101
2102                 if (r) {
2103                         r->set_meter_point (i->second, arg);
2104                 }
2105         }
2106 }
2107
2108 void
2109 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2110 {
2111         for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2112
2113                 boost::shared_ptr<Route> r = (i->first.lock());
2114
2115                 if (r) {
2116                         Route* rp = r.get();
2117                         (rp->*method) (i->second, arg);
2118                 }
2119         }
2120 }
2121
2122 void
2123 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2124 {
2125         set_global_route_boolean (s, &Route::set_mute, src);
2126 }
2127
2128 void
2129 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2130 {
2131         set_global_route_boolean (s, &Route::set_solo, src);
2132 }
2133
2134 void
2135 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2136 {
2137         set_global_route_boolean (s, &Route::set_record_enable, src);
2138 }
2139
2140 #if 0
2141 UndoAction
2142 Session::global_mute_memento (void* src)
2143 {
2144         return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2145 }
2146
2147 UndoAction
2148 Session::global_metering_memento (void* src)
2149 {
2150         return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2151 }
2152
2153 UndoAction
2154 Session::global_solo_memento (void* src)
2155 {
2156         return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2157 }
2158
2159 UndoAction
2160 Session::global_record_enable_memento (void* src)
2161 {
2162         return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2163 }
2164 #endif
2165
2166 static bool
2167 accept_all_non_peak_files (const string& path, void *arg)
2168 {
2169         return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2170 }
2171
2172 static bool
2173 accept_all_state_files (const string& path, void *arg)
2174 {
2175         return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2176 }
2177
2178 int 
2179 Session::find_all_sources (string path, set<string>& result)
2180 {
2181         XMLTree tree;
2182         XMLNode* node;
2183
2184         if (!tree.read (path)) {
2185                 return -1;
2186         }
2187
2188         if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2189                 return -2;
2190         }
2191
2192         XMLNodeList nlist;
2193         XMLNodeConstIterator niter;
2194
2195         nlist = node->children();
2196
2197         set_dirty();
2198
2199         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2200                 
2201                 XMLProperty* prop;
2202
2203                 if ((prop = (*niter)->property (X_("name"))) == 0) {
2204                         continue;
2205                 }
2206
2207                 if (prop->value()[0] == '/') {
2208                         /* external file, ignore */
2209                         continue;
2210                 }
2211
2212                 sys::path source_path = _session_dir->sound_path ();
2213
2214                 source_path /= prop->value ();
2215
2216                 result.insert (source_path.to_string ());
2217         }
2218
2219         return 0;
2220 }
2221
2222 int
2223 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2224 {
2225         PathScanner scanner;
2226         vector<string*>* state_files;
2227         string ripped;
2228         string this_snapshot_path;
2229
2230         result.clear ();
2231
2232         ripped = _path;
2233
2234         if (ripped[ripped.length()-1] == '/') {
2235                 ripped = ripped.substr (0, ripped.length() - 1);
2236         }
2237
2238         state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2239         
2240         if (state_files == 0) {
2241                 /* impossible! */
2242                 return 0;
2243         }
2244
2245         this_snapshot_path = _path;
2246         this_snapshot_path += _current_snapshot_name;
2247         this_snapshot_path += statefile_suffix;
2248
2249         for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2250
2251                 if (exclude_this_snapshot && **i == this_snapshot_path) {
2252                         continue;
2253                 }
2254
2255                 if (find_all_sources (**i, result) < 0) {
2256                         return -1;
2257                 }
2258         }
2259
2260         return 0;
2261 }
2262
2263 struct RegionCounter {
2264     typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2265     AudioSourceList::iterator iter;
2266     boost::shared_ptr<Region> region;
2267     uint32_t count;
2268     
2269     RegionCounter() : count (0) {}
2270 };
2271
2272 int
2273 Session::cleanup_sources (Session::cleanup_report& rep)
2274 {
2275         // FIXME: needs adaptation to midi
2276         
2277         vector<boost::shared_ptr<Source> > dead_sources;
2278         vector<boost::shared_ptr<Playlist> > playlists_tbd;
2279         PathScanner scanner;
2280         string sound_path;
2281         vector<space_and_path>::iterator i;
2282         vector<space_and_path>::iterator nexti;
2283         vector<string*>* soundfiles;
2284         vector<string> unused;
2285         set<string> all_sources;
2286         bool used;
2287         string spath;
2288         int ret = -1;
2289                 
2290         _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2291         
2292         /* step 1: consider deleting all unused playlists */
2293
2294         for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2295                 int status;
2296
2297                 status = AskAboutPlaylistDeletion (*x);
2298
2299                 switch (status) {
2300                 case -1:
2301                         ret = 0;
2302                         goto out;
2303                         break;
2304
2305                 case 0:
2306                         playlists_tbd.push_back (*x);
2307                         break;
2308
2309                 default:
2310                         /* leave it alone */
2311                         break;
2312                 }
2313         }
2314
2315         /* now delete any that were marked for deletion */
2316
2317         for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2318                 (*x)->drop_references ();
2319         }
2320
2321         playlists_tbd.clear ();
2322
2323         /* step 2: find all un-used sources */
2324
2325         rep.paths.clear ();
2326         rep.space = 0;
2327
2328         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2329                 
2330                 SourceMap::iterator tmp;
2331
2332                 tmp = i;
2333                 ++tmp;
2334
2335                 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2336                    capture files.
2337                 */
2338
2339                 if (!i->second->used() && i->second->length() > 0) {
2340                         dead_sources.push_back (i->second);
2341                         i->second->GoingAway();
2342                 } 
2343
2344                 i = tmp;
2345         }
2346
2347         /* build a list of all the possible sound directories for the session */
2348
2349         for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2350
2351                 nexti = i;
2352                 ++nexti;
2353
2354                 SessionDirectory sdir ((*i).path);
2355                 sound_path += sdir.sound_path().to_string();
2356
2357                 if (nexti != session_dirs.end()) {
2358                         sound_path += ':';
2359                 }
2360
2361                 i = nexti;
2362         }
2363
2364         /* now do the same thing for the files that ended up in the sounds dir(s) 
2365            but are not referenced as sources in any snapshot.
2366         */
2367
2368         soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2369
2370         if (soundfiles == 0) {
2371                 return 0;
2372         }
2373
2374         /* find all sources, but don't use this snapshot because the
2375            state file on disk still references sources we may have already
2376            dropped.
2377         */
2378         
2379         find_all_sources_across_snapshots (all_sources, true);
2380
2381         /*  add our current source list
2382          */
2383         
2384         for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2385                 boost::shared_ptr<AudioFileSource> fs;
2386                 
2387                 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2388                         all_sources.insert (fs->path());
2389                 } 
2390         }
2391
2392         char tmppath1[PATH_MAX+1];
2393         char tmppath2[PATH_MAX+1];
2394         
2395         for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2396
2397                 used = false;
2398                 spath = **x;
2399
2400                 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2401
2402                         realpath(spath.c_str(), tmppath1);
2403                         realpath((*i).c_str(),  tmppath2);
2404
2405                         if (strcmp(tmppath1, tmppath2) == 0) {
2406                                 used = true;
2407                                 break;
2408                         }
2409                 }
2410
2411                 if (!used) {
2412                         unused.push_back (spath);
2413                 }
2414         }
2415
2416         /* now try to move all unused files into the "dead_sounds" directory(ies) */
2417
2418         for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2419                 struct stat statbuf;
2420
2421                 rep.paths.push_back (*x);
2422                 if (stat ((*x).c_str(), &statbuf) == 0) {
2423                         rep.space += statbuf.st_size;
2424                 }
2425
2426                 string newpath;
2427                 
2428                 /* don't move the file across filesystems, just
2429                    stick it in the `dead_sound_dir_name' directory
2430                    on whichever filesystem it was already on.
2431                 */
2432
2433                 if ((*x).find ("/sounds/") != string::npos) {
2434
2435                         /* old school, go up 1 level */
2436
2437                         newpath = Glib::path_get_dirname (*x);      // "sounds" 
2438                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2439
2440                 } else {
2441
2442                         /* new school, go up 4 levels */
2443                         
2444                         newpath = Glib::path_get_dirname (*x);      // "audiofiles" 
2445                         newpath = Glib::path_get_dirname (newpath); // "session-name"
2446                         newpath = Glib::path_get_dirname (newpath); // "interchange"
2447                         newpath = Glib::path_get_dirname (newpath); // "session-dir"
2448                 }
2449
2450                 newpath += '/';
2451                 newpath += dead_sound_dir_name;
2452
2453                 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2454                         error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2455                         return -1;
2456                 }
2457
2458                 newpath += '/';
2459                 newpath += Glib::path_get_basename ((*x));
2460                 
2461                 if (access (newpath.c_str(), F_OK) == 0) {
2462                         
2463                         /* the new path already exists, try versioning */
2464                         
2465                         char buf[PATH_MAX+1];
2466                         int version = 1;
2467                         string newpath_v;
2468                         
2469                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2470                         newpath_v = buf;
2471
2472                         while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2473                                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2474                                 newpath_v = buf;
2475                         }
2476                         
2477                         if (version == 999) {
2478                                 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2479                                                   newpath)
2480                                       << endmsg;
2481                         } else {
2482                                 newpath = newpath_v;
2483                         }
2484                         
2485                 } else {
2486                         
2487                         /* it doesn't exist, or we can't read it or something */
2488                         
2489                 }
2490
2491                 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2492                         error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2493                                           (*x), newpath, strerror (errno))
2494                               << endmsg;
2495                         goto out;
2496                 }
2497
2498                 /* see if there an easy to find peakfile for this file, and remove it.
2499                  */
2500
2501                 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2502                 peakpath += peakfile_suffix;
2503
2504                 if (access (peakpath.c_str(), W_OK) == 0) {
2505                         if (::unlink (peakpath.c_str()) != 0) {
2506                                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2507                                                   peakpath, _path, strerror (errno))
2508                                       << endmsg;
2509                                 /* try to back out */
2510                                 rename (newpath.c_str(), _path.c_str());
2511                                 goto out;
2512                         }
2513                 }
2514         }
2515
2516         ret = 0;
2517
2518         /* dump the history list */
2519
2520         _history.clear ();
2521
2522         /* save state so we don't end up a session file
2523            referring to non-existent sources.
2524         */
2525         
2526         save_state ("");
2527
2528   out:
2529         _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2530         return ret;
2531 }
2532
2533 int
2534 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2535 {
2536         // FIXME: needs adaptation for MIDI
2537         
2538         vector<space_and_path>::iterator i;
2539         string dead_sound_dir;
2540         struct dirent* dentry;
2541         struct stat statbuf;
2542         DIR* dead;
2543
2544         rep.paths.clear ();
2545         rep.space = 0;
2546
2547         for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2548                 
2549                 dead_sound_dir = (*i).path;
2550                 dead_sound_dir += dead_sound_dir_name;
2551
2552                 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2553                         continue;
2554                 }
2555
2556                 while ((dentry = readdir (dead)) != 0) {
2557
2558                         /* avoid '.' and '..' */
2559                         
2560                         if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || 
2561                             (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2562                                 continue;
2563                         }
2564
2565                         string fullpath;
2566
2567                         fullpath = dead_sound_dir;
2568                         fullpath += '/';
2569                         fullpath += dentry->d_name;
2570
2571                         if (stat (fullpath.c_str(), &statbuf)) {
2572                                 continue;
2573                         }
2574
2575                         if (!S_ISREG (statbuf.st_mode)) {
2576                                 continue;
2577                         }
2578
2579                         if (unlink (fullpath.c_str())) {
2580                                 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2581                                                   fullpath, strerror (errno))
2582                                       << endmsg;
2583                         }
2584
2585                         rep.paths.push_back (dentry->d_name);
2586                         rep.space += statbuf.st_size;
2587                 }
2588
2589                 closedir (dead);
2590                 
2591         }
2592
2593         return 0;
2594 }
2595
2596 void
2597 Session::set_dirty ()
2598 {
2599         bool was_dirty = dirty();
2600
2601         _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2602
2603         if (!was_dirty) {
2604                 DirtyChanged(); /* EMIT SIGNAL */
2605         }
2606 }
2607
2608
2609 void
2610 Session::set_clean ()
2611 {
2612         bool was_dirty = dirty();
2613         
2614         _state_of_the_state = Clean;
2615
2616         if (was_dirty) {
2617                 DirtyChanged(); /* EMIT SIGNAL */
2618         }
2619 }
2620
2621 void
2622 Session::set_deletion_in_progress ()
2623 {
2624         _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2625 }
2626
2627 void
2628 Session::add_controllable (boost::shared_ptr<Controllable> c)
2629 {
2630         /* this adds a controllable to the list managed by the Session.
2631            this is a subset of those managed by the Controllable class
2632            itself, and represents the only ones whose state will be saved
2633            as part of the session.
2634         */
2635
2636         Glib::Mutex::Lock lm (controllables_lock);
2637         controllables.insert (c);
2638 }
2639         
2640 struct null_deleter { void operator()(void const *) const {} };
2641
2642 void
2643 Session::remove_controllable (Controllable* c)
2644 {
2645         if (_state_of_the_state | Deletion) {
2646                 return;
2647         }
2648
2649         Glib::Mutex::Lock lm (controllables_lock);
2650
2651         Controllables::iterator x = controllables.find(
2652                  boost::shared_ptr<Controllable>(c, null_deleter()));
2653
2654         if (x != controllables.end()) {
2655                 controllables.erase (x);
2656         }
2657 }       
2658
2659 boost::shared_ptr<Controllable>
2660 Session::controllable_by_id (const PBD::ID& id)
2661 {
2662         Glib::Mutex::Lock lm (controllables_lock);
2663         
2664         for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2665                 if ((*i)->id() == id) {
2666                         return *i;
2667                 }
2668         }
2669
2670         return boost::shared_ptr<Controllable>();
2671 }
2672
2673 void 
2674 Session::add_instant_xml (XMLNode& node)
2675 {
2676         Stateful::add_instant_xml (node, _path);
2677         Config->add_instant_xml (node);
2678 }
2679
2680 XMLNode*
2681 Session::instant_xml (const string& node_name)
2682 {
2683         return Stateful::instant_xml (node_name, _path);
2684 }
2685
2686 int 
2687 Session::save_history (string snapshot_name)
2688 {
2689     XMLTree tree;
2690     string xml_path;
2691     string bak_path;
2692
2693     tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2694
2695     if (snapshot_name.empty()) {
2696         snapshot_name = _current_snapshot_name;
2697     }
2698
2699     xml_path = _path + snapshot_name + ".history"; 
2700
2701     bak_path = xml_path + ".bak";
2702
2703     if ((access (xml_path.c_str(), F_OK) == 0) &&
2704         (rename (xml_path.c_str(), bak_path.c_str())))
2705     {
2706         error << _("could not backup old history file, current history not saved.") << endmsg;
2707         return -1;
2708     }
2709
2710     if (!tree.write (xml_path))
2711     {
2712         error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2713
2714         /* don't leave a corrupt file lying around if it is
2715          * possible to fix.
2716          */
2717
2718         if (unlink (xml_path.c_str())) {
2719                 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2720         } else {
2721                 if (rename (bak_path.c_str(), xml_path.c_str())) 
2722                 {
2723                         error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2724                 }
2725         }
2726
2727         return -1;
2728     }
2729
2730     return 0;
2731 }
2732
2733 int
2734 Session::restore_history (string snapshot_name)
2735 {
2736     XMLTree tree;
2737     string xmlpath;
2738
2739     if (snapshot_name.empty()) {
2740             snapshot_name = _current_snapshot_name;
2741     }
2742
2743     /* read xml */
2744     xmlpath = _path + snapshot_name + ".history";
2745     cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2746
2747     if (access (xmlpath.c_str(), F_OK)) {
2748             info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2749             return 1;
2750     }
2751
2752     if (!tree.read (xmlpath)) {
2753             error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2754             return -1;
2755     }
2756
2757     /* replace history */
2758     _history.clear();
2759
2760     for (XMLNodeConstIterator it  = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2761             
2762             XMLNode *t = *it;
2763             UndoTransaction* ut = new UndoTransaction ();
2764             struct timeval tv;
2765             
2766             ut->set_name(t->property("name")->value());
2767             stringstream ss(t->property("tv_sec")->value());
2768             ss >> tv.tv_sec;
2769             ss.str(t->property("tv_usec")->value());
2770             ss >> tv.tv_usec;
2771             ut->set_timestamp(tv);
2772             
2773             for (XMLNodeConstIterator child_it  = t->children().begin();
2774                  child_it != t->children().end();
2775                  child_it++)
2776             {
2777                     XMLNode *n = *child_it;
2778                     Command *c;
2779         
2780                     if (n->name() == "MementoCommand" ||
2781                         n->name() == "MementoUndoCommand" ||
2782                         n->name() == "MementoRedoCommand") {
2783
2784                             if ((c = memento_command_factory(n))) {
2785                                     ut->add_command(c);
2786                             }
2787                             
2788                     } else if (n->name() == X_("GlobalRouteStateCommand")) {
2789
2790                             if ((c = global_state_command_factory (*n))) {
2791                                     ut->add_command (c);
2792                             }
2793                             
2794                     } else {
2795
2796                             error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2797                     }
2798             }
2799
2800             _history.add (ut);
2801     }
2802
2803     return 0;
2804 }
2805
2806 void
2807 Session::config_changed (const char* parameter_name)
2808 {
2809 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2810
2811         if (PARAM_IS ("seamless-loop")) {
2812                 
2813         } else if (PARAM_IS ("rf-speed")) {
2814                 
2815         } else if (PARAM_IS ("auto-loop")) {
2816                 
2817         } else if (PARAM_IS ("auto-input")) {
2818
2819                 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2820                         /* auto-input only makes a difference if we're rolling */
2821                         
2822                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2823                         
2824                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2825                                 if ((*i)->record_enabled ()) {
2826                                         (*i)->monitor_input (!Config->get_auto_input());
2827                                 }
2828                         }
2829                 }
2830
2831         } else if (PARAM_IS ("punch-in")) {
2832
2833                 Location* location;
2834                 
2835                 if ((location = _locations.auto_punch_location()) != 0) {
2836                         
2837                         if (Config->get_punch_in ()) {
2838                                 replace_event (Event::PunchIn, location->start());
2839                         } else {
2840                                 remove_event (location->start(), Event::PunchIn);
2841                         }
2842                 }
2843                 
2844         } else if (PARAM_IS ("punch-out")) {
2845
2846                 Location* location;
2847                 
2848                 if ((location = _locations.auto_punch_location()) != 0) {
2849                         
2850                         if (Config->get_punch_out()) {
2851                                 replace_event (Event::PunchOut, location->end());
2852                         } else {
2853                                 clear_events (Event::PunchOut);
2854                         }
2855                 }
2856
2857         } else if (PARAM_IS ("edit-mode")) {
2858
2859                 Glib::Mutex::Lock lm (playlist_lock);
2860                 
2861                 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2862                         (*i)->set_edit_mode (Config->get_edit_mode ());
2863                 }
2864
2865         } else if (PARAM_IS ("use-video-sync")) {
2866
2867                 waiting_for_sync_offset = Config->get_use_video_sync();
2868
2869         } else if (PARAM_IS ("mmc-control")) {
2870
2871                 //poke_midi_thread ();
2872
2873         } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
2874
2875                 if (mmc) {
2876                         mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
2877                 }
2878
2879         } else if (PARAM_IS ("mmc-send-id")) {
2880
2881                 if (mmc) {
2882                         mmc->set_send_device_id (Config->get_mmc_send_device_id());
2883                 }
2884
2885         } else if (PARAM_IS ("midi-control")) {
2886                 
2887                 //poke_midi_thread ();
2888
2889         } else if (PARAM_IS ("raid-path")) {
2890
2891                 setup_raid_path (Config->get_raid_path());
2892
2893         } else if (PARAM_IS ("smpte-format")) {
2894
2895                 sync_time_vars ();
2896
2897         } else if (PARAM_IS ("video-pullup")) {
2898
2899                 sync_time_vars ();
2900
2901         } else if (PARAM_IS ("seamless-loop")) {
2902
2903                 if (play_loop && transport_rolling()) {
2904                         // to reset diskstreams etc
2905                         request_play_loop (true);
2906                 }
2907
2908         } else if (PARAM_IS ("rf-speed")) {
2909
2910                 cumulative_rf_motion = 0;
2911                 reset_rf_scale (0);
2912
2913         } else if (PARAM_IS ("click-sound")) {
2914
2915                 setup_click_sounds (1);
2916
2917         } else if (PARAM_IS ("click-emphasis-sound")) {
2918
2919                 setup_click_sounds (-1);
2920
2921         } else if (PARAM_IS ("clicking")) {
2922
2923                 if (Config->get_clicking()) {
2924                         if (_click_io && click_data) { // don't require emphasis data
2925                                 _clicking = true;
2926                         }
2927                 } else {
2928                         _clicking = false;
2929                 }
2930
2931         } else if (PARAM_IS ("send-mtc")) {
2932                 
2933                 /* only set the internal flag if we have
2934                    a port.
2935                 */
2936                 
2937                 if (_mtc_port != 0) {
2938                         session_send_mtc = Config->get_send_mtc();
2939                         if (session_send_mtc) {
2940                                 /* mark us ready to send */
2941                                 next_quarter_frame_to_send = 0;
2942                         }
2943                 } else {
2944                         session_send_mtc = false;
2945                 }
2946
2947         } else if (PARAM_IS ("send-mmc")) {
2948                 
2949                 /* only set the internal flag if we have
2950                    a port.
2951                 */
2952                 
2953                 if (_mmc_port != 0) {
2954                         session_send_mmc = Config->get_send_mmc();
2955                 } else {
2956                         mmc = 0;
2957                         session_send_mmc = false; 
2958                 }
2959
2960         } else if (PARAM_IS ("midi-feedback")) {
2961                 
2962                 /* only set the internal flag if we have
2963                    a port.
2964                 */
2965                 
2966                 if (_mtc_port != 0) {
2967                         session_midi_feedback = Config->get_midi_feedback();
2968                 }
2969
2970         } else if (PARAM_IS ("jack-time-master")) {
2971
2972                 engine().reset_timebase ();
2973
2974         } else if (PARAM_IS ("native-file-header-format")) {
2975
2976                 if (!first_file_header_format_reset) {
2977                         reset_native_file_format ();
2978                 }
2979
2980                 first_file_header_format_reset = false;
2981
2982         } else if (PARAM_IS ("native-file-data-format")) {
2983
2984                 if (!first_file_data_format_reset) {
2985                         reset_native_file_format ();
2986                 }
2987
2988                 first_file_data_format_reset = false;
2989
2990         } else if (PARAM_IS ("slave-source")) {
2991                 set_slave_source (Config->get_slave_source());
2992         } else if (PARAM_IS ("remote-model")) {
2993                 set_remote_control_ids ();
2994         }  else if (PARAM_IS ("denormal-model")) {
2995                 setup_fpu ();
2996         }
2997
2998         set_dirty ();
2999                    
3000 #undef PARAM_IS
3001
3002 }