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