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