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