Fix double-display of VST preset names (#3576)
[ardour.git] / gtk2_ardour / engine_dialog.cc
index 05d953aeabc40742376c1107bdaf44cc6c360cc1..a3c3edd1cc4815fad04270771516184b442e7fb9 100644 (file)
@@ -1,3 +1,22 @@
+/*
+    Copyright (C) 2010 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include <vector>
 #include <cmath>
 #include <fstream>
@@ -46,6 +65,10 @@ EngineControl::EngineControl ()
          priority_spinner (priority_adjustment),
          ports_adjustment (128, 8, 1024, 1, 16),
          ports_spinner (ports_adjustment),
+         input_latency_adjustment (0, 0, 99999, 1),
+         input_latency (input_latency_adjustment),
+         output_latency_adjustment (0, 0, 99999, 1),
+         output_latency (output_latency_adjustment),
          realtime_button (_("Realtime")),
          no_memory_lock_button (_("Do not lock memory")),
          unlock_memory_button (_("Unlock memory")),
@@ -115,6 +138,7 @@ EngineControl::EngineControl ()
 #else
        strings.push_back (X_("ALSA"));
        strings.push_back (X_("OSS"));
+       strings.push_back (X_("FreeBoB"));
        strings.push_back (X_("FFADO"));
 #endif
        strings.push_back (X_("NetJACK"));
@@ -122,73 +146,86 @@ EngineControl::EngineControl ()
        set_popdown_strings (driver_combo, strings);
        driver_combo.set_active_text (strings.front());
 
-       driver_combo.signal_changed().connect (mem_fun (*this, &EngineControl::driver_changed));
+       driver_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::driver_changed));
        driver_changed ();
 
        strings.clear ();
-       strings.push_back (_("Playback/Recording on 1 Device"));
-       strings.push_back (_("Playback/Recording on 2 Devices"));
+       strings.push_back (_("Playback/recording on 1 device"));
+       strings.push_back (_("Playback/recording on 2 devices"));
        strings.push_back (_("Playback only"));
        strings.push_back (_("Recording only"));
        set_popdown_strings (audio_mode_combo, strings);
        audio_mode_combo.set_active_text (strings.front());
 
-       audio_mode_combo.signal_changed().connect (mem_fun (*this, &EngineControl::audio_mode_changed));
+       audio_mode_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::audio_mode_changed));
        audio_mode_changed ();
 
+       strings.clear ();
+       strings.push_back (_("None"));
+       strings.push_back (_("seq"));
+       strings.push_back (_("raw"));
+       set_popdown_strings (midi_driver_combo, strings);
+       midi_driver_combo.set_active_text (strings.front ());
+
        row = 0;
 
-       label = manage (new Label (_("Driver")));
+       label = manage (new Label (_("Driver:")));
+       label->set_alignment (0, 0.5);
        basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        basic_packer.attach (driver_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        row++;
 
-       label = manage (new Label (_("Interface")));
+       label = manage (new Label (_("Interface:")));
+       label->set_alignment (0, 0.5);
        basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        basic_packer.attach (interface_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        row++;
 
-       label = manage (new Label (_("Sample Rate")));
+       label = manage (new Label (_("Sample rate:")));
+       label->set_alignment (0, 0.5);
        basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        basic_packer.attach (sample_rate_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        row++;
 
-       label = manage (new Label (_("Buffer size")));
+       label = manage (new Label (_("Buffer size:")));
+       label->set_alignment (0, 0.5);
        basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        basic_packer.attach (period_size_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        row++;
 
 #ifndef __APPLE__
-       label = manage (new Label (_("Number of buffers")));
+       label = manage (new Label (_("Number of buffers:")));
+       label->set_alignment (0, 0.5);
        basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        basic_packer.attach (periods_spinner, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        periods_spinner.set_value (2);
        row++;
 #endif
 
-       label = manage (new Label (_("Approximate latency")));
-       label->set_alignment (0.0, 0.5);
+       label = manage (new Label (_("Approximate latency:")));
+       label->set_alignment (0, 0.5);
        basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        basic_packer.attach (latency_label, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        row++;
 
-       sample_rate_combo.signal_changed().connect (mem_fun (*this, &EngineControl::redisplay_latency));
-       periods_adjustment.signal_value_changed().connect (mem_fun (*this, &EngineControl::redisplay_latency));
-       period_size_combo.signal_changed().connect (mem_fun (*this, &EngineControl::redisplay_latency));
+       sample_rate_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency));
+       periods_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency));
+       period_size_combo.signal_changed().connect (sigc::mem_fun (*this, &EngineControl::redisplay_latency));
        redisplay_latency();
        row++;
        /* no audio mode with CoreAudio, its duplex or nuthin' */
 
 #ifndef __APPLE__
-       label = manage (new Label (_("Audio Mode")));
+       label = manage (new Label (_("Audio mode:")));
+       label->set_alignment (0, 0.5);
        basic_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        basic_packer.attach (audio_mode_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        row++;
 #endif
 
-       interface_combo.set_size_request (125, -1);
-       input_device_combo.set_size_request (125, -1);
-       output_device_combo.set_size_request (125, -1);
+       interface_combo.set_size_request (250, -1);
+       input_device_combo.set_size_request (250, -1);
+       output_device_combo.set_size_request (250, -1);
 
        /*
 
@@ -198,8 +235,8 @@ EngineControl::EngineControl ()
                stop_button.set_sensitive (false);
        }
 
-       start_button.signal_clicked().connect (mem_fun (*this, &EngineControl::start_engine));
-       stop_button.signal_clicked().connect (mem_fun (*this, &EngineControl::start_engine));
+       start_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::start_engine));
+       stop_button.signal_clicked().connect (sigc::mem_fun (*this, &EngineControl::start_engine));
        */
 
        button_box.pack_start (start_button, false, false);
@@ -216,7 +253,7 @@ EngineControl::EngineControl ()
        ++row;
 
        realtime_button.set_active (true);
-       realtime_button.signal_toggled().connect (mem_fun (*this, &EngineControl::realtime_changed));
+       realtime_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::realtime_changed));
        realtime_changed ();
 
 #if PROVIDE_TOO_MANY_OPTIONS
@@ -266,15 +303,21 @@ EngineControl::EngineControl ()
        ++row;
 
 #endif /* PROVIDE_TOO_MANY_OPTIONS */
-       label = manage (new Label (_("Number of ports")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Number of ports:")));
+       label->set_alignment (0, 0.5);
        options_packer.attach (ports_spinner, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0));
        options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
 
+       label = manage (new Label (_("MIDI driver:")));
+       label->set_alignment (0, 0.5);
+       options_packer.attach (midi_driver_combo, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0));
+       options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
+       ++row;
+
 #ifndef __APPLE__
-       label = manage (new Label (_("Dither")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Dither:")));
+       label->set_alignment (0, 0.5);
        options_packer.attach (dither_mode_combo, 1, 2, row, row + 1, FILL|EXPAND, AttachOptions(0));
        options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
@@ -304,36 +347,42 @@ EngineControl::EngineControl ()
        row = 0;
 
 #ifndef __APPLE__
-       label = manage (new Label (_("Input device")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Input device:")));
+       label->set_alignment (0, 0.5);
        device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        device_packer.attach (input_device_combo, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
-       label = manage (new Label (_("Output device")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Output device:")));
+       label->set_alignment (0, 0.5);
        device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        device_packer.attach (output_device_combo, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
 #endif
-       label = manage (new Label (_("Input channels")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Input channels:")));
+       label->set_alignment (0, 0.5);
        device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        device_packer.attach (input_channels, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
-       label = manage (new Label (_("Output channels")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Output channels:")));
+       label->set_alignment (0, 0.5);
        device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        device_packer.attach (output_channels, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
-       label = manage (new Label (_("Hardware input latency (samples)")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Hardware input latency:")));
+       label->set_alignment (0, 0.5);
        device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        device_packer.attach (input_latency, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0);
+       label = manage (new Label (_("samples")));
+       label->set_alignment (0, 0.5);
+       device_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
-       label = manage (new Label (_("Hardware output latency (samples)")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (new Label (_("Hardware output latency:")));
+       label->set_alignment (0, 0.5);
        device_packer.attach (*label, 0, 1, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        device_packer.attach (output_latency, 1, 2, row, row+1, FILL|EXPAND, (AttachOptions) 0);
+       label = manage (new Label (_("samples")));
+       label->set_alignment (0, 0.5);
+       device_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
 
        basic_hbox.pack_start (basic_packer, false, false);
@@ -362,12 +411,10 @@ EngineControl::build_command_line (vector<string>& cmd)
 {
        string str;
        string driver;
-       bool using_oss = false;
        bool using_alsa = false;
        bool using_coreaudio = false;
-       bool using_netjack = false;
-       bool using_ffado = false;
        bool using_dummy = false;
+       bool using_ffado = false;
 
        /* first, path to jackd */
 
@@ -376,11 +423,14 @@ EngineControl::build_command_line (vector<string>& cmd)
        /* now jackd arguments */
 
        str = timeout_combo.get_active_text ();
+       
        if (str != _("Ignore")) {
+
                double secs = 0;
                uint32_t msecs;
                secs = atof (str);
                msecs = (uint32_t) floor (secs * 1000.0);
+               
                if (msecs > 0) {
                        cmd.push_back ("-t");
                        cmd.push_back (to_string (msecs, std::dec));
@@ -398,6 +448,8 @@ EngineControl::build_command_line (vector<string>& cmd)
                cmd.push_back ("-R");
                cmd.push_back ("-P");
                cmd.push_back (to_string ((uint32_t) floor (priority_spinner.get_value()), std::dec));
+       } else {
+               cmd.push_back ("-r"); /* override jackd's default --realtime */
        }
 
        if (unlock_memory_button.get_active()) {
@@ -417,31 +469,22 @@ EngineControl::build_command_line (vector<string>& cmd)
        cmd.push_back ("-d");
 
        driver = driver_combo.get_active_text ();
+       
        if (driver == X_("ALSA")) {
                using_alsa = true;
                cmd.push_back ("alsa");
        } else if (driver == X_("OSS")) {
-               using_oss = true;
                cmd.push_back ("oss");
        } else if (driver == X_("CoreAudio")) {
                using_coreaudio = true;
                cmd.push_back ("coreaudio");
        } else if (driver == X_("NetJACK")) {
-               using_netjack = true;
                cmd.push_back ("netjack");
+       } else if (driver == X_("FreeBoB")) {
+               cmd.push_back ("freebob");
        } else if (driver == X_("FFADO")) {
                using_ffado = true;
-
-               /* do this until FFADO becomes the standard */
-
-               char* hack = getenv ("ARDOUR_FIREWIRE_DRIVER_NAME");
-
-               if (hack) {
-                       cmd.push_back (hack);
-               } else {
-                       cmd.push_back ("freebob");
-               }
-
+               cmd.push_back ("firewire");
        } else if ( driver == X_("Dummy")) {
                using_dummy = true;
                cmd.push_back ("dummy");
@@ -468,6 +511,7 @@ EngineControl::build_command_line (vector<string>& cmd)
 
                        cmd.push_back ("-C");
                        cmd.push_back (input_device);
+                       
                        cmd.push_back ("-P");
                        cmd.push_back (output_device);
 
@@ -477,7 +521,7 @@ EngineControl::build_command_line (vector<string>& cmd)
                        cmd.push_back ("-C");
                }
 
-               if (! using_dummy ) {
+               if (!using_dummy) {
                        cmd.push_back ("-n");
                        cmd.push_back (to_string ((uint32_t) floor (periods_spinner.get_value()), std::dec));
                }
@@ -488,6 +532,23 @@ EngineControl::build_command_line (vector<string>& cmd)
 
        cmd.push_back ("-p");
        cmd.push_back (period_size_combo.get_active_text());
+       
+       if (using_alsa || using_ffado || using_coreaudio) {
+
+               double val = input_latency_adjustment.get_value();
+
+                if (val) {
+                        cmd.push_back ("-I");
+                        cmd.push_back (to_string ((uint32_t) val, std::dec));
+                }
+
+                val = output_latency_adjustment.get_value();
+                
+               if (val) {
+                        cmd.push_back ("-O");
+                        cmd.push_back (to_string ((uint32_t) val, std::dec));
+                }
+       }
 
        if (using_alsa) {
 
@@ -530,6 +591,13 @@ EngineControl::build_command_line (vector<string>& cmd)
                        cmd.push_back ("-s");
                }
 
+               str = midi_driver_combo.get_active_text ();
+
+               if (str == _("seq")) {
+                       cmd.push_back ("-X seq");
+               } else if (str == _("raw")) {
+                       cmd.push_back ("-X raw");
+               }
        } else if (using_coreaudio) {
 
 #ifdef __APPLE__
@@ -545,10 +613,6 @@ EngineControl::build_command_line (vector<string>& cmd)
                cmd.push_back (device);
 #endif
 
-       } else if (using_oss) {
-
-       } else if (using_netjack) {
-
        }
 }
 
@@ -577,7 +641,7 @@ EngineControl::setup_engine ()
                return 1; // try again
        }
 
-       Glib::ustring jackdrc_path = Glib::get_home_dir();
+       std::string jackdrc_path = Glib::get_home_dir();
        jackdrc_path += "/.jackdrc";
 
        ofstream jackdrc (jackdrc_path.c_str());
@@ -620,6 +684,8 @@ EngineControl::enumerate_devices (const string& driver)
 #ifndef __APPLE__
        } else if (driver == "ALSA") {
                devices[driver] = enumerate_alsa_devices ();
+       } else if (driver == "FreeBOB") {
+               devices[driver] = enumerate_freebob_devices ();
        } else if (driver == "FFADO") {
                devices[driver] = enumerate_ffado_devices ();
        } else if (driver == "OSS") {
@@ -771,28 +837,11 @@ EngineControl::enumerate_alsa_devices ()
 
                        while (snd_ctl_pcm_next_device (handle, &device) >= 0 && device >= 0) {
 
-                               bool have_playback = false;
-                               bool have_capture = false;
-
-                               /* find duplex devices only */
-
-                               snd_pcm_info_set_device (pcminfo, device);
-                               snd_pcm_info_set_subdevice (pcminfo, 0);
-                               snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_CAPTURE);
-
-                               if (snd_ctl_pcm_info (handle, pcminfo) >= 0) {
-                                       have_capture = true;
-                               }
-
                                snd_pcm_info_set_device (pcminfo, device);
                                snd_pcm_info_set_subdevice (pcminfo, 0);
                                snd_pcm_info_set_stream (pcminfo, SND_PCM_STREAM_PLAYBACK);
 
                                if (snd_ctl_pcm_info (handle, pcminfo) >= 0) {
-                                       have_playback = true;
-                               }
-
-                               if (have_capture && have_playback) {
                                        devs.push_back (snd_pcm_info_get_name (pcminfo));
                                        devname += ',';
                                        devname += to_string (device, std::dec);
@@ -821,6 +870,7 @@ EngineControl::enumerate_freebob_devices ()
        vector<string> devs;
        return devs;
 }
+
 vector<string>
 EngineControl::enumerate_oss_devices ()
 {
@@ -853,7 +903,7 @@ EngineControl::driver_changed ()
 
        vector<string>& strings = devices[driver];
 
-       if (strings.empty() && driver != "FFADO" && driver != "Dummy") {
+       if (strings.empty() && driver != "FreeBoB" && driver != "FFADO" && driver != "Dummy") {
                error << string_compose (_("No devices found for driver \"%1\""), driver) << endmsg;
                return;
        }
@@ -911,12 +961,13 @@ EngineControl::redisplay_latency ()
        snprintf (buf, sizeof(buf), "%.1fmsec", (periods * period_size) / (rate/1000.0));
 
        latency_label.set_text (buf);
+       latency_label.set_alignment (0, 0.5);
 }
 
 void
 EngineControl::audio_mode_changed ()
 {
-       Glib::ustring str = audio_mode_combo.get_active_text();
+       std::string str = audio_mode_combo.get_active_text();
 
        if (str == _("Playback/Recording on 1 Device")) {
                input_device_combo.set_sensitive (false);
@@ -959,7 +1010,7 @@ EngineControl::find_jack_servers (vector<string>& strings)
        if (getenv ("ARDOUR_WITH_JACK")) {
                /* no other options - only use the JACK we supply */
                if (strings.empty()) {
-                       fatal << _("JACK appears to be missing from the Ardour bundle") << endmsg;
+                       fatal << string_compose (_("JACK appears to be missing from the %1 bundle"), PROGRAM_NAME) << endmsg;
                        /*NOTREACHED*/
                }
                return;
@@ -1053,7 +1104,7 @@ EngineControl::get_state ()
 {
        XMLNode* root = new XMLNode ("AudioSetup");
        XMLNode* child;
-       Glib::ustring path;
+       std::string path;
 
        child = new XMLNode ("periods");
        child->add_property ("val", to_string (periods_adjustment.get_value(), std::dec));
@@ -1155,6 +1206,10 @@ EngineControl::get_state ()
        child->add_property ("val", output_device_combo.get_active_text());
        root->add_child_nocopy (*child);
 
+       child = new XMLNode ("mididriver");
+       child->add_property ("val", midi_driver_combo.get_active_text());
+       root->add_child_nocopy (*child);
+
        return *root;
 }
 
@@ -1166,15 +1221,21 @@ EngineControl::set_state (const XMLNode& root)
        XMLNode* child;
        XMLProperty* prop = NULL;
        bool using_dummy = false;
+       bool using_ffado = false;
 
        int val;
        string strval;
 
        if ( (child = root.child ("driver"))){
                prop = child->property("val");
+               
                if (prop && (prop->value() == "Dummy") ) {
                        using_dummy = true;
                }
+               if (prop && (prop->value() == "FFADO") ) {
+                       using_ffado = true;
+               }
+
        }
 
        clist = root.children();
@@ -1187,8 +1248,15 @@ EngineControl::set_state (const XMLNode& root)
 
                if (!prop || prop->value().empty()) {
 
-                       if ( using_dummy && ( child->name() == "interface" || child->name() == "inputdevice" || child->name() == "outputdevice" ))
+                       if (((using_dummy || using_ffado) 
+                               && ( child->name() == "interface" 
+                                       || child->name() == "inputdevice" 
+                                       || child->name() == "outputdevice")) 
+                               || child->name() == "timeout")
+                       {
                                continue;
+                       }
+                       
                        error << string_compose (_("AudioSetup value for %1 is missing data"), child->name()) << endmsg;
                        continue;
                }
@@ -1255,24 +1323,34 @@ EngineControl::set_state (const XMLNode& root)
                } else if (child->name() == "periodsize") {
                        period_size_combo.set_active_text(strval);
                } else if (child->name() == "serverpath") {
-                       /* do not allow us to use a server path that doesn't
-                          exist on this system. this handles cases where
-                          the user has an RC file listing a serverpath
-                          from some other machine.
-                       */
-                       vector<string>::iterator x;
-                       for (x = server_strings.begin(); x != server_strings.end(); ++x) {
-                               if (*x == strval) {
-                                       break;
-                               }
-                       }
-                       if (x != server_strings.end()) {
-                               serverpath_combo.set_active_text (strval);
-                       } else {
-                               warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"),
-                                                            strval)
-                                       << endmsg;
-                       }
+                        
+                        /* only attempt to set this if we have bothered to look
+                           up server names already. otherwise this is all
+                           redundant (actually, all of this dialog/widget
+                           is redundant in that case ...)
+                        */
+                        
+                        if (!server_strings.empty()) {
+                                /* do not allow us to use a server path that doesn't
+                                   exist on this system. this handles cases where
+                                   the user has an RC file listing a serverpath
+                                   from some other machine.
+                                */
+                                vector<string>::iterator x;
+                                for (x = server_strings.begin(); x != server_strings.end(); ++x) {
+                                        if (*x == strval) {
+                                                break;
+                                        }
+                                }
+                                if (x != server_strings.end()) {
+                                        serverpath_combo.set_active_text (strval);
+                                } else {
+                                        warning << string_compose (_("configuration files contain a JACK server path that doesn't exist (%1)"),
+                                                                   strval)
+                                                << endmsg;
+                                }
+                        }
+                        
                } else if (child->name() == "driver") {
                        driver_combo.set_active_text(strval);
                } else if (child->name() == "interface") {
@@ -1287,6 +1365,8 @@ EngineControl::set_state (const XMLNode& root)
                        input_device_combo.set_active_text(strval);
                } else if (child->name() == "outputdevice") {
                        output_device_combo.set_active_text(strval);
+               } else if (child->name() == "mididriver") {
+                       midi_driver_combo.set_active_text(strval);
                }
        }
 }