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