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