diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp
index 581b81882..22053cd06 100644
--- a/plugins/channeltx/modssb/ssbmod.cpp
+++ b/plugins/channeltx/modssb/ssbmod.cpp
@@ -27,6 +27,7 @@
 #include "util/db.h"
 
 MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureSSBMod, Message)
+MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureChannelizer, Message)
 MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureFileSourceName, Message)
 MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureFileSourceSeek, Message)
 MESSAGE_CLASS_DEFINITION(SSBMod::MsgConfigureAFInput, Message)
@@ -59,26 +60,16 @@ SSBMod::SSBMod(BasebandSampleSink* sampleSink) :
 {
 	setObjectName("SSBMod");
 
-    m_SSBFilter = new fftfilt(m_config.m_lowCutoff / m_config.m_audioSampleRate, m_config.m_bandwidth / m_config.m_audioSampleRate, m_ssbFftLen);
-    m_DSBFilter = new fftfilt((2.0f * m_config.m_bandwidth) / m_config.m_audioSampleRate, 2 * m_ssbFftLen);
+    m_SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_settings.m_audioSampleRate, m_settings.m_bandwidth / m_settings.m_audioSampleRate, m_ssbFftLen);
+    m_DSBFilter = new fftfilt((2.0f * m_settings.m_bandwidth) / m_settings.m_audioSampleRate, 2 * m_ssbFftLen);
     m_SSBFilterBuffer = new Complex[m_ssbFftLen>>1]; // filter returns data exactly half of its size
     m_DSBFilterBuffer = new Complex[m_ssbFftLen];
     memset(m_SSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen>>1));
     memset(m_DSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen));
 
-    m_config.m_outputSampleRate = 48000;
-	m_config.m_inputFrequencyOffset = 0;
-	m_config.m_bandwidth = 12500;
-	m_config.m_toneFrequency = 1000.0f;
-	m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
-
 	m_audioBuffer.resize(1<<14);
 	m_audioBufferFill = 0;
 
-//    m_magsqSpectrum = 0.0f;
-//    m_magsqSum = 0.0f;
-//    m_magsqPeak = 0.0f;
-//    m_magsqCount = 0;
     m_sum.real(0.0f);
     m_sum.imag(0.0f);
     m_undersampleCount = 0;
@@ -87,18 +78,18 @@ SSBMod::SSBMod(BasebandSampleSink* sampleSink) :
 	m_movingAverage.resize(16, 0);
 	m_magsq = 0.0;
 
-	m_toneNco.setFreq(1000.0, m_config.m_audioSampleRate);
+	m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
 	DSPEngine::instance()->addAudioSource(&m_audioFifo);
 
 	// CW keyer
-	m_cwKeyer.setSampleRate(m_config.m_audioSampleRate);
+	m_cwKeyer.setSampleRate(m_settings.m_audioSampleRate);
 	m_cwKeyer.setWPM(13);
 	m_cwKeyer.setMode(CWKeyer::CWNone);
 
-	m_inAGC.setGate(m_config.m_agcThresholdGate);
-	m_inAGC.setStepDownDelay(m_config.m_agcThresholdDelay);
+	m_inAGC.setGate(m_settings.m_agcThresholdGate);
+	m_inAGC.setStepDownDelay(m_settings.m_agcThresholdDelay);
 	m_inAGC.setClamping(true);
-    apply();
+    applySettings(m_settings, true);
 }
 
 SSBMod::~SSBMod()
@@ -122,43 +113,6 @@ SSBMod::~SSBMod()
     DSPEngine::instance()->removeAudioSource(&m_audioFifo);
 }
 
-void SSBMod::configure(MessageQueue* messageQueue,
-		Real bandwidth,
-		Real lowCutoff,
-		float toneFrequency,
-		float volumeFactor,
-		int spanLog2,
-		bool audioBinaural,
-		bool audioFlipChannels,
-		bool dsb,
-		bool audioMute,
-		bool playLoop,
-		bool agc,
-		float agcOrder,
-		int agcTime,
-		int agcThreshold,
-		int agcThresholdGate,
-		int agcThresholdDelay)
-{
-	Message* cmd = MsgConfigureSSBMod::create(bandwidth,
-			lowCutoff,
-			toneFrequency,
-			volumeFactor,
-			spanLog2,
-			audioBinaural,
-			audioFlipChannels,
-			dsb,
-			audioMute,
-			playLoop,
-			agc,
-			agcOrder,
-			agcTime,
-			agcThreshold,
-			agcThresholdGate,
-			agcThresholdDelay);
-	messageQueue->push(cmd);
-}
-
 void SSBMod::pull(Sample& sample)
 {
 	Complex ci;
@@ -200,7 +154,7 @@ void SSBMod::pull(Sample& sample)
 
 void SSBMod::pullAudio(int nbSamples)
 {
-    unsigned int nbSamplesAudio = nbSamples * ((Real) m_config.m_audioSampleRate / (Real) m_config.m_basebandSampleRate);
+    unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_settings.m_basebandSampleRate);
 
     if (nbSamplesAudio > m_audioBuffer.size())
     {
@@ -220,7 +174,7 @@ void SSBMod::modulateSample()
 
 void SSBMod::pullAF(Complex& sample)
 {
-	if (m_running.m_audioMute)
+	if (m_settings.m_audioMute)
 	{
         sample.real(0.0f);
         sample.imag(0.0f);
@@ -231,13 +185,13 @@ void SSBMod::pullAF(Complex& sample)
     fftfilt::cmplx *filtered;
     int n_out = 0;
 
-    int decim = 1<<(m_running.m_spanLog2 - 1);
+    int decim = 1<<(m_settings.m_spanLog2 - 1);
     unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
 
     switch (m_afInput)
     {
     case SSBModInputTone:
-    	if (m_running.m_dsb)
+    	if (m_settings.m_dsb)
     	{
     		Real t = m_toneNco.next()/1.25;
     		sample.real(t);
@@ -245,7 +199,7 @@ void SSBMod::pullAF(Complex& sample)
     	}
     	else
     	{
-    		if (m_running.m_usb) {
+    		if (m_settings.m_usb) {
     			sample = m_toneNco.nextIQ();
     		} else {
     			sample = m_toneNco.nextQI();
@@ -263,7 +217,7 @@ void SSBMod::pullAF(Complex& sample)
         {
             if (m_ifstream.eof())
             {
-            	if (m_running.m_playLoop)
+            	if (m_settings.m_playLoop)
             	{
                     m_ifstream.clear();
                     m_ifstream.seekg(0, std::ios::beg);
@@ -277,19 +231,19 @@ void SSBMod::pullAF(Complex& sample)
             }
             else
             {
-            	if (m_running.m_audioBinaural)
+            	if (m_settings.m_audioBinaural)
             	{
             		Complex c;
                 	m_ifstream.read(reinterpret_cast<char*>(&c), sizeof(Complex));
 
-                	if (m_running.m_audioFlipChannels)
+                	if (m_settings.m_audioFlipChannels)
                 	{
-                        ci.real(c.imag() * m_running.m_volumeFactor);
-                        ci.imag(c.real() * m_running.m_volumeFactor);
+                        ci.real(c.imag() * m_settings.m_volumeFactor);
+                        ci.imag(c.real() * m_settings.m_volumeFactor);
                 	}
                 	else
                 	{
-                    	ci = c * m_running.m_volumeFactor;
+                    	ci = c * m_settings.m_volumeFactor;
                 	}
             	}
             	else
@@ -297,16 +251,16 @@ void SSBMod::pullAF(Complex& sample)
                     Real real;
                 	m_ifstream.read(reinterpret_cast<char*>(&real), sizeof(Real));
 
-                	if (m_running.m_agc)
+                	if (m_settings.m_agc)
                 	{
                         ci.real(real);
                         ci.imag(0.0f);
                         m_inAGC.feed(ci);
-                        ci *= m_running.m_volumeFactor;
+                        ci *= m_settings.m_volumeFactor;
                 	}
                 	else
                 	{
-                        ci.real(real * m_running.m_volumeFactor);
+                        ci.real(real * m_settings.m_volumeFactor);
                         ci.imag(0.0f);
                 	}
             	}
@@ -319,31 +273,31 @@ void SSBMod::pullAF(Complex& sample)
         }
         break;
     case SSBModInputAudio:
-        if (m_running.m_audioBinaural)
+        if (m_settings.m_audioBinaural)
     	{
-        	if (m_running.m_audioFlipChannels)
+        	if (m_settings.m_audioFlipChannels)
         	{
-                ci.real((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_running.m_volumeFactor);
-                ci.imag((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_running.m_volumeFactor);
+                ci.real((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_settings.m_volumeFactor);
+                ci.imag((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_settings.m_volumeFactor);
         	}
         	else
         	{
-                ci.real((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_running.m_volumeFactor);
-                ci.imag((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_running.m_volumeFactor);
+                ci.real((m_audioBuffer[m_audioBufferFill].l / 32768.0f) * m_settings.m_volumeFactor);
+                ci.imag((m_audioBuffer[m_audioBufferFill].r / 32768.0f) * m_settings.m_volumeFactor);
         	}
     	}
         else
         {
-            if (m_running.m_agc)
+            if (m_settings.m_agc)
             {
                 ci.real(((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r)  / 65536.0f));
                 ci.imag(0.0f);
                 m_inAGC.feed(ci);
-                ci *= m_running.m_volumeFactor;
+                ci *= m_settings.m_volumeFactor;
             }
             else
             {
-                ci.real(((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r)  / 65536.0f) * m_running.m_volumeFactor);
+                ci.real(((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r)  / 65536.0f) * m_settings.m_volumeFactor);
                 ci.imag(0.0f);
             }
         }
@@ -356,7 +310,7 @@ void SSBMod::pullAF(Complex& sample)
         {
             m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
 
-        	if (m_running.m_dsb)
+        	if (m_settings.m_dsb)
         	{
         		Real t = m_toneNco.next() * fadeFactor;
         		sample.real(t);
@@ -364,7 +318,7 @@ void SSBMod::pullAF(Complex& sample)
         	}
         	else
         	{
-        		if (m_running.m_usb) {
+        		if (m_settings.m_usb) {
         			sample = m_toneNco.nextIQ() * fadeFactor;
         		} else {
         			sample = m_toneNco.nextQI() * fadeFactor;
@@ -375,7 +329,7 @@ void SSBMod::pullAF(Complex& sample)
         {
         	if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
         	{
-            	if (m_running.m_dsb)
+            	if (m_settings.m_dsb)
             	{
             		Real t = (m_toneNco.next() * fadeFactor)/1.25;
             		sample.real(t);
@@ -383,7 +337,7 @@ void SSBMod::pullAF(Complex& sample)
             	}
             	else
             	{
-            		if (m_running.m_usb) {
+            		if (m_settings.m_usb) {
             			sample = m_toneNco.nextIQ() * fadeFactor;
             		} else {
             			sample = m_toneNco.nextQI() * fadeFactor;
@@ -406,7 +360,7 @@ void SSBMod::pullAF(Complex& sample)
 
     if ((m_afInput == SSBModInputFile) || (m_afInput == SSBModInputAudio)) // real audio
     {
-    	if (m_running.m_dsb)
+    	if (m_settings.m_dsb)
     	{
     		n_out = m_DSBFilter->runDSB(ci, &filtered);
 
@@ -421,7 +375,7 @@ void SSBMod::pullAF(Complex& sample)
     	}
     	else
     	{
-    		n_out = m_SSBFilter->runSSB(ci, &filtered, m_running.m_usb);
+    		n_out = m_SSBFilter->runSSB(ci, &filtered, m_settings.m_usb);
 
     		if (n_out > 0)
     		{
@@ -457,7 +411,7 @@ void SSBMod::pullAF(Complex& sample)
 //
 //                    m_magsqCount++;
 
-                    if (!m_running.m_dsb & !m_running.m_usb)
+                    if (!m_settings.m_dsb & !m_settings.m_usb)
                     { // invert spectrum for LSB
                         m_sampleBuffer.push_back(Sample(avgi, avgr));
                     }
@@ -491,7 +445,7 @@ void SSBMod::pullAF(Complex& sample)
 //
 //            m_magsqCount++;
 
-            if (!m_running.m_dsb & !m_running.m_usb)
+            if (!m_settings.m_dsb & !m_settings.m_usb)
             { // invert spectrum for LSB
                 m_sampleBuffer.push_back(Sample(avgi, avgr));
             }
@@ -504,7 +458,7 @@ void SSBMod::pullAF(Complex& sample)
             m_sum.imag(0.0);
         }
 
-        if (m_sumCount < (m_running.m_dsb ? m_ssbFftLen : m_ssbFftLen>>1))
+        if (m_sumCount < (m_settings.m_dsb ? m_ssbFftLen : m_ssbFftLen>>1))
         {
             n_out = 0;
             m_sumCount++;
@@ -520,7 +474,7 @@ void SSBMod::pullAF(Complex& sample)
     {
         if (m_sampleSink != 0)
         {
-            m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), !m_running.m_dsb);
+            m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), !m_settings.m_dsb);
         }
 
         m_sampleBuffer.clear();
@@ -550,8 +504,8 @@ void SSBMod::calculateLevel(Complex& sample)
 
 void SSBMod::start()
 {
-	qDebug() << "SSBMod::start: m_outputSampleRate: " << m_config.m_outputSampleRate
-			<< " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset;
+	qDebug() << "SSBMod::start: m_outputSampleRate: " << m_settings.m_outputSampleRate
+			<< " m_inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
 
 	m_audioFifo.clear();
 }
@@ -566,91 +520,82 @@ bool SSBMod::handleMessage(const Message& cmd)
 	{
 		UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd;
 
-		m_config.m_basebandSampleRate = notif.getBasebandSampleRate();
-		m_config.m_outputSampleRate = notif.getSampleRate();
-		m_config.m_inputFrequencyOffset = notif.getFrequencyOffset();
+		SSBModSettings settings = m_settings;
 
-		apply();
+		settings.m_basebandSampleRate = notif.getBasebandSampleRate();
+		settings.m_outputSampleRate = notif.getSampleRate();
+		settings.m_inputFrequencyOffset = notif.getFrequencyOffset();
+
+		applySettings(settings);
 
 		qDebug() << "SSBMod::handleMessage: MsgChannelizerNotification:"
-				<< " m_basebandSampleRate: " << m_config.m_basebandSampleRate
-                << " m_outputSampleRate: " << m_config.m_outputSampleRate
-				<< " m_inputFrequencyOffset: " << m_config.m_inputFrequencyOffset;
+				<< " m_basebandSampleRate: " << settings.m_basebandSampleRate
+                << " m_outputSampleRate: " << settings.m_outputSampleRate
+				<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset;
 
 		return true;
 	}
-	else if (MsgConfigureSSBMod::match(cmd))
-	{
-		float band, lowCutoff;
+    else if (MsgConfigureSSBMod::match(cmd))
+    {
+        float band, lowCutoff;
+        MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd;
 
-	    MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd;
-	    m_settingsMutex.lock();
+        SSBModSettings settings = cfg.getSettings();
 
-		band = cfg.getBandwidth();
-		lowCutoff = cfg.getLowCutoff();
+        // These settings are set with UpChannelizer::MsgChannelizerNotification
+        settings.m_basebandSampleRate = m_settings.m_basebandSampleRate;
+        settings.m_outputSampleRate = m_settings.m_outputSampleRate;
+        settings.m_inputFrequencyOffset = m_settings.m_inputFrequencyOffset;
 
-		if (band < 0) // negative means LSB
-		{
-			band = -band;            // turn to positive
-			lowCutoff = -lowCutoff;
-			m_config.m_usb = false;  // and take note of side band
-		}
-		else
-		{
-			m_config.m_usb = true;
-		}
+        band = settings.m_bandwidth;
+        lowCutoff = settings.m_lowCutoff;
 
-		if (band < 100.0f) // at least 100 Hz
-		{
-			band = 100.0f;
-			lowCutoff = 0;
-		}
+        if (band < 0) // negative means LSB
+        {
+            band = -band;            // turn to positive
+            lowCutoff = -lowCutoff;
+            settings.m_usb = false;  // and take note of side band
+        }
+        else
+        {
+            settings.m_usb = true;
+        }
 
-		m_config.m_bandwidth = band;
-		m_config.m_lowCutoff = lowCutoff;
+        if (band < 100.0f) // at least 100 Hz
+        {
+            band = 100.0f;
+            lowCutoff = 0;
+        }
 
-		m_config.m_toneFrequency = cfg.getToneFrequency();
-		m_config.m_volumeFactor = cfg.getVolumeFactor();
-		m_config.m_spanLog2 = cfg.getSpanLog2();
-		m_config.m_audioBinaural = cfg.getAudioBinaural();
-		m_config.m_audioFlipChannels = cfg.getAudioFlipChannels();
-		m_config.m_dsb = cfg.getDSB();
-		m_config.m_audioMute = cfg.getAudioMute();
-		m_config.m_playLoop = cfg.getPlayLoop();
-		m_config.m_agc = cfg.getAGC();
+        settings.m_bandwidth = band;
+        settings.m_lowCutoff = lowCutoff;
 
-		m_config.m_agcTime = cfg.getAGCTime(); // ms
-		m_config.m_agcOrder = cfg.getAGCOrder();
-		m_config.m_agcThresholdEnable = cfg.getAGCThreshold() != -99;
-		m_config.m_agcThreshold = CalcDb::powerFromdB(cfg.getAGCThreshold()); // power dB
-		m_config.m_agcThresholdGate = cfg.getAGCThresholdGate(); // ms
-		m_config.m_agcThresholdDelay = cfg.getAGCThresholdDelay(); // ms
+        applySettings(settings, cfg.getForce());
 
-        apply();
+        qDebug() << "SSBMod::handleMessage: MsgConfigureSSBMod:"
+                << " m_bandwidth: " << settings.m_bandwidth
+                << " m_lowCutoff: " << settings.m_lowCutoff
+                << " m_toneFrequency: " << settings.m_toneFrequency
+                << " m_volumeFactor: " << settings.m_volumeFactor
+                << " m_spanLog2: " << settings.m_spanLog2
+                << " m_outputSampleRate: " << m_settings.m_outputSampleRate
+                << " m_audioSampleRate: " << settings.m_audioSampleRate
+                << " m_audioBinaural: " << settings.m_audioBinaural
+                << " m_audioFlipChannels: " << settings.m_audioFlipChannels
+                << " m_dsb: " << settings.m_dsb
+                << " m_audioMute: " << settings.m_audioMute
+                << " m_playLoop: " << settings.m_playLoop
+                << " m_agc: " << settings.m_agc
+                << " m_agcTime: " << settings.m_agcTime
+                << " m_agcOrder: " << settings.m_agcOrder
+                << " m_agcThresholdEnable: " << settings.m_agcThresholdEnable
+                << " m_agcThreshold: " << settings.m_agcThreshold
+                << " m_agcThresholdGate: " << settings.m_agcThresholdGate
+                << " m_agcThresholdDelay: " << settings.m_agcThresholdDelay
+                << " force: " << cfg.getForce();
 
-		m_settingsMutex.unlock();
-
-		qDebug() << "SSBMod::handleMessage: MsgConfigureSSBMod:"
-				<< " m_bandwidth: " << m_config.m_bandwidth
-				<< " m_lowCutoff: " << m_config.m_lowCutoff
-                << " m_toneFrequency: " << m_config.m_toneFrequency
-                << " m_volumeFactor: " << m_config.m_volumeFactor
-				<< " m_spanLog2: " << m_config.m_spanLog2
-				<< " m_audioBinaural: " << m_config.m_audioBinaural
-				<< " m_audioFlipChannels: " << m_config.m_audioFlipChannels
-				<< " m_dsb: " << m_config.m_dsb
-				<< " m_audioMute: " << m_config.m_audioMute
-				<< " m_playLoop: " << m_config.m_playLoop
-				<< " m_agc: " << m_config.m_agc
-				<< " m_agcTime: " << m_config.m_agcTime
-                << " m_agcOrder: " << m_config.m_agcOrder
-                << " m_agcThresholdEnable: " << m_config.m_agcThresholdEnable
-                << " m_agcThreshold: " << m_config.m_agcThreshold
-                << " m_agcThresholdGate: " << m_config.m_agcThresholdGate
-                << " m_agcThresholdDelay: " << m_config.m_agcThresholdDelay;
-
-		return true;
-	}
+        return true;
+    }
 	else if (MsgConfigureFileSourceName::match(cmd))
     {
         MsgConfigureFileSourceName& conf = (MsgConfigureFileSourceName&) cmd;
@@ -695,115 +640,6 @@ bool SSBMod::handleMessage(const Message& cmd)
 	}
 }
 
-void SSBMod::apply()
-{
-    if ((m_config.m_bandwidth != m_running.m_bandwidth) ||
-        (m_config.m_lowCutoff != m_running.m_lowCutoff) ||
-        (m_config.m_audioSampleRate != m_running.m_audioSampleRate))
-    {
-        m_settingsMutex.lock();
-        m_SSBFilter->create_filter(m_config.m_lowCutoff / m_config.m_audioSampleRate, m_config.m_bandwidth / m_config.m_audioSampleRate);
-        m_DSBFilter->create_dsb_filter((2.0f * m_config.m_bandwidth) / m_config.m_audioSampleRate);
-        m_settingsMutex.unlock();
-    }
-
-	if ((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) ||
-	    (m_config.m_outputSampleRate != m_running.m_outputSampleRate))
-	{
-        m_settingsMutex.lock();
-		m_carrierNco.setFreq(m_config.m_inputFrequencyOffset, m_config.m_outputSampleRate);
-        m_settingsMutex.unlock();
-	}
-
-	if((m_config.m_outputSampleRate != m_running.m_outputSampleRate) ||
-	   (m_config.m_bandwidth != m_running.m_bandwidth) ||
-	   (m_config.m_audioSampleRate != m_running.m_audioSampleRate))
-	{
-		m_settingsMutex.lock();
-		m_interpolatorDistanceRemain = 0;
-		m_interpolatorConsumed = false;
-		m_interpolatorDistance = (Real) m_config.m_audioSampleRate / (Real) m_config.m_outputSampleRate;
-        m_interpolator.create(48, m_config.m_audioSampleRate, m_config.m_bandwidth, 3.0);
-		m_settingsMutex.unlock();
-	}
-
-	if ((m_config.m_toneFrequency != m_running.m_toneFrequency) ||
-	    (m_config.m_audioSampleRate != m_running.m_audioSampleRate))
-	{
-        m_settingsMutex.lock();
-        m_toneNco.setFreq(m_config.m_toneFrequency, m_config.m_audioSampleRate);
-        m_settingsMutex.unlock();
-	}
-
-	if (m_config.m_audioSampleRate != m_running.m_audioSampleRate)
-	{
-        m_settingsMutex.lock();
-	    m_cwKeyer.setSampleRate(m_config.m_audioSampleRate);
-        m_settingsMutex.unlock();
-	}
-
-	if (m_config.m_dsb != m_running.m_dsb)
-	{
-		if (m_config.m_dsb)
-		{
-			memset(m_DSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen));
-			m_DSBFilterBufferIndex = 0;
-		}
-		else
-		{
-			memset(m_SSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen>>1));
-			m_SSBFilterBufferIndex = 0;
-		}
-	}
-
-    if ((m_config.m_agcTime != m_running.m_agcTime) || (m_config.m_agcOrder != m_running.m_agcOrder))
-    {
-        m_inAGC.resize(m_config.m_agcTime, m_config.m_agcOrder);
-    }
-
-    if (m_config.m_agcThresholdEnable != m_running.m_agcThresholdEnable)
-    {
-        m_inAGC.setThresholdEnable(m_config.m_agcThresholdEnable);
-    }
-
-    if (m_config.m_agcThreshold != m_running.m_agcThreshold)
-    {
-        m_inAGC.setThreshold(m_config.m_agcThreshold);
-    }
-
-    if (m_config.m_agcThresholdGate != m_running.m_agcThresholdGate)
-    {
-        m_inAGC.setGate(m_config.m_agcThresholdGate);
-    }
-
-    if (m_config.m_agcThresholdDelay != m_running.m_agcThresholdDelay)
-    {
-        m_inAGC.setStepDownDelay(m_config.m_agcThresholdDelay);
-    }
-
-	m_running.m_outputSampleRate = m_config.m_outputSampleRate;
-	m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset;
-	m_running.m_bandwidth = m_config.m_bandwidth;
-	m_running.m_lowCutoff = m_config.m_lowCutoff;
-	m_running.m_usb = m_config.m_usb;
-	m_running.m_toneFrequency = m_config.m_toneFrequency;
-    m_running.m_volumeFactor = m_config.m_volumeFactor;
-	m_running.m_audioSampleRate = m_config.m_audioSampleRate;
-	m_running.m_spanLog2 = m_config.m_spanLog2;
-	m_running.m_audioBinaural = m_config.m_audioBinaural;
-	m_running.m_audioFlipChannels = m_config.m_audioFlipChannels;
-	m_running.m_dsb = m_config.m_dsb;
-	m_running.m_audioMute = m_config.m_audioMute;
-	m_running.m_playLoop = m_config.m_playLoop;
-	m_running.m_agc = m_config.m_agc;
-    m_running.m_agcOrder = m_config.m_agcOrder;
-    m_running.m_agcTime = m_config.m_agcTime;
-    m_running.m_agcThresholdEnable = m_config.m_agcThresholdEnable;
-    m_running.m_agcThreshold = m_config.m_agcThreshold;
-    m_running.m_agcThresholdGate = m_config.m_agcThresholdGate;
-    m_running.m_agcThresholdDelay = m_config.m_agcThresholdDelay;
-}
-
 void SSBMod::openFileStream()
 {
     if (m_ifstream.is_open()) {
@@ -838,3 +674,93 @@ void SSBMod::seekFileStream(int seekPercentage)
         m_ifstream.seekg(seekPoint, std::ios::beg);
     }
 }
+
+void SSBMod::applySettings(const SSBModSettings& settings, bool force)
+{
+    if ((settings.m_bandwidth != m_settings.m_bandwidth) ||
+        (settings.m_lowCutoff != m_settings.m_lowCutoff) ||
+        (settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
+    {
+        m_settingsMutex.lock();
+        m_SSBFilter->create_filter(settings.m_lowCutoff / settings.m_audioSampleRate, settings.m_bandwidth / settings.m_audioSampleRate);
+        m_DSBFilter->create_dsb_filter((2.0f * settings.m_bandwidth) / settings.m_audioSampleRate);
+        m_settingsMutex.unlock();
+    }
+
+    if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) ||
+        (settings.m_outputSampleRate != m_settings.m_outputSampleRate) || force)
+    {
+        m_settingsMutex.lock();
+        m_carrierNco.setFreq(settings.m_inputFrequencyOffset, settings.m_outputSampleRate);
+        m_settingsMutex.unlock();
+    }
+
+    if((settings.m_outputSampleRate != m_settings.m_outputSampleRate) ||
+       (settings.m_bandwidth != m_settings.m_bandwidth) ||
+       (settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
+    {
+        m_settingsMutex.lock();
+        m_interpolatorDistanceRemain = 0;
+        m_interpolatorConsumed = false;
+        m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) settings.m_outputSampleRate;
+        m_interpolator.create(48, settings.m_audioSampleRate, settings.m_bandwidth, 3.0);
+        m_settingsMutex.unlock();
+    }
+
+    if ((settings.m_toneFrequency != m_settings.m_toneFrequency) ||
+        (settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
+    {
+        m_settingsMutex.lock();
+        m_toneNco.setFreq(settings.m_toneFrequency, settings.m_audioSampleRate);
+        m_settingsMutex.unlock();
+    }
+
+    if ((settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
+    {
+        m_settingsMutex.lock();
+        m_cwKeyer.setSampleRate(settings.m_audioSampleRate);
+        m_settingsMutex.unlock();
+    }
+
+    if ((settings.m_dsb != m_settings.m_dsb) || force)
+    {
+        if (settings.m_dsb)
+        {
+            memset(m_DSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen));
+            m_DSBFilterBufferIndex = 0;
+        }
+        else
+        {
+            memset(m_SSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen>>1));
+            m_SSBFilterBufferIndex = 0;
+        }
+    }
+
+    if ((settings.m_agcTime != m_settings.m_agcTime) ||
+        (settings.m_agcOrder != m_settings.m_agcOrder) || force)
+    {
+        m_inAGC.resize(settings.m_agcTime, settings.m_agcOrder);
+    }
+
+    if ((settings.m_agcThresholdEnable != m_settings.m_agcThresholdEnable) || force)
+    {
+        m_inAGC.setThresholdEnable(settings.m_agcThresholdEnable);
+    }
+
+    if ((settings.m_agcThreshold != m_settings.m_agcThreshold) || force)
+    {
+        m_inAGC.setThreshold(settings.m_agcThreshold);
+    }
+
+    if ((settings.m_agcThresholdGate != m_settings.m_agcThresholdGate) || force)
+    {
+        m_inAGC.setGate(settings.m_agcThresholdGate);
+    }
+
+    if ((settings.m_agcThresholdDelay != m_settings.m_agcThresholdDelay) || force)
+    {
+        m_inAGC.setStepDownDelay(settings.m_agcThresholdDelay);
+    }
+
+    m_settings = settings;
+}
diff --git a/plugins/channeltx/modssb/ssbmod.h b/plugins/channeltx/modssb/ssbmod.h
index 63dd0f4aa..150c91310 100644
--- a/plugins/channeltx/modssb/ssbmod.h
+++ b/plugins/channeltx/modssb/ssbmod.h
@@ -33,6 +33,8 @@
 #include "audio/audiofifo.h"
 #include "util/message.h"
 
+#include "ssbmodsettings.h"
+
 class SSBMod : public BasebandSampleSource {
     Q_OBJECT
 
@@ -46,6 +48,52 @@ public:
         SSBModInputCWTone
     } SSBModInputAF;
 
+    class MsgConfigureSSBMod : public Message {
+        MESSAGE_CLASS_DECLARATION
+
+    public:
+        const SSBModSettings& getSettings() const { return m_settings; }
+        bool getForce() const { return m_force; }
+
+        static MsgConfigureSSBMod* create(const SSBModSettings& settings, bool force)
+        {
+            return new MsgConfigureSSBMod(settings, force);
+        }
+
+    private:
+        SSBModSettings m_settings;
+        bool m_force;
+
+        MsgConfigureSSBMod(const SSBModSettings& settings, bool force) :
+            Message(),
+            m_settings(settings),
+            m_force(force)
+        { }
+    };
+
+    class MsgConfigureChannelizer : public Message {
+        MESSAGE_CLASS_DECLARATION
+
+    public:
+        int getSampleRate() const { return m_sampleRate; }
+        int getCenterFrequency() const { return m_centerFrequency; }
+
+        static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
+        {
+            return new MsgConfigureChannelizer(sampleRate, centerFrequency);
+        }
+
+    private:
+        int m_sampleRate;
+        int  m_centerFrequency;
+
+        MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
+            Message(),
+            m_sampleRate(sampleRate),
+            m_centerFrequency(centerFrequency)
+        { }
+    };
+
     class MsgConfigureFileSourceName : public Message
     {
         MESSAGE_CLASS_DECLARATION
@@ -177,24 +225,6 @@ public:
     SSBMod(BasebandSampleSink* sampleSink);
     ~SSBMod();
 
-    void configure(MessageQueue* messageQueue,
-            Real bandwidth,
-			Real lowCutoff,
-            float toneFrequency,
-			float volumeFactor,
-			int spanLog2,
-			bool audioBinaural,
-			bool audioFlipChannels,
-			bool dsb,
-			bool audioMute,
-            bool playLoop,
-            bool agc,
-            float agcOrder,
-            int agcTime,
-            int agcThreshold,
-            int agcThresholdGate,
-            int agcThresholdDelay);
-
     virtual void pull(Sample& sample);
     virtual void pullAudio(int nbSamples);
     virtual void start();
@@ -216,178 +246,12 @@ signals:
 
 
 private:
-    class MsgConfigureSSBMod : public Message
-    {
-        MESSAGE_CLASS_DECLARATION
-
-    public:
-        Real getBandwidth() const { return m_bandwidth; }
-        Real getLowCutoff() const { return m_lowCutoff; }
-        float getToneFrequency() const { return m_toneFrequency; }
-        float getVolumeFactor() const { return m_volumeFactor; }
-        int getSpanLog2() const { return m_spanLog2; }
-        bool getAudioBinaural() const { return m_audioBinaural; }
-        bool getAudioFlipChannels() const { return m_audioFlipChannels; }
-        bool getDSB() const { return m_dsb; }
-        bool getAudioMute() const { return m_audioMute; }
-        bool getPlayLoop() const { return m_playLoop; }
-        bool getAGC() const { return m_agc; }
-        float getAGCOrder() const { return m_agcOrder; }
-        int getAGCTime() const { return m_agcTime; }
-        int getAGCThreshold() const { return m_agcThreshold; }
-        int getAGCThresholdGate() const { return m_agcThresholdGate; }
-        int getAGCThresholdDelay() const { return m_agcThresholdDelay; }
-
-        static MsgConfigureSSBMod* create(Real bandwidth,
-        		Real lowCutoff,
-        		float toneFrequency,
-				float volumeFactor,
-				int spanLog2,
-				bool audioBinaural,
-				bool audioFlipChannels,
-				bool dsb,
-				bool audioMute,
-				bool playLoop,
-				bool agc,
-				float agcOrder,
-				int agcTime,
-                int agcThreshold,
-                int agcThresholdGate,
-                int agcThresholdDelay)
-        {
-            return new MsgConfigureSSBMod(bandwidth,
-            		lowCutoff,
-					toneFrequency,
-					volumeFactor,
-					spanLog2,
-					audioBinaural,
-					audioFlipChannels,
-					dsb,
-					audioMute,
-					playLoop,
-					agc,
-					agcOrder,
-					agcTime,
-					agcThreshold,
-					agcThresholdGate,
-					agcThresholdDelay);
-        }
-
-    private:
-        Real m_bandwidth;
-        Real m_lowCutoff;
-        float m_toneFrequency;
-        float m_volumeFactor;
-		int  m_spanLog2;
-		bool m_audioBinaural;
-		bool m_audioFlipChannels;
-		bool m_dsb;
-        bool m_audioMute;
-        bool m_playLoop;
-        bool m_agc;
-        float m_agcOrder;
-        int m_agcTime;
-        int m_agcThreshold;
-        int m_agcThresholdGate;
-        int m_agcThresholdDelay;
-
-        MsgConfigureSSBMod(Real bandwidth,
-        		Real lowCutoff,
-        		float toneFrequency,
-				float volumeFactor,
-				int spanLog2,
-				bool audioBinaural,
-				bool audioFlipChannels,
-				bool dsb,
-				bool audioMute,
-				bool playLoop,
-				bool agc,
-				float agcOrder,
-				int agcTime,
-				int agcThreshold,
-				int agcThresholdGate,
-				int agcThresholdDelay) :
-            Message(),
-            m_bandwidth(bandwidth),
-			m_lowCutoff(lowCutoff),
-            m_toneFrequency(toneFrequency),
-            m_volumeFactor(volumeFactor),
-			m_spanLog2(spanLog2),
-			m_audioBinaural(audioBinaural),
-			m_audioFlipChannels(audioFlipChannels),
-			m_dsb(dsb),
-            m_audioMute(audioMute),
-			m_playLoop(playLoop),
-			m_agc(agc),
-			m_agcOrder(agcOrder),
-			m_agcTime(agcTime),
-			m_agcThreshold(agcThreshold),
-			m_agcThresholdGate(agcThresholdGate),
-			m_agcThresholdDelay(agcThresholdDelay)
-        { }
-    };
-
-    //=================================================================
-
     enum RateState {
         RSInitialFill,
         RSRunning
     };
 
-    struct Config {
-        int m_basebandSampleRate;
-        int m_outputSampleRate;
-        qint64 m_inputFrequencyOffset;
-        Real m_bandwidth;
-        Real m_lowCutoff;
-        bool m_usb;
-        float m_toneFrequency;
-        float m_volumeFactor;
-        quint32 m_audioSampleRate;
-		int  m_spanLog2;
-		bool m_audioBinaural;
-		bool m_audioFlipChannels;
-		bool m_dsb;
-		bool m_audioMute;
-        bool m_playLoop;
-        bool m_agc;
-        float m_agcOrder;
-        int m_agcTime;
-        bool m_agcThresholdEnable;
-        double m_agcThreshold;
-        int m_agcThresholdGate;
-        int m_agcThresholdDelay;
-
-        Config() :
-            m_basebandSampleRate(0),
-            m_outputSampleRate(0),
-            m_inputFrequencyOffset(0),
-            m_bandwidth(3000.0f),
-			m_lowCutoff(300.0f),
-			m_usb(true),
-            m_toneFrequency(1000.0f),
-            m_volumeFactor(1.0f),
-            m_audioSampleRate(0),
-			m_spanLog2(3),
-			m_audioBinaural(false),
-			m_audioFlipChannels(false),
-			m_dsb(false),
-            m_audioMute(false),
-			m_playLoop(false),
-			m_agc(false),
-			m_agcOrder(0.2),
-			m_agcTime(9600),
-			m_agcThresholdEnable(true),
-			m_agcThreshold(1e-4),
-			m_agcThresholdGate(192),
-			m_agcThresholdDelay(2400)
-        { }
-    };
-
-    //=================================================================
-
-    Config m_config;
-    Config m_running;
+    SSBModSettings m_settings;
 
     NCOF m_carrierNco;
     NCOF m_toneNco;
@@ -407,10 +271,6 @@ private:
 	BasebandSampleSink* m_sampleSink;
 	SampleVector m_sampleBuffer;
 
-//    Real m_magsqSpectrum;
-//    Real m_magsqSum;
-//    Real m_magsqPeak;
-//    int  m_magsqCount;
     fftfilt::cmplx m_sum;
     int m_undersampleCount;
     int m_sumCount;
@@ -440,7 +300,7 @@ private:
 
     static const int m_levelNbSamples;
 
-    void apply();
+    void applySettings(const SSBModSettings& settings, bool force = false);
     void pullAF(Complex& sample);
     void calculateLevel(Complex& sample);
     void modulateSample();
diff --git a/plugins/channeltx/modssb/ssbmodgui.cpp b/plugins/channeltx/modssb/ssbmodgui.cpp
index 9ed3fbb27..220f50af2 100644
--- a/plugins/channeltx/modssb/ssbmodgui.cpp
+++ b/plugins/channeltx/modssb/ssbmodgui.cpp
@@ -63,6 +63,7 @@ qint64 SSBModGUI::getCenterFrequency() const {
 void SSBModGUI::setCenterFrequency(qint64 centerFrequency)
 {
 	m_channelMarker.setCenterFrequency(centerFrequency);
+    m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
 	applySettings();
 }
 
@@ -81,14 +82,14 @@ bool SSBModGUI::deserialize(const QByteArray& data)
     if(m_settings.deserialize(data))
     {
         displaySettings();
-        applySettings(); // will have true
+        applySettings(true); // will have true
         return true;
     }
     else
     {
         m_settings.resetToDefaults();
         displaySettings();
-        applySettings(); // will have true
+        applySettings(true); // will have true
         return false;
     }
 }
@@ -478,7 +479,6 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* pa
     ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
     ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
 
-	//m_channelMarker = new ChannelMarker(this);
 	m_channelMarker.setColor(Qt::green);
 	m_channelMarker.setBandwidth(m_rate);
 	m_channelMarker.setSidebands(ChannelMarker::usb);
@@ -497,7 +497,7 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* pa
     m_settings.setCWKeyerGUI(ui->cwKeyerGUI);
 
     displaySettings();
-	applySettings();
+	applySettings(true);
 	setNewRate(m_settings.m_spanLog2);
 
 	connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
@@ -512,7 +512,6 @@ SSBModGUI::~SSBModGUI()
 	delete m_channelizer;
 	delete m_ssbMod;
 	delete m_spectrumVis;
-	//delete m_channelMarker;
 	delete ui;
 }
 
@@ -597,35 +596,16 @@ void SSBModGUI::blockApplySettings(bool block)
     m_doApplySettings = !block;
 }
 
-void SSBModGUI::applySettings()
+void SSBModGUI::applySettings(bool force)
 {
 	if (m_doApplySettings)
 	{
-		setTitleColor(m_channelMarker.getColor());
-
 		m_channelizer->configure(m_channelizer->getInputMessageQueue(),
 			48000,
 			m_channelMarker.getCenterFrequency());
 
-		ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
-
-        m_ssbMod->configure(m_ssbMod->getInputMessageQueue(),
-            m_settings.m_bandwidth,
-            m_settings.m_lowCutoff,
-            m_settings.m_toneFrequency,
-            m_settings.m_volumeFactor,
-            m_settings.m_spanLog2,
-            m_settings.m_audioBinaural,
-            m_settings.m_audioFlipChannels,
-            m_settings.m_dsb,
-            m_settings.m_audioMute,
-            m_settings.m_playLoop,
-            m_settings.m_agc,
-            m_settings.m_agcOrder,
-            m_settings.m_agcTime,
-            m_settings.m_agcThreshold,
-            m_settings.m_agcThresholdGate,
-            m_settings.m_agcThresholdDelay);
+		SSBMod::MsgConfigureSSBMod *msg = SSBMod::MsgConfigureSSBMod::create(m_settings, force);
+		m_ssbMod->getInputMessageQueue()->push(msg);
 	}
 }
 
diff --git a/plugins/channeltx/modssb/ssbmodgui.h b/plugins/channeltx/modssb/ssbmodgui.h
index 71db67a66..f3b6d4182 100644
--- a/plugins/channeltx/modssb/ssbmodgui.h
+++ b/plugins/channeltx/modssb/ssbmodgui.h
@@ -101,7 +101,6 @@ private:
     bool m_basicSettingsShown;
     bool m_doApplySettings;
 	int m_rate;
-	int m_spanLog2;
 
     ThreadedBasebandSampleSource* m_threadedChannelizer;
     UpChannelizer* m_channelizer;
@@ -118,8 +117,6 @@ private:
     SSBMod::SSBModInputAF m_modAFInput;
     MessageQueue m_inputMessageQueue;
 
-    //static const int m_agcTimeConstant[]; //!< time constant index to value in ms
-
     explicit SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL);
     virtual ~SSBModGUI();
 
@@ -127,7 +124,7 @@ private:
     bool setNewRate(int spanLog2);
 
     void blockApplySettings(bool block);
-    void applySettings();
+    void applySettings(bool force = false);
     void displaySettings();
     void displayAGCPowerThreshold();
     void updateWithStreamData();