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