diff --git a/plugins/channelrx/demodbfm/bfmdemod.cpp b/plugins/channelrx/demodbfm/bfmdemod.cpp
index 7dd65ee6d..f17ae25d3 100644
--- a/plugins/channelrx/demodbfm/bfmdemod.cpp
+++ b/plugins/channelrx/demodbfm/bfmdemod.cpp
@@ -495,8 +495,7 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force)
     if ((settings.m_squelch != m_settings.m_squelch) || force)
     {
         qDebug() << "BFMDemod::handleMessage: set m_squelchLevel";
-        m_squelchLevel = std::pow(10.0, settings.m_squelch / 20.0);
-        m_squelchLevel *= m_squelchLevel;
+        m_squelchLevel = std::pow(10.0, settings.m_squelch / 10.0);
     }
 
     if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
diff --git a/plugins/channelrx/demodwfm/wfmdemod.cpp b/plugins/channelrx/demodwfm/wfmdemod.cpp
index 5e4a993ea..81378b46f 100644
--- a/plugins/channelrx/demodwfm/wfmdemod.cpp
+++ b/plugins/channelrx/demodwfm/wfmdemod.cpp
@@ -107,41 +107,41 @@ void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
 
 		for (int i = 0 ; i < rf_out; i++)
 		{
-		    demod = m_phaseDiscri.phaseDiscriminatorDelta(rf[i], msq, fmDev);
+		    msq = rf[i].real()*rf[i].real() + rf[i].imag()*rf[i].imag();
 		    Real magsq = msq / (SDR_RX_SCALED*SDR_RX_SCALED);
+		    m_magsqSum += magsq;
+		    m_movingAverage(magsq);
 
-			m_movingAverage(magsq);
-            m_magsqSum += magsq;
-
-            if (magsq > m_magsqPeak)
-            {
+            if (magsq > m_magsqPeak) {
                 m_magsqPeak = magsq;
             }
 
             m_magsqCount++;
 
-			if((Real) m_movingAverage >= m_squelchLevel)
-				m_squelchState = m_settings.m_rfBandwidth / 20; // decay rate
-
-			if (m_squelchState > 0)
-			{
-				m_squelchState--;
-				m_squelchOpen = true;
-			}
-			else
-			{
-				demod = 0;
-                m_squelchOpen = false;
-			}
-
-            if (m_settings.m_audioMute)
+            if (magsq >= m_squelchLevel)
             {
+                if (m_squelchState < m_settings.m_rfBandwidth / 10) { // twice attack and decay rate
+                    m_squelchState++;
+                }
+            }
+            else
+            {
+                if (m_squelchState > 0) {
+                    m_squelchState--;
+                }
+            }
+
+			m_squelchOpen = (m_squelchState > (m_settings.m_rfBandwidth / 20));
+
+			if (m_squelchOpen && !m_settings.m_audioMute) { // squelch open and not mute
+                demod = m_phaseDiscri.phaseDiscriminatorDelta(rf[i], msq, fmDev);
+            } else {
                 demod = 0;
             }
 
             Complex e(demod, 0);
 
-			if(m_interpolator.decimate(&m_interpolatorDistanceRemain, e, &ci))
+			if (m_interpolator.decimate(&m_interpolatorDistanceRemain, e, &ci))
 			{
 				qint16 sample = (qint16)(ci.real() * 3276.8f * m_settings.m_volume);
 				m_sampleBuffer.push_back(Sample(sample, sample));
@@ -154,8 +154,7 @@ void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
 				{
 					uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1);
 
-					if(res != m_audioBufferFill)
-					{
+					if (res != m_audioBufferFill) {
 						qDebug("WFMDemod::feed: %u/%u audio samples written", res, m_audioBufferFill);
 					}
 
@@ -167,12 +166,11 @@ void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
 		}
 	}
 
-	if(m_audioBufferFill > 0)
+	if (m_audioBufferFill > 0)
 	{
 		uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1);
 
-		if(res != m_audioBufferFill)
-		{
+		if (res != m_audioBufferFill) {
 			qDebug("WFMDemod::feed: %u/%u tail samples written", res, m_audioBufferFill);
 		}
 
@@ -339,8 +337,7 @@ void WFMDemod::applySettings(const WFMDemodSettings& settings, bool force)
     if ((settings.m_squelch != m_settings.m_squelch) || force)
     {
         qDebug() << "WFMDemod::applySettings: set m_squelchLevel";
-        m_squelchLevel = pow(10.0, settings.m_squelch / 20.0);
-        m_squelchLevel *= m_squelchLevel;
+        m_squelchLevel = pow(10.0, settings.m_squelch / 10.0);
     }
 
     if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
diff --git a/plugins/channelrx/demodwfm/wfmplugin.cpp b/plugins/channelrx/demodwfm/wfmplugin.cpp
index 735ab1a3d..fa0c2ad8f 100644
--- a/plugins/channelrx/demodwfm/wfmplugin.cpp
+++ b/plugins/channelrx/demodwfm/wfmplugin.cpp
@@ -3,7 +3,9 @@
 #include <QtPlugin>
 #include "plugin/pluginapi.h"
 
+#ifndef SERVER_MODE
 #include "wfmdemodgui.h"
+#endif
 #include "wfmdemod.h"
 
 const PluginDescriptor WFMPlugin::m_pluginDescriptor = {
@@ -34,10 +36,19 @@ void WFMPlugin::initPlugin(PluginAPI* pluginAPI)
 	m_pluginAPI->registerRxChannel(WFMDemod::m_channelIdURI, WFMDemod::m_channelId, this);
 }
 
+#ifdef SERVER_MODE
+PluginInstanceGUI* WFMPlugin::createRxChannelGUI(
+        DeviceUISet *deviceUISet __attribute__((unused)),
+        BasebandSampleSink *rxChannel __attribute__((unused)))
+{
+    return 0;
+}
+#else
 PluginInstanceGUI* WFMPlugin::createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
 {
 	return WFMDemodGUI::create(m_pluginAPI, deviceUISet, rxChannel);
 }
+#endif
 
 BasebandSampleSink* WFMPlugin::createRxChannelBS(DeviceSourceAPI *deviceAPI)
 {
diff --git a/pluginssrv/channelrx/CMakeLists.txt b/pluginssrv/channelrx/CMakeLists.txt
index 93d93d349..09ac520ab 100644
--- a/pluginssrv/channelrx/CMakeLists.txt
+++ b/pluginssrv/channelrx/CMakeLists.txt
@@ -5,3 +5,4 @@ add_subdirectory(demodbfm)
 add_subdirectory(demoddsd)
 add_subdirectory(demodnfm)
 add_subdirectory(demodssb)
+add_subdirectory(demodwfm)
diff --git a/pluginssrv/channelrx/demodwfm/CMakeLists.txt b/pluginssrv/channelrx/demodwfm/CMakeLists.txt
new file mode 100644
index 000000000..ef69350ad
--- /dev/null
+++ b/pluginssrv/channelrx/demodwfm/CMakeLists.txt
@@ -0,0 +1,43 @@
+project(wfm)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+set(PLUGIN_PREFIX "../../../plugins/channelrx/demodwfm")
+
+set(wfm_SOURCES
+	${PLUGIN_PREFIX}/wfmdemod.cpp
+	${PLUGIN_PREFIX}/wfmdemodsettings.cpp
+	${PLUGIN_PREFIX}/wfmplugin.cpp
+)
+
+set(wfm_HEADERS
+	${PLUGIN_PREFIX}/wfmdemod.h
+	${PLUGIN_PREFIX}/wfmdemodsettings.h
+	${PLUGIN_PREFIX}/wfmplugin.h
+)
+
+include_directories(
+	.
+	${CMAKE_CURRENT_BINARY_DIR}
+    ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client		
+)
+
+#include(${QT_USE_FILE})
+add_definitions(${QT_DEFINITIONS})
+add_definitions(-DQT_PLUGIN)
+add_definitions(-DQT_SHARED)
+
+#qt5_wrap_cpp(nfm_HEADERS_MOC ${nfm_HEADERS})
+
+add_library(demodwfmsrv SHARED
+	${wfm_SOURCES}
+	${wfm_HEADERS_MOC}
+)
+
+target_link_libraries(demodwfmsrv
+	${QT_LIBRARIES}
+	sdrbase
+)
+
+qt5_use_modules(demodwfmsrv Core)
+
+install(TARGETS demodwfmsrv DESTINATION lib/pluginssrv/channelrx)
\ No newline at end of file