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