2 Copyright (C) 1999-2006 Paul Davis
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.
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.
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.
22 #include <cstdio> /* for snprintf, grrr */
24 #include <pbd/failed_constructor.h>
25 #include <pbd/xml++.h>
27 #include <ardour/ardour.h>
28 #include <ardour/configuration.h>
29 #include <ardour/audio_diskstream.h>
30 #include <ardour/destructive_filesource.h>
31 #include <ardour/control_protocol_manager.h>
35 using namespace ARDOUR;
39 /* this is global so that we do not have to indirect through an object pointer
44 float speed_quietning = 0.251189; // -12dB reduction for ffwd or rewind
47 Configuration::Configuration ()
49 /* construct variables */
50 #undef CONFIG_VARIABLE
51 #undef CONFIG_VARIABLE_SPECIAL
52 #define CONFIG_VARIABLE(Type,var,name,value) var (name,value),
53 #define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) var (name,value,mutator),
54 #include "ardour/configuration_vars.h"
55 #undef CONFIG_VARIABLE
56 #undef CONFIG_VARIABLE_SPECIAL
58 user_configuration (false)
60 _control_protocol_state = 0;
63 Configuration::~Configuration ()
68 Configuration::load_state ()
72 /* load system configuration first */
74 rcfile = find_config_file ("ardour_system.rc");
76 if (rcfile.length()) {
80 cerr << string_compose (_("loading system configuration file %1"), rcfile) << endl;
82 if (!tree.read (rcfile.c_str())) {
83 error << string_compose(_("Ardour: cannot read system configuration file \"%1\""), rcfile) << endmsg;
87 if (set_state (*tree.root())) {
88 error << string_compose(_("Ardour: system configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
93 /* from this point on, all configuration changes are user driven */
95 user_configuration = true;
97 /* now load configuration file for user */
99 rcfile = find_config_file ("ardour.rc");
101 if (rcfile.length()) {
105 cerr << string_compose (_("loading user configuration file %1"), rcfile) << endl;
107 if (!tree.read (rcfile)) {
108 error << string_compose(_("Ardour: cannot read configuration file \"%1\""), rcfile) << endmsg;
112 if (set_state (*tree.root())) {
113 error << string_compose(_("Ardour: user configuration file \"%1\" not loaded successfully."), rcfile) << endmsg;
122 Configuration::save_state()
127 /* Note: this only writes the per-user file, and therefore
128 only saves variables marked as user-set or modified
131 rcfile = get_user_ardour_path ();
132 rcfile += "ardour.rc";
134 if (rcfile.length()) {
135 tree.set_root (&state (true));
136 if (!tree.write (rcfile.c_str())){
137 error << string_compose (_("Config file %1 not saved"), rcfile) << endmsg;
146 Configuration::get_state ()
148 return state (false);
152 Configuration::state (bool user_only)
154 XMLNode* root = new XMLNode("Ardour");
155 LocaleGuard lg (X_("POSIX"));
157 typedef map<string, MidiPortDescriptor*>::const_iterator CI;
158 for(CI m = midi_ports.begin(); m != midi_ports.end(); ++m){
159 root->add_child_nocopy(m->second->get_state());
162 XMLNode* node = new XMLNode("Config");
164 #undef CONFIG_VARIABLE
165 #undef CONFIG_VARIABLE_SPECIAL
166 #define CONFIG_VARIABLE(type,var,name,value) \
167 if (!user_only || var.is_user()) var.add_to_node (*node);
168 #define CONFIG_VARIABLE_SPECIAL(type,var,name,value,mutator) \
169 if (!user_only || var.is_user()) var.add_to_node (*node);
170 #include "ardour/configuration_vars.h"
171 #undef CONFIG_VARIABLE
172 #undef CONFIG_VARIABLE_SPECIAL
174 root->add_child_nocopy (*node);
177 root->add_child_copy (*_extra_xml);
180 root->add_child_nocopy (ControlProtocolManager::instance().get_state());
186 Configuration::set_state (const XMLNode& root)
188 if (root.name() != "Ardour") {
192 XMLNodeList nlist = root.children();
193 XMLNodeConstIterator niter;
196 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
200 if (node->name() == "MIDI-port") {
203 pair<string,MidiPortDescriptor*> newpair;
204 newpair.second = new MidiPortDescriptor (*node);
205 newpair.first = newpair.second->tag;
206 midi_ports.insert (newpair);
209 catch (failed_constructor& err) {
210 warning << _("ill-formed MIDI port specification in ardour rcfile (ignored)") << endmsg;
213 } else if (node->name() == "Config") {
215 #undef CONFIG_VARIABLE
216 #undef CONFIG_VARIABLE_SPECIAL
217 #define CONFIG_VARIABLE(type,var,name,value) \
218 var.set_from_node (*node); \
219 var.set_is_user (user_configuration);
220 #define CONFIG_VARIABLE_SPECIAL(type,var,name,value,mutator) \
221 var.set_from_node (*node); \
222 var.set_is_user (user_configuration);
223 #include "ardour/configuration_vars.h"
224 #undef CONFIG_VARIABLE
225 #undef CONFIG_VARIABLE_SPECIAL
227 } else if (node->name() == "extra") {
228 _extra_xml = new XMLNode (*node);
230 } else if (node->name() == ControlProtocolManager::state_node_name) {
231 _control_protocol_state = new XMLNode (*node);
235 AudioDiskstream::set_disk_io_chunk_frames (minimum_disk_io_bytes.get() / sizeof (Sample));
240 Configuration::MidiPortDescriptor::MidiPortDescriptor (const XMLNode& node)
242 const XMLProperty *prop;
243 bool have_tag = false;
244 bool have_device = false;
245 bool have_type = false;
246 bool have_mode = false;
248 if ((prop = node.property ("tag")) != 0) {
253 if ((prop = node.property ("device")) != 0) {
254 device = prop->value();
258 if ((prop = node.property ("type")) != 0) {
259 type = prop->value();
263 if ((prop = node.property ("mode")) != 0) {
264 mode = prop->value();
268 if (!have_tag || !have_device || !have_type || !have_mode) {
269 throw failed_constructor();
274 Configuration::MidiPortDescriptor::get_state()
276 XMLNode* root = new XMLNode("MIDI-port");
278 root->add_property("tag", tag);
279 root->add_property("device", device);
280 root->add_property("type", type);
281 root->add_property("mode", mode);