28f13aabb8442281a361ac5f06f4171379c2b87d
[ardour.git] / libs / ardour / configuration.cc
1 /*
2     Copyright (C) 1999 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     $Id$
19 */
20
21 #include <unistd.h>
22 #include <cstdio> /* for snprintf, grrr */
23
24 #ifdef HAVE_WORDEXP
25 #include <wordexp.h>
26 #endif
27
28 #include <pbd/failed_constructor.h>
29 #include <pbd/xml++.h>
30
31 #include <ardour/ardour.h>
32 #include <ardour/configuration.h>
33 #include <ardour/diskstream.h>
34
35 #include "i18n.h"
36
37 using namespace ARDOUR;
38 using namespace std;
39
40 /* this is global so that we do not have to indirect through an object pointer
41    to reference it.
42 */
43
44 namespace ARDOUR {
45     float speed_quietning = 0.251189; // -12dB reduction for ffwd or rewind
46 }
47
48 Configuration::Configuration ()
49 {
50         key_node = 0;
51         user_configuration = false;
52         set_defaults ();
53 }
54
55 Configuration::~Configuration ()
56 {
57 }
58         
59 string
60 Configuration::get_user_path()
61 {
62         char *envvar;
63
64         if ((envvar = getenv ("ARDOUR_RC")) != 0) {
65                 return envvar;
66         }
67
68         return find_config_file ("ardour.rc");
69 }
70
71 string
72 Configuration::get_system_path()
73 {
74         char* envvar;
75
76         if ((envvar = getenv ("ARDOUR_SYSTEM_RC")) != 0) {
77                 return envvar;
78         }
79
80         return find_config_file ("ardour_system.rc");
81 }
82
83 int
84 Configuration::load_state ()
85 {
86         string rcfile;
87         
88         /* load system configuration first */
89
90         rcfile = get_system_path ();
91
92         if (rcfile.length()) {
93
94                 XMLTree tree;
95
96                 cerr << "Loading system configuration file " << rcfile << endl;
97
98                 if (!tree.read (rcfile.c_str())) {
99                         error << string_compose(_("Ardour: cannot read system configuration file \"%1\""), rcfile) << endmsg;
100                         return -1;
101                 }
102
103                 if (set_state (*tree.root())) {
104                         error << string_compose(_("Ardour: system configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
105                         return -1;
106                 }
107         }
108
109         /* from this point on, all configuration changes are user driven */
110
111         user_configuration = true;
112
113         /* now load configuration file for user */
114         
115         rcfile = get_user_path ();
116
117         if (rcfile.length()) {
118
119                 XMLTree tree;
120
121                 cerr << "Loading user configuration file " << rcfile << endl;
122
123                 if (!tree.read (rcfile)) {
124                         error << string_compose(_("Ardour: cannot read configuration file \"%1\""), rcfile) << endmsg;
125                         return -1;
126                 }
127                 
128                 
129                 if (set_state (*tree.root())) {
130                         error << string_compose(_("Ardour: configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
131                         return -1;
132                 }
133         }
134
135         return 0;
136 }
137
138 int
139 Configuration::save_state()
140 {
141         XMLTree tree;
142         string rcfile;
143         char *envvar;
144
145         /* Note: this only writes the per-user file, and therefore
146            only saves variables marked as user-set or modified
147         */
148
149         if ((envvar = getenv ("ARDOUR_RC")) != 0) {
150                 if (strlen (envvar) == 0) {
151                         return -1;
152                 }
153                 rcfile = envvar;
154         } else {
155
156                 if ((envvar = getenv ("HOME")) == 0) {
157                         return -1;
158                 }
159                 if (strlen (envvar) == 0) {
160                         return -1;
161                 }
162                 rcfile = envvar;
163                 rcfile += "/.ardour/ardour.rc";
164         }
165
166         if (rcfile.length()) {
167                 tree.set_root (&state (true));
168                 if (!tree.write (rcfile.c_str())){
169                         error << _("Config file not saved") << endmsg;
170                         return -1;
171                 }
172         }
173
174         return 0;
175 }
176
177 XMLNode&
178 Configuration::get_state ()
179 {
180         return state (false);
181 }
182
183 XMLNode&
184 Configuration::state (bool user_only)
185 {
186         XMLNode* root = new XMLNode("Ardour");
187         LocaleGuard lg (X_("POSIX"));
188
189         typedef map<string, MidiPortDescriptor*>::const_iterator CI;
190         for(CI m = midi_ports.begin(); m != midi_ports.end(); ++m){
191                 root->add_child_nocopy(m->second->get_state());
192         }
193
194         XMLNode* node = new XMLNode("Config");
195         char buf[32];
196         
197         if (!user_only || minimum_disk_io_bytes_is_user) {
198                 snprintf(buf, sizeof(buf), "%" PRIu32 , minimum_disk_io_bytes);
199                 node->add_child_nocopy(option_node("minimum-disk-io-bytes", string(buf)));
200         }
201         if (!user_only || track_buffer_seconds_is_user) {
202                 snprintf(buf, sizeof(buf), "%f", track_buffer_seconds);
203                 node->add_child_nocopy(option_node("track-buffer-seconds", string(buf)));
204         }
205         if (!user_only || disk_choice_space_threshold_is_user) {
206                 snprintf(buf, sizeof(buf), "%" PRIu32, disk_choice_space_threshold);
207                 node->add_child_nocopy(option_node("disk-choice-space-threshold", string(buf)));
208         }
209
210         if (!user_only || midi_feedback_interval_ms_is_user) {
211                 snprintf(buf, sizeof(buf), "%" PRIu32, midi_feedback_interval_ms);
212                 node->add_child_nocopy(option_node("midi-feedback-interval-ms", string(buf)));
213         }
214
215         if (!user_only || mute_affects_pre_fader_is_user) {
216                 node->add_child_nocopy(option_node("mute-affects-pre-fader", mute_affects_pre_fader?"yes":"no"));
217         }
218         if (!user_only || mute_affects_post_fader_is_user) {
219                 node->add_child_nocopy(option_node("mute-affects-post-fader", mute_affects_post_fader?"yes":"no"));
220         }
221         if (!user_only || mute_affects_control_outs_is_user) {
222                 node->add_child_nocopy(option_node("mute-affects-control-outs", mute_affects_control_outs?"yes":"no"));
223         }
224         if (!user_only || mute_affects_main_outs_is_user) {
225                 node->add_child_nocopy(option_node("mute-affects-main-outs", mute_affects_main_outs?"yes":"no"));
226         }
227         if (!user_only || solo_latch_is_user) {
228                 node->add_child_nocopy(option_node("solo-latch", solo_latch?"yes":"no"));
229         }
230         if (!user_only || raid_path_is_user) {
231                 node->add_child_nocopy(option_node("raid-path", orig_raid_path));
232         }
233         if (!user_only || mtc_port_name_is_user) {
234                 node->add_child_nocopy(option_node("mtc-port", mtc_port_name));
235         }
236         if (!user_only || mmc_port_name_is_user) {
237                 node->add_child_nocopy(option_node("mmc-port", mmc_port_name));
238         }
239         if (!user_only || midi_port_name_is_user) {
240                 node->add_child_nocopy(option_node("midi-port", midi_port_name));
241         }
242         if (!user_only || use_hardware_monitoring_is_user) {
243                 node->add_child_nocopy(option_node("hardware-monitoring", use_hardware_monitoring?"yes":"no"));
244         }
245         if (!user_only || be_jack_time_master_is_user) {
246                 node->add_child_nocopy(option_node("jack-time-master", be_jack_time_master?"yes":"no"));
247         }
248         if (!user_only || native_format_is_bwf_is_user) {
249                 node->add_child_nocopy(option_node("native-format-bwf", native_format_is_bwf?"yes":"no"));
250         }
251         if (!user_only || trace_midi_input_is_user) {
252                 node->add_child_nocopy(option_node("trace-midi-input", trace_midi_input?"yes":"no"));
253         }
254         if (!user_only || trace_midi_output_is_user) {
255                 node->add_child_nocopy(option_node("trace-midi-output", trace_midi_output?"yes":"no"));
256         }
257         if (!user_only || plugins_stop_with_transport_is_user) {
258                 node->add_child_nocopy(option_node("plugins-stop-with-transport", plugins_stop_with_transport?"yes":"no"));
259         }
260         if (!user_only || use_sw_monitoring_is_user) {
261                 node->add_child_nocopy(option_node("use-sw-monitoring", use_sw_monitoring?"yes":"no"));
262         }
263         if (!user_only || stop_recording_on_xrun_is_user) {
264                 node->add_child_nocopy(option_node("stop-recording-on-xrun", stop_recording_on_xrun?"yes":"no"));
265         }
266         if (!user_only || verify_remove_last_capture_is_user) {
267                 node->add_child_nocopy(option_node("verify-remove-last-capture", verify_remove_last_capture?"yes":"no"));
268         }
269         if (!user_only || stop_at_session_end_is_user) {
270                 node->add_child_nocopy(option_node("stop-at-session-end", stop_at_session_end?"yes":"no"));
271         }
272         if (!user_only || seamless_looping_is_user) {
273                 node->add_child_nocopy(option_node("seamless-loop", seamless_looping?"yes":"no"));
274         }
275         if (!user_only || auto_xfade_is_user) {
276                 node->add_child_nocopy(option_node("auto-xfade", auto_xfade?"yes":"no"));
277         }
278         if (!user_only || no_new_session_dialog_is_user) {
279                 node->add_child_nocopy(option_node("no-new-session-dialog", no_new_session_dialog?"yes":"no"));
280         }
281         if (!user_only || timecode_source_is_synced_is_user) {
282                 node->add_child_nocopy(option_node("timecode-source-is-synced", timecode_source_is_synced?"yes":"no"));
283         }
284         if (!user_only || auditioner_output_left_is_user) {
285                 node->add_child_nocopy(option_node("auditioner-left-out", auditioner_output_left));
286         }
287         if (!user_only || auditioner_output_right_is_user) {
288                 node->add_child_nocopy(option_node("auditioner-right-out", auditioner_output_right));
289         }
290         if (!user_only || quieten_at_speed_is_user) {
291                 snprintf (buf, sizeof (buf), "%f", speed_quietning);
292                 node->add_child_nocopy(option_node("quieten-at-speed", buf));
293         }
294
295         /* use-vst is always per-user */
296         node->add_child_nocopy (option_node ("use-vst", use_vst?"yes":"no"));
297
298         root->add_child_nocopy (*node);
299
300         if (key_node) {
301                 root->add_child_copy (*key_node);
302         }
303
304         if (_extra_xml) {
305                 root->add_child_copy (*_extra_xml);
306         }
307
308         return *root;
309 }
310
311 int
312 Configuration::set_state (const XMLNode& root)
313 {
314         if (root.name() != "Ardour") {
315                 return -1;
316         }
317
318         XMLNodeList nlist = root.children();
319         XMLNodeConstIterator niter;
320         XMLNode *node;
321         XMLProperty *prop;
322
323         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
324
325                 node = *niter;
326
327                 if (node->name() == "MIDI-port") {
328
329                         try {
330                                 pair<string,MidiPortDescriptor*> newpair;
331                                 newpair.second = new MidiPortDescriptor (*node);
332                                 newpair.first = newpair.second->tag;
333                                 midi_ports.insert (newpair);
334                         }
335
336                         catch (failed_constructor& err) {
337                                 warning << _("ill-formed MIDI port specification in ardour rcfile (ignored)") << endmsg;
338                         }
339
340                 } else if (node->name() == "Config") {
341                         
342                         XMLNodeList option_list = node->children();
343                         XMLNodeConstIterator option_iter;
344                         XMLNode *option_node;
345
346                         string option_name;
347                         string option_value;
348
349                         for (option_iter = option_list.begin(); option_iter != option_list.end(); ++option_iter) {
350
351                                 option_node = *option_iter;
352
353                                 if (option_node->name() != "Option") {
354                                         continue;
355                                 }
356
357                                 if ((prop = option_node->property ("name")) != 0) {
358                                         option_name = prop->value();
359                                 } else {
360                                         throw failed_constructor ();
361                                 }
362                                 
363                                 if ((prop = option_node->property ("value")) != 0) {
364                                         option_value = prop->value();
365                                 } else {
366                                         throw failed_constructor ();
367                                 }
368                                 
369                                 if (option_name == "minimum-disk-io-bytes") {
370                                         set_minimum_disk_io (atoi (option_value.c_str()));
371                                 } else if (option_name == "track-buffer-seconds") {
372                                         set_track_buffer (atof (option_value.c_str()));
373                                 } else if (option_name == "raid-path") {
374                                         set_raid_path (option_value);
375                                 } else if (option_name == "hiding-groups-deactivates-groups") {
376                                         set_hiding_groups_deactivates_groups (option_value == "yes");
377                                 } else if (option_name == "mute-affects-pre-fader") {
378                                         set_mute_affects_pre_fader (option_value == "yes");
379                                 } else if (option_name == "mute-affects-post-fader") {
380                                         set_mute_affects_post_fader (option_value == "yes");
381                                 } else if (option_name == "mute-affects-control-outs") {
382                                         set_mute_affects_control_outs (option_value == "yes");
383                                 } else if (option_name == "mute-affects-main-outs") {
384                                         set_mute_affects_main_outs (option_value == "yes");
385                                 } else if (option_name == "solo-latch") {
386                                         set_solo_latch (option_value == "yes");
387                                 } else if (option_name == "mtc-port") {
388                                         set_mtc_port_name (option_value);
389                                 } else if (option_name == "mmc-port") {
390                                         set_mmc_port_name (option_value);
391                                 } else if (option_name == "midi-port") {
392                                         set_midi_port_name (option_value);
393                                 } else if (option_name == "hardware-monitoring") {
394                                         set_use_hardware_monitoring (option_value == "yes");
395                                 } else if (option_name == "jack-time-master") {
396                                         set_jack_time_master (option_value == "yes");
397                                 } else if (option_name == "trace-midi-input") {
398                                         set_trace_midi_input (option_value == "yes");
399                                 } else if (option_name == "trace-midi-output") {
400                                         set_trace_midi_output (option_value == "yes");
401                                 } else if (option_name == "plugins-stop-with-transport") {
402                                         set_plugins_stop_with_transport (option_value == "yes");
403                                 } else if (option_name == "use-sw-monitoring") {
404                                         set_use_sw_monitoring (option_value == "yes");
405                                 } else if (option_name == "no-sw-monitoring") {     /* DEPRECATED */
406                                         set_use_sw_monitoring (option_value != "yes");
407                                 } else if (option_name == "stop-recording-on-xrun") {
408                                         set_stop_recording_on_xrun (option_value == "yes");
409                                 } else if (option_name == "verify-remove-last-capture") {
410                                         set_verify_remove_last_capture (option_value == "yes");
411                                 } else if (option_name == "stop-at-session-end") {
412                                         set_stop_at_session_end (option_value == "yes");
413                                 } else if (option_name == "seamless-loop") {
414                                         set_seamless_looping (option_value == "yes");
415                                 } else if (option_name == "auto-xfade") {
416                                         set_auto_xfade (option_value == "yes");
417                                 } else if (option_name == "no-new-session-dialog") {
418                                         set_no_new_session_dialog (option_value == "yes");
419                                 } else if (option_name == "timecode-source-is-synced") {
420                                         set_timecode_source_is_synced (option_value == "yes");
421                                 } else if (option_name == "auditioner-left-out") {
422                                         set_auditioner_output_left (option_value);
423                                 } else if (option_name == "auditioner-right-out") {
424                                         set_auditioner_output_right (option_value);
425                                 } else if (option_name == "use-vst") {
426                                         set_use_vst (option_value == "yes");
427                                 } else if (option_name == "quieten-at-speed") {
428                                         float v;
429                                         if (sscanf (option_value.c_str(), "%f", &v) == 1) {
430                                                 set_quieten_at_speed (v);
431                                         }
432                                 } else if (option_name == "midi-feedback-interval-ms") {
433                                         set_midi_feedback_interval_ms (atoi (option_value.c_str()));
434                                 }
435                         }
436                         
437                 } else if (node->name() == "Keys") {
438                         /* defer handling of this for UI objects */
439                         key_node = new XMLNode (*node);
440                 } else if (node->name() == "extra") {
441                         _extra_xml = new XMLNode (*node);
442                 }
443         }
444
445         DiskStream::set_disk_io_chunk_frames (minimum_disk_io_bytes / sizeof (Sample));
446
447         return 0;
448 }
449
450 void
451 Configuration::set_defaults ()
452 {
453         raid_path = "";
454         orig_raid_path = raid_path;
455
456         mtc_port_name = N_("default");
457         mmc_port_name = N_("default");
458         midi_port_name = N_("default");
459 #ifdef __APPLE__
460         auditioner_output_left = N_("coreaudio:Built-in Audio:in1");
461         auditioner_output_right = N_("coreaudio:Built-in Audio:in2");
462 #else
463         auditioner_output_left = N_("alsa_pcm:playback_1");
464         auditioner_output_right = N_("alsa_pcm:playback_2");
465 #endif
466         minimum_disk_io_bytes = 1024 * 256;
467         track_buffer_seconds = 5.0;
468         hiding_groups_deactivates_groups = true;
469         mute_affects_pre_fader = 1;
470         mute_affects_post_fader = 1;
471         mute_affects_control_outs = 1;
472         mute_affects_main_outs = 1;
473         solo_latch = 1;
474         use_hardware_monitoring = true;
475         be_jack_time_master = true;
476         native_format_is_bwf = true;
477         trace_midi_input = false;
478         trace_midi_output = false;
479         plugins_stop_with_transport = false;
480         use_sw_monitoring = true;
481         stop_recording_on_xrun = false;
482         verify_remove_last_capture = true;
483         stop_at_session_end = true;
484         seamless_looping = true;
485         auto_xfade = true;
486         no_new_session_dialog = false;
487         timecode_source_is_synced = true;
488         use_vst = true; /* if we build with VST_SUPPORT, otherwise no effect */
489         quieten_at_speed = true;
490
491         midi_feedback_interval_ms = 100;
492         
493         // this is about 5 minutes at 48kHz, 4 bytes/sample
494         disk_choice_space_threshold = 57600000;
495
496         /* at this point, no variables from from the user */
497
498         raid_path_is_user = false;
499         minimum_disk_io_bytes_is_user = false;
500         track_buffer_seconds_is_user = false;
501         hiding_groups_deactivates_groups_is_user = false;
502         auditioner_output_left_is_user = false;
503         auditioner_output_right_is_user = false;
504         mute_affects_pre_fader_is_user = false;
505         mute_affects_post_fader_is_user = false;
506         mute_affects_control_outs_is_user = false;
507         mute_affects_main_outs_is_user = false;
508         solo_latch_is_user = false;
509         disk_choice_space_threshold_is_user = false;
510         mtc_port_name_is_user = false;
511         mmc_port_name_is_user = false;
512         midi_port_name_is_user = false;
513         use_hardware_monitoring_is_user = false;
514         be_jack_time_master_is_user = false;
515         native_format_is_bwf_is_user = false;
516         trace_midi_input_is_user = false;
517         trace_midi_output_is_user = false;
518         plugins_stop_with_transport_is_user = false;
519         use_sw_monitoring_is_user = false;
520         stop_recording_on_xrun_is_user = false;
521         verify_remove_last_capture_is_user = false;
522         stop_at_session_end_is_user = false;
523         seamless_looping_is_user = false;
524         auto_xfade_is_user = false;
525         no_new_session_dialog_is_user = false;
526         timecode_source_is_synced_is_user = false;
527         quieten_at_speed_is_user = false;
528         midi_feedback_interval_ms_is_user = false;
529 }
530
531 Configuration::MidiPortDescriptor::MidiPortDescriptor (const XMLNode& node)
532 {
533         const XMLProperty *prop;
534         bool have_tag = false;
535         bool have_device = false;
536         bool have_type = false;
537         bool have_mode = false;
538
539         if ((prop = node.property ("tag")) != 0) {
540                 tag = prop->value();
541                 have_tag = true;
542         }
543
544         if ((prop = node.property ("device")) != 0) {
545                 device = prop->value();
546                 have_device = true;
547         }
548
549         if ((prop = node.property ("type")) != 0) {
550                 type = prop->value();
551                 have_type = true;
552         }
553
554         if ((prop = node.property ("mode")) != 0) {
555                 mode = prop->value();
556                 have_mode = true;
557         }
558
559         if (!have_tag || !have_device || !have_type || !have_mode) {
560                 throw failed_constructor();
561         }
562 }
563
564 XMLNode&
565 Configuration::MidiPortDescriptor::get_state()
566 {
567         XMLNode* root = new XMLNode("MIDI-port");
568
569         root->add_property("tag", tag);
570         root->add_property("device", device);
571         root->add_property("type", type);
572         root->add_property("mode", mode);
573
574         return *root;
575 }
576
577 XMLNode&
578 Configuration::option_node(const string & name, const string & value)
579 {
580         XMLNode* root = new XMLNode("Option");
581
582         root->add_property("name", name);
583         root->add_property("value", value);
584         
585         return *root;
586 }
587
588 string
589 Configuration::get_raid_path()
590 {
591         return raid_path;
592 }
593
594 void
595 Configuration::set_raid_path(string path)
596 {
597 #ifdef HAVE_WORDEXP
598         /* Handle tilde and environment variable expansion in session path */
599         wordexp_t expansion;
600         switch (wordexp (path.c_str(), &expansion, WRDE_NOCMD|WRDE_UNDEF)) {
601         case 0:
602                 break;
603         default:
604                 error << _("illegal or badly-formed string used for RAID path") << endmsg;
605                 return;
606         }
607
608         if (expansion.we_wordc > 1) {
609                 error << _("RAID search path is ambiguous") << endmsg;
610                 return;
611         }
612
613         raid_path = expansion.we_wordv[0];
614         orig_raid_path = path;
615         wordfree (&expansion);
616 #else
617         raid_path = orig_raid_path = path;
618 #endif
619
620         if (user_configuration) {
621                 raid_path_is_user = true;
622         }
623 }
624
625 uint32_t
626 Configuration::get_minimum_disk_io()
627 {
628         return minimum_disk_io_bytes;
629 }
630         
631 void
632 Configuration::set_minimum_disk_io(uint32_t min)
633 {
634         minimum_disk_io_bytes = min;
635         if (user_configuration) {
636                 minimum_disk_io_bytes_is_user = true;
637         }
638 }
639
640 float
641 Configuration::get_track_buffer()
642 {
643         return track_buffer_seconds;
644 }
645
646 void 
647 Configuration::set_track_buffer(float buffer)
648 {
649         track_buffer_seconds = buffer;
650         if (user_configuration) {
651                 track_buffer_seconds_is_user = true;
652         }
653 }
654
655 bool 
656 Configuration::does_hiding_groups_deactivates_groups()
657 {
658         return hiding_groups_deactivates_groups;
659 }
660
661 void 
662 Configuration::set_hiding_groups_deactivates_groups(bool hiding)
663 {
664         hiding_groups_deactivates_groups = hiding;
665         if (user_configuration) {
666                 hiding_groups_deactivates_groups_is_user = true;
667         }
668 }
669
670 string
671 Configuration::get_auditioner_output_left ()
672 {
673         return auditioner_output_left;
674 }
675
676 void
677 Configuration::set_auditioner_output_left (string str)
678 {
679         auditioner_output_left = str;
680         if (user_configuration) {
681                 auditioner_output_left_is_user = true;
682         }
683 }
684
685 string
686 Configuration::get_auditioner_output_right ()
687 {
688         return auditioner_output_right;
689 }
690
691 void
692 Configuration::set_auditioner_output_right (string str)
693 {
694         auditioner_output_right = str;
695         if (user_configuration) {
696                 auditioner_output_right_is_user = true;
697         }
698 }
699
700 bool
701 Configuration::get_mute_affects_pre_fader()
702 {
703         return mute_affects_pre_fader;
704 }
705
706 void 
707 Configuration::set_mute_affects_pre_fader (bool affects)
708 {
709         mute_affects_pre_fader = affects;
710         if (user_configuration) {
711                 mute_affects_pre_fader_is_user = true;
712         }
713 }
714
715 bool 
716 Configuration::get_mute_affects_post_fader()
717 {
718         return mute_affects_post_fader;
719 }
720
721 void 
722 Configuration::set_mute_affects_post_fader (bool affects)
723 {
724         mute_affects_post_fader = affects;
725         if (user_configuration) {
726                 mute_affects_post_fader_is_user = true;
727         }
728 }
729
730 bool 
731 Configuration::get_mute_affects_control_outs()
732 {
733         return mute_affects_control_outs;
734 }
735
736 void 
737 Configuration::set_mute_affects_control_outs (bool affects)
738 {
739         mute_affects_control_outs = affects;
740         if (user_configuration) {
741                 mute_affects_control_outs_is_user = true;
742         }
743 }
744
745 bool 
746 Configuration::get_mute_affects_main_outs()
747 {
748         return mute_affects_main_outs;
749 }
750
751 void 
752 Configuration::set_mute_affects_main_outs (bool affects)
753 {
754         mute_affects_main_outs = affects;
755         if (user_configuration) {
756                 mute_affects_main_outs_is_user = true;
757         }
758 }
759
760 bool 
761 Configuration::get_solo_latch()
762 {
763         return solo_latch;
764 }
765
766 void 
767 Configuration::set_solo_latch (bool latch)
768 {
769         solo_latch = latch;
770         if (user_configuration) {
771                 solo_latch_is_user = true;
772         }
773 }
774
775 XMLNode *
776 Configuration::get_keys () const
777 {
778         return key_node;
779 }
780
781 void
782 Configuration::set_keys (XMLNode* keys)
783 {
784         key_node = keys;
785 }
786
787 uint32_t
788 Configuration::get_disk_choice_space_threshold ()
789 {
790         return disk_choice_space_threshold;
791 }
792
793 void
794 Configuration::set_disk_choice_space_threshold (uint32_t val)
795 {
796         disk_choice_space_threshold = val;
797         if (user_configuration) {
798                 disk_choice_space_threshold_is_user = true;
799         }
800 }
801
802 string
803 Configuration::get_mmc_port_name ()
804 {
805         return mmc_port_name;
806 }
807
808 void
809 Configuration::set_mmc_port_name (string name)
810 {
811         mmc_port_name = name;
812         if (user_configuration) {
813                 mmc_port_name_is_user = true;
814         }
815 }
816
817 string
818 Configuration::get_mtc_port_name ()
819 {
820         return mtc_port_name;
821 }
822
823 void
824 Configuration::set_mtc_port_name (string name)
825 {
826         mtc_port_name = name;
827         if (user_configuration) {
828                 mtc_port_name_is_user = true;
829         }
830 }
831
832 string
833 Configuration::get_midi_port_name ()
834 {
835         return midi_port_name;
836 }
837
838 void
839 Configuration::set_midi_port_name (string name)
840 {
841         midi_port_name = name;
842         if (user_configuration) {
843                 midi_port_name_is_user = true;
844         }
845 }
846
847 uint32_t
848 Configuration::get_midi_feedback_interval_ms ()
849 {
850         return midi_feedback_interval_ms;
851 }
852
853 void
854 Configuration::set_midi_feedback_interval_ms (uint32_t val)
855 {
856         midi_feedback_interval_ms = val;
857         if (user_configuration) {
858                 midi_feedback_interval_ms_is_user = true;
859         }
860 }
861
862 bool
863 Configuration::get_use_hardware_monitoring()
864 {
865         return use_hardware_monitoring;
866 }
867
868 void
869 Configuration::set_use_hardware_monitoring(bool yn)
870 {
871         use_hardware_monitoring = yn;
872         if (user_configuration) {
873                 use_hardware_monitoring_is_user = true;
874         }
875 }
876
877 bool
878 Configuration::get_jack_time_master()
879 {
880         return be_jack_time_master;
881 }
882
883 void
884 Configuration::set_jack_time_master(bool yn)
885 {
886         be_jack_time_master = yn;
887         if (user_configuration) {
888                 be_jack_time_master_is_user = true;
889         }
890 }
891
892 bool
893 Configuration::get_native_format_is_bwf()
894 {
895         return native_format_is_bwf;
896 }
897
898 void
899 Configuration::set_native_format_is_bwf(bool yn)
900 {
901         native_format_is_bwf = yn;
902         if (user_configuration) {
903                 native_format_is_bwf_is_user = true;
904         }
905 }
906
907 bool
908 Configuration::get_trace_midi_input ()
909 {
910         return trace_midi_input;
911 }
912
913 void
914 Configuration::set_trace_midi_input (bool yn)
915 {
916         trace_midi_input = yn;
917         if (user_configuration) {
918                 trace_midi_input_is_user = true;
919         }
920 }
921
922 bool
923 Configuration::get_trace_midi_output ()
924 {
925         return trace_midi_output;
926 }
927
928 void
929 Configuration::set_trace_midi_output (bool yn)
930 {
931         trace_midi_output = yn;
932         if (user_configuration) {
933                 trace_midi_output_is_user = true;
934         }
935 }
936
937 bool
938 Configuration::get_plugins_stop_with_transport ()
939 {
940         return plugins_stop_with_transport;
941 }
942
943 void
944 Configuration::set_plugins_stop_with_transport (bool yn)
945 {
946         plugins_stop_with_transport = yn;
947         if (user_configuration) {
948                 plugins_stop_with_transport_is_user = true;
949         }
950 }
951
952 bool
953 Configuration::get_use_sw_monitoring ()
954 {
955         return use_sw_monitoring;
956 }
957
958 void
959 Configuration::set_use_sw_monitoring (bool yn)
960 {
961         use_sw_monitoring = yn;
962         if (user_configuration) {
963                 use_sw_monitoring_is_user = true;
964         }
965 }
966
967 bool
968 Configuration::get_stop_recording_on_xrun ()
969 {
970         return stop_recording_on_xrun;
971 }
972
973 void
974 Configuration::set_stop_recording_on_xrun (bool yn)
975 {
976         stop_recording_on_xrun = yn;
977         if (user_configuration) {
978                 stop_recording_on_xrun_is_user = true;
979         }
980 }
981
982 bool
983 Configuration::get_verify_remove_last_capture ()
984 {
985         return verify_remove_last_capture;
986 }
987
988 void
989 Configuration::set_verify_remove_last_capture (bool yn)
990 {
991         verify_remove_last_capture = yn;
992         if (user_configuration) {
993                 verify_remove_last_capture_is_user = true;
994         }
995 }
996
997 bool
998 Configuration::get_stop_at_session_end ()
999 {
1000         return stop_at_session_end;
1001 }
1002
1003 void
1004 Configuration::set_stop_at_session_end (bool yn)
1005 {
1006         stop_at_session_end = yn;
1007         if (user_configuration) {
1008                 stop_at_session_end_is_user = true;
1009         }
1010 }
1011
1012 bool
1013 Configuration::get_seamless_looping ()
1014 {
1015         return seamless_looping;
1016 }
1017
1018 void
1019 Configuration::set_seamless_looping (bool yn)
1020 {
1021         seamless_looping = yn;
1022         if (user_configuration) {
1023                 seamless_looping_is_user = true;
1024         }
1025 }
1026
1027 bool
1028 Configuration::get_auto_xfade ()
1029 {
1030         return auto_xfade;
1031 }
1032
1033 void
1034 Configuration::set_auto_xfade (bool yn)
1035 {
1036         auto_xfade = yn;
1037         if (user_configuration) {
1038                 auto_xfade_is_user = true;
1039         }
1040 }
1041
1042 string
1043 Configuration::get_user_ardour_path ()
1044 {
1045         string path;
1046         char* envvar;
1047         
1048         if ((envvar = getenv ("HOME")) == 0 || strlen (envvar) == 0) {
1049                 return "/";
1050         }
1051                 
1052         path = envvar;
1053         path += "/.ardour/";
1054         
1055         return path;
1056 }
1057
1058 string
1059 Configuration::get_system_ardour_path ()
1060 {
1061         string path;
1062         char* envvar;
1063
1064         if ((envvar = getenv ("ARDOUR_DATA_PATH")) != 0) {
1065                 path += envvar;
1066                 if (path[path.length()-1] != ':') {
1067                         path += ':';
1068                 }
1069         }
1070
1071         path += DATA_DIR;
1072         path += "/ardour/";
1073         
1074         return path;
1075 }
1076
1077 bool 
1078 Configuration::get_no_new_session_dialog()
1079 {
1080         return no_new_session_dialog;
1081 }
1082
1083 void 
1084 Configuration::set_no_new_session_dialog(bool yn)
1085 {
1086         no_new_session_dialog = yn;
1087         if (user_configuration) {
1088                 no_new_session_dialog_is_user = true;
1089         }
1090 }
1091
1092 bool
1093 Configuration::get_timecode_source_is_synced()
1094 {
1095         return timecode_source_is_synced;
1096 }
1097
1098 void
1099 Configuration::set_timecode_source_is_synced (bool yn)
1100 {
1101         timecode_source_is_synced = yn;
1102         if (user_configuration) {
1103                 timecode_source_is_synced_is_user = true;
1104         }
1105 }
1106
1107 bool
1108 Configuration::get_use_vst ()
1109 {
1110         return use_vst;
1111 }
1112
1113 void
1114 Configuration::set_use_vst (bool yn)
1115 {
1116         use_vst = yn;
1117 }
1118
1119 gain_t
1120 Configuration::get_quieten_at_speed()
1121 {
1122         return speed_quietning;
1123 }
1124
1125 void
1126 Configuration::set_quieten_at_speed (float gain_coefficient)
1127 {
1128         speed_quietning = gain_coefficient;
1129         if (user_configuration) {
1130                 quieten_at_speed_is_user = true;
1131         }
1132 }