diff --git a/sdrangel.windows.pro b/sdrangel.windows.pro
index 3ecdb336d..75de2ce60 100644
--- a/sdrangel.windows.pro
+++ b/sdrangel.windows.pro
@@ -6,6 +6,8 @@
TEMPLATE = subdirs
+CONFIG += ordered
+
SUBDIRS = serialdv
SUBDIRS += httpserver
SUBDIRS += logging
@@ -59,5 +61,4 @@ SUBDIRS += plugins/channeltx/modwfm
SUBDIRS += plugins/channeltx/udpsink
# Main app must be last
-CONFIG += ordered
SUBDIRS += app
diff --git a/sdrbase/audio/audiodeviceinfo.cpp b/sdrbase/audio/audiodeviceinfo.cpp
index 477e80f20..0a37a17fb 100644
--- a/sdrbase/audio/audiodeviceinfo.cpp
+++ b/sdrbase/audio/audiodeviceinfo.cpp
@@ -1,67 +1,84 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2017 F4EXB //
-// written by Edouard Griffiths //
-// //
-// 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 as version 3 of the License, or //
-// //
-// 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 V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#include "audio/audiodeviceinfo.h"
-#include "util/simpleserializer.h"
-
-AudioDeviceInfo::AudioDeviceInfo() :
- m_inputDeviceIndex(-1), // default device
- m_outputDeviceIndex(-1), // default device
- m_inputVolume(1.0f)
-{
- m_inputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
- m_outputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
-}
-
-void AudioDeviceInfo::resetToDefaults()
-{
- m_inputDeviceIndex = -1;
- m_outputDeviceIndex = -1;
- m_inputVolume = 1.0f;
-}
-
-QByteArray AudioDeviceInfo::serialize() const
-{
- SimpleSerializer s(1);
- s.writeS32(1, m_inputDeviceIndex);
- s.writeS32(2, m_outputDeviceIndex);
- s.writeFloat(3, m_inputVolume);
- return s.final();
-}
-
-bool AudioDeviceInfo::deserialize(const QByteArray& data)
-{
- SimpleDeserializer d(data);
-
- if(!d.isValid()) {
- resetToDefaults();
- return false;
- }
-
- if(d.getVersion() == 1)
- {
- d.readS32(1, &m_inputDeviceIndex, -1);
- d.readS32(2, &m_outputDeviceIndex, -1);
- d.readFloat(3, &m_inputVolume, 1.0f);
- return true;
- }
- else
- {
- resetToDefaults();
- return false;
- }
-}
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2017 F4EXB //
+// written by Edouard Griffiths //
+// //
+// 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 as version 3 of the License, or //
+// //
+// 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 V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "audio/audiodeviceinfo.h"
+#include "util/simpleserializer.h"
+
+AudioDeviceInfo::AudioDeviceInfo() :
+ m_inputDeviceIndex(-1), // default device
+ m_outputDeviceIndex(-1), // default device
+ m_inputVolume(1.0f)
+{
+ m_inputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
+ m_outputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
+}
+
+void AudioDeviceInfo::resetToDefaults()
+{
+ m_inputDeviceIndex = -1;
+ m_outputDeviceIndex = -1;
+ m_inputVolume = 1.0f;
+}
+
+QByteArray AudioDeviceInfo::serialize() const
+{
+ SimpleSerializer s(1);
+ s.writeS32(1, m_inputDeviceIndex);
+ s.writeS32(2, m_outputDeviceIndex);
+ s.writeFloat(3, m_inputVolume);
+ return s.final();
+}
+
+bool AudioDeviceInfo::deserialize(const QByteArray& data)
+{
+ SimpleDeserializer d(data);
+
+ if(!d.isValid()) {
+ resetToDefaults();
+ return false;
+ }
+
+ if(d.getVersion() == 1)
+ {
+ d.readS32(1, &m_inputDeviceIndex, -1);
+ d.readS32(2, &m_outputDeviceIndex, -1);
+ d.readFloat(3, &m_inputVolume, 1.0f);
+ return true;
+ }
+ else
+ {
+ resetToDefaults();
+ return false;
+ }
+}
+
+void AudioDeviceInfo::setInputDeviceIndex(int inputDeviceIndex)
+{
+ int nbDevices = m_inputDevicesInfo.size();
+ m_inputDeviceIndex = inputDeviceIndex < -1 ? -1 : inputDeviceIndex >= nbDevices ? nbDevices-1 : inputDeviceIndex;
+}
+
+void AudioDeviceInfo::setOutputDeviceIndex(int outputDeviceIndex)
+{
+ int nbDevices = m_outputDevicesInfo.size();
+ m_outputDeviceIndex = outputDeviceIndex < -1 ? -1 : outputDeviceIndex >= nbDevices ? nbDevices-1 : outputDeviceIndex;
+}
+
+void AudioDeviceInfo::setInputVolume(float inputVolume)
+{
+ m_inputVolume = inputVolume < 0.0 ? 0.0 : inputVolume > 1.0 ? 1.0 : inputVolume;
+}
diff --git a/sdrbase/audio/audiodeviceinfo.h b/sdrbase/audio/audiodeviceinfo.h
index b0d713ade..38bce5596 100644
--- a/sdrbase/audio/audiodeviceinfo.h
+++ b/sdrbase/audio/audiodeviceinfo.h
@@ -1,52 +1,55 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2017 F4EXB //
-// written by Edouard Griffiths //
-// //
-// 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 as version 3 of the License, or //
-// //
-// 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 V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef INCLUDE_AUDIODEVICEINFO_H
-#define INCLUDE_AUDIODEVICEINFO_H
-
-#include
-#include
-#include
-
-#include "util/export.h"
-
-class SDRANGEL_API AudioDeviceInfo {
-public:
- AudioDeviceInfo();
-
- const QList& getInputDevices() const { return m_inputDevicesInfo; }
- const QList& getOutputDevices() const { return m_outputDevicesInfo; }
- int getInputDeviceIndex() const { return m_inputDeviceIndex; }
- int getOutputDeviceIndex() const { return m_outputDeviceIndex; }
- float getInputVolume() const { return m_inputVolume; }
-
-private:
- QList m_inputDevicesInfo;
- QList m_outputDevicesInfo;
- int m_inputDeviceIndex;
- int m_outputDeviceIndex;
- float m_inputVolume;
-
- void resetToDefaults();
- QByteArray serialize() const;
- bool deserialize(const QByteArray& data);
-
- friend class AudioDialog;
- friend class MainSettings;
-};
-
-#endif // INCLUDE_AUDIODEVICEINFO_H
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2017 F4EXB //
+// written by Edouard Griffiths //
+// //
+// 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 as version 3 of the License, or //
+// //
+// 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 V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDE_AUDIODEVICEINFO_H
+#define INCLUDE_AUDIODEVICEINFO_H
+
+#include
+#include
+#include
+
+#include "util/export.h"
+
+class SDRANGEL_API AudioDeviceInfo {
+public:
+ AudioDeviceInfo();
+
+ const QList& getInputDevices() const { return m_inputDevicesInfo; }
+ const QList& getOutputDevices() const { return m_outputDevicesInfo; }
+ int getInputDeviceIndex() const { return m_inputDeviceIndex; }
+ int getOutputDeviceIndex() const { return m_outputDeviceIndex; }
+ float getInputVolume() const { return m_inputVolume; }
+ void setInputDeviceIndex(int inputDeviceIndex);
+ void setOutputDeviceIndex(int inputDeviceIndex);
+ void setInputVolume(float inputVolume);
+
+private:
+ QList m_inputDevicesInfo;
+ QList m_outputDevicesInfo;
+ int m_inputDeviceIndex;
+ int m_outputDeviceIndex;
+ float m_inputVolume;
+
+ void resetToDefaults();
+ QByteArray serialize() const;
+ bool deserialize(const QByteArray& data);
+
+ friend class AudioDialog;
+ friend class MainSettings;
+};
+
+#endif // INCLUDE_AUDIODEVICEINFO_H
diff --git a/sdrbase/resources/index.html b/sdrbase/resources/index.html
index e9c527b75..2acf9644e 100644
--- a/sdrbase/resources/index.html
+++ b/sdrbase/resources/index.html
@@ -695,451 +695,471 @@ margin-bottom: 20px;
@@ -1450,11 +1470,11 @@ except ApiException as e: