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