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