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