add chinese translation from Rui-huai Zhang
[ardour.git] / gtk2_ardour / engine_dialog.cc
index bfb2796529c95dca0c4b599d87641d331abead41..615e79e184402b39d53a86a2a871f5f327671c67 100644 (file)
@@ -1,10 +1,33 @@
+/*
+    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>
 #include <map>
 
+#include <boost/scoped_ptr.hpp>
+
 #include <glibmm.h>
 #include <gtkmm/messagedialog.h>
+
+#include "pbd/epa.h"
 #include "pbd/xml++.h"
 
 #ifdef __APPLE__
@@ -16,7 +39,6 @@
 #include <alsa/asoundlib.h>
 #endif
 
-#include "ardour/profile.h"
 #include <jack/jack.h>
 
 #include <gtkmm/stock.h>
@@ -42,10 +64,12 @@ using namespace Glib;
 EngineControl::EngineControl ()
        : periods_adjustment (2, 2, 16, 1, 2),
          periods_spinner (periods_adjustment),
-         priority_adjustment (60, 10, 90, 1, 10),
-         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 +139,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"));
@@ -126,8 +151,8 @@ EngineControl::EngineControl ()
        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);
@@ -136,38 +161,44 @@ EngineControl::EngineControl ()
        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 (left_aligned_label (_("Driver:")));
        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 (left_aligned_label (_("Audio Interface:")));
        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 (left_aligned_label (_("Sample rate:")));
        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 (left_aligned_label (_("Buffer size:")));
        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 (left_aligned_label (_("Number of buffers:")));
        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 (left_aligned_label (_("Approximate latency:")));
        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++;
@@ -180,15 +211,15 @@ EngineControl::EngineControl ()
        /* no audio mode with CoreAudio, its duplex or nuthin' */
 
 #ifndef __APPLE__
-       label = manage (new Label (_("Audio Mode")));
+       label = manage (left_aligned_label (_("Audio mode:")));
        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);
 
        /*
 
@@ -216,19 +247,10 @@ EngineControl::EngineControl ()
        ++row;
 
        realtime_button.set_active (true);
-       realtime_button.signal_toggled().connect (sigc::mem_fun (*this, &EngineControl::realtime_changed));
-       realtime_changed ();
 
 #if PROVIDE_TOO_MANY_OPTIONS
 
 #ifndef __APPLE__
-       label = manage (new Label (_("Realtime Priority")));
-       label->set_alignment (1.0, 0.5);
-       options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
-       options_packer.attach (priority_spinner, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
-       ++row;
-       priority_spinner.set_value (60);
-
        options_packer.attach (no_memory_lock_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
        options_packer.attach (unlock_memory_button, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
@@ -266,15 +288,18 @@ EngineControl::EngineControl ()
        ++row;
 
 #endif /* PROVIDE_TOO_MANY_OPTIONS */
-       label = manage (new Label (_("Number of ports")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (left_aligned_label (_("Number of ports:")));
        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 (left_aligned_label (_("MIDI driver:")));
+       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 (left_aligned_label (_("Dither:")));
        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;
@@ -291,9 +316,8 @@ EngineControl::EngineControl ()
        serverpath_combo.set_active_text (server_strings.front());
 
        if (server_strings.size() > 1) {
-               label = manage (new Label (_("Server:")));
+               label = manage (left_aligned_label (_("Server:")));
                options_packer.attach (*label, 0, 1, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
-               label->set_alignment (0.0, 0.5);
                options_packer.attach (serverpath_combo, 1, 2, row, row + 1, FILL|EXPAND, (AttachOptions) 0);
                ++row;
        }
@@ -304,36 +328,26 @@ EngineControl::EngineControl ()
        row = 0;
 
 #ifndef __APPLE__
-       label = manage (new Label (_("Input device")));
-       label->set_alignment (1.0, 0.5);
+       label = manage (left_aligned_label (_("Input device:")));
        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 (left_aligned_label (_("Output device:")));
        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);
-       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);
-       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 (left_aligned_label (_("Hardware input latency:")));
        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 (left_aligned_label (_("samples")));
+       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 (left_aligned_label (_("Hardware output latency:")));
        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 (left_aligned_label (_("samples")));
+       device_packer.attach (*label, 2, 3, row, row+1, FILL|EXPAND, (AttachOptions) 0);
        ++row;
 
        basic_hbox.pack_start (basic_packer, false, false);
@@ -362,12 +376,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 +388,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));
@@ -396,8 +411,6 @@ EngineControl::build_command_line (vector<string>& cmd)
 
        if (realtime_button.get_active()) {
                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 */
        }
@@ -419,31 +432,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");
@@ -470,6 +474,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);
 
@@ -479,7 +484,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));
                }
@@ -491,6 +496,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) {
 
                if (audio_mode_combo.get_active_text() != _("Playback/Recording on 2 Devices")) {
@@ -532,6 +554,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__
@@ -547,16 +576,23 @@ EngineControl::build_command_line (vector<string>& cmd)
                cmd.push_back (device);
 #endif
 
-       } else if (using_oss) {
-
-       } else if (using_netjack) {
-
        }
 }
 
 bool
 EngineControl::engine_running ()
 {
+        EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
+        boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
+
+        /* revert all environment settings back to whatever they were when ardour started
+         */
+
+        if (global_epa) {
+                current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
+                global_epa->restore ();
+        }
+
        jack_status_t status;
        jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status);
 
@@ -579,7 +615,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());
@@ -601,14 +637,6 @@ EngineControl::setup_engine ()
        return 0;
 }
 
-void
-EngineControl::realtime_changed ()
-{
-#ifndef __APPLE__
-       priority_spinner.set_sensitive (realtime_button.get_active());
-#endif
-}
-
 void
 EngineControl::enumerate_devices (const string& driver)
 {
@@ -622,6 +650,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") {
@@ -659,7 +689,7 @@ EngineControl::enumerate_coreaudio_devices ()
        // (code snippet gently "borrowed" from St?hane Letz jackdmp;)
        OSStatus err;
        Boolean isWritable;
-       size_t outSize = sizeof(isWritable);
+       UInt32 outSize = sizeof(isWritable);
 
        backend_devs.clear ();
 
@@ -675,7 +705,7 @@ EngineControl::enumerate_coreaudio_devices ()
                if (err == noErr) {
                        // Look for the CoreAudio device name...
                        char coreDeviceName[256];
-                       size_t nameSize;
+                       UInt32 nameSize;
 
                        for (int i = 0; i < numCoreDevices; i++) {
 
@@ -806,6 +836,7 @@ EngineControl::enumerate_freebob_devices ()
        vector<string> devs;
        return devs;
 }
+
 vector<string>
 EngineControl::enumerate_oss_devices ()
 {
@@ -831,22 +862,19 @@ EngineControl::driver_changed ()
 {
        string driver = driver_combo.get_active_text();
        string::size_type maxlen = 0;
-       int maxindex = -1;
        int n = 0;
 
        enumerate_devices (driver);
 
        vector<string>& strings = devices[driver];
 
-       if (strings.empty() && driver != "FFADO" && driver != "Dummy") {
-               error << string_compose (_("No devices found for driver \"%1\""), driver) << endmsg;
+       if (strings.empty() && driver != "FreeBoB" && driver != "FFADO" && driver != "Dummy") {
                return;
        }
 
        for (vector<string>::iterator i = strings.begin(); i != strings.end(); ++i, ++n) {
                if ((*i).length() > maxlen) {
                        maxlen = (*i).length();
-                       maxindex = n;
                }
        }
 
@@ -878,7 +906,14 @@ EngineControl::driver_changed ()
 uint32_t
 EngineControl::get_rate ()
 {
-       return atoi (sample_rate_combo.get_active_text ());
+       double r = atof (sample_rate_combo.get_active_text ());
+       /* the string may have been translated with an abbreviation for
+        * thousands, so use a crude heuristic to fix this.
+        */
+       if (r < 1000.0) {
+               r *= 1000.0;
+       }
+       return lrint (r);
 }
 
 void
@@ -896,12 +931,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);
@@ -911,8 +947,10 @@ EngineControl::audio_mode_changed ()
                output_device_combo.set_sensitive (true);
        } else if (str == _("Playback only")) {
                output_device_combo.set_sensitive (true);
+               input_device_combo.set_sensitive (false);
        } else if (str == _("Recording only")) {
                input_device_combo.set_sensitive (true);
+               output_device_combo.set_sensitive (false);
        }
 }
 
@@ -988,6 +1026,9 @@ EngineControl::find_jack_servers (vector<string>& strings)
 #endif
 
        jack_servers = scanner (path, jack_server_filter, 0, false, true);
+       if (!jack_servers) {
+               return;
+       }
 
        vector<string *>::iterator iter;
 
@@ -1012,6 +1053,7 @@ EngineControl::get_device_name (const string& driver, const string& human_readab
                   another computer system in it
                */
                MessageDialog msg (_("You need to choose an audio device first."));
+                msg.set_position (WIN_POS_MOUSE);
                msg.run ();
                return string();
        }
@@ -1038,28 +1080,16 @@ 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));
        root->add_child_nocopy (*child);
 
-       child = new XMLNode ("priority");
-       child->add_property ("val", to_string (priority_adjustment.get_value(), std::dec));
-       root->add_child_nocopy (*child);
-
        child = new XMLNode ("ports");
        child->add_property ("val", to_string (ports_adjustment.get_value(), std::dec));
        root->add_child_nocopy (*child);
 
-       child = new XMLNode ("inchannels");
-       child->add_property ("val", to_string (input_channels.get_value(), std::dec));
-       root->add_child_nocopy (*child);
-
-       child = new XMLNode ("outchannels");
-       child->add_property ("val", to_string (output_channels.get_value(), std::dec));
-       root->add_child_nocopy (*child);
-
        child = new XMLNode ("inlatency");
        child->add_property ("val", to_string (input_latency.get_value(), std::dec));
        root->add_child_nocopy (*child);
@@ -1140,6 +1170,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;
 }
 
@@ -1151,15 +1185,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();
@@ -1172,9 +1212,15 @@ EngineControl::set_state (const XMLNode& root)
 
                if (!prop || prop->value().empty()) {
 
-                       if ((using_dummy && ( child->name() == "interface" || child->name() == "inputdevice" || child->name() == "outputdevice" )) ||
-                               child->name() == "timeout")
+                       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;
                }
@@ -1186,18 +1232,9 @@ EngineControl::set_state (const XMLNode& root)
                if (child->name() == "periods") {
                        val = atoi (strval);
                        periods_adjustment.set_value(val);
-               } else if (child->name() == "priority") {
-                       val = atoi (strval);
-                       priority_adjustment.set_value(val);
                } else if (child->name() == "ports") {
                        val = atoi (strval);
                        ports_adjustment.set_value(val);
-               } else if (child->name() == "inchannels") {
-                       val = atoi (strval);
-                       input_channels.set_value(val);
-               } else if (child->name() == "outchannels") {
-                       val = atoi (strval);
-                       output_channels.set_value(val);
                } else if (child->name() == "inlatency") {
                        val = atoi (strval);
                        input_latency.set_value(val);
@@ -1241,13 +1278,13 @@ EngineControl::set_state (const XMLNode& root)
                } else if (child->name() == "periodsize") {
                        period_size_combo.set_active_text(strval);
                } else if (child->name() == "serverpath") {
-                        
+
                         /* 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
@@ -1268,7 +1305,7 @@ EngineControl::set_state (const XMLNode& root)
                                                 << endmsg;
                                 }
                         }
-                        
+
                } else if (child->name() == "driver") {
                        driver_combo.set_active_text(strval);
                } else if (child->name() == "interface") {
@@ -1283,6 +1320,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);
                }
        }
 }