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