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