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