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