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