diff --git a/Readme.md b/Readme.md
index d18aaa1fa..280d18de1 100644
--- a/Readme.md
+++ b/Readme.md
@@ -74,6 +74,10 @@ The audio devices with Qt are supported through pulseaudio and unless you are us
 
 In case you cannot see anything related to HDMI or your desired audio device in pavucontrol just restart pulseaudio with `pulseaudio -k` (`-k` kills the previous instance before restarting) and do the above steps again.
 
+<h1>Note on udev rules</h1>
+
+On Linux you need specific files in `/etc/udev/rules.d` to be able to access the SDR hardware. Please refer to the respective hardware vendor instructions to install these files.
+
 <h1>Software build on Linux</h1>
 
 Plese consult the [Wiki page for compilation in Linux](https://github.com/f4exb/sdrangel/wiki/Compile-from-source-in-Linux). The notes below are left for further information if needed although you should be all set with the Wiki.
diff --git a/plugins/samplemimo/testmi/testmi.cpp b/plugins/samplemimo/testmi/testmi.cpp
index ce1d7317e..0307f4c0c 100644
--- a/plugins/samplemimo/testmi/testmi.cpp
+++ b/plugins/samplemimo/testmi/testmi.cpp
@@ -29,6 +29,7 @@
 #include "device/deviceapi.h"
 #include "dsp/dspcommands.h"
 #include "dsp/dspengine.h"
+#include "dsp/dspdevicemimoengine.h"
 #include "dsp/devicesamplesource.h"
 #include "dsp/filerecord.h"
 
@@ -388,7 +389,9 @@ bool TestMI::applySettings(const TestMISettings& settings, bool force)
         int sampleRate = settings.m_sampleRate/(1<<settings.m_log2Decim);
         DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_centerFrequency);
         m_fileSink->handleMessage(*notif); // forward to file sink
-        m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
+        DSPDeviceMIMOEngine::SignalNotification *engineNotif = new DSPDeviceMIMOEngine::SignalNotification(
+            sampleRate, settings.m_centerFrequency, true, 0);
+        m_deviceAPI->getDeviceEngineInputMessageQueue()->push(engineNotif);
     }
 
     if ((m_settings.m_modulationTone != settings.m_modulationTone) || force)
diff --git a/plugins/samplemimo/testmi/testmigui.cpp b/plugins/samplemimo/testmi/testmigui.cpp
index 032ee23d1..fe9ece930 100644
--- a/plugins/samplemimo/testmi/testmigui.cpp
+++ b/plugins/samplemimo/testmi/testmigui.cpp
@@ -30,6 +30,7 @@
 #include "gui/crightclickenabler.h"
 #include "gui/basicdevicesettingsdialog.h"
 #include "dsp/dspengine.h"
+#include "dsp/dspdevicemimoengine.h"
 #include "dsp/dspcommands.h"
 #include "util/db.h"
 
@@ -489,12 +490,13 @@ void TestMIGui::handleInputMessages()
 
     while ((message = m_inputMessageQueue.pop()) != 0)
     {
-        if (DSPSignalNotification::match(*message))
+        if (DSPDeviceMIMOEngine::SignalNotification::match(*message))
         {
-            DSPSignalNotification* notif = (DSPSignalNotification*) message;
+            DSPDeviceMIMOEngine::SignalNotification* notif = (DSPDeviceMIMOEngine::SignalNotification*) message;
             m_deviceSampleRate = notif->getSampleRate();
             m_deviceCenterFrequency = notif->getCenterFrequency();
-            qDebug("TestMIGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu",
+            // Do not consider multiple sources at this time
+            qDebug("TestMIGui::handleInputMessages: DSPDeviceMIMOEngine::SignalNotification: SampleRate:%d, CenterFrequency:%llu",
                     notif->getSampleRate(),
                     notif->getCenterFrequency());
             updateSampleRateAndFrequency();
diff --git a/sdrbase/device/deviceapi.cpp b/sdrbase/device/deviceapi.cpp
index 0ce097d16..49108bdc2 100644
--- a/sdrbase/device/deviceapi.cpp
+++ b/sdrbase/device/deviceapi.cpp
@@ -74,6 +74,13 @@ void DeviceAPI::removeAncillarySink(BasebandSampleSink* sink)
     }
 }
 
+void DeviceAPI::setSpectrumSinkInput(bool sourceElseSink, unsigned int index)
+{
+    if (m_deviceMIMOEngine) { // In practice this is only used in the MIMO case
+        m_deviceMIMOEngine->setSpectrumSinkInput(sourceElseSink, index);
+    }
+}
+
 void DeviceAPI::addChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex)
 {
     (void) streamIndex;
diff --git a/sdrbase/device/deviceapi.h b/sdrbase/device/deviceapi.h
index bcda31ed9..735ece4b7 100644
--- a/sdrbase/device/deviceapi.h
+++ b/sdrbase/device/deviceapi.h
@@ -68,6 +68,7 @@ public:
 
     void addAncillarySink(BasebandSampleSink* sink);     //!< Adds a sink to receive full baseband and that is not a channel (e.g. spectrum)
     void removeAncillarySink(BasebandSampleSink* sink);  //!< Removes it
+    void setSpectrumSinkInput(bool sourceElseSink = true, unsigned int index = 0); //!< Used in the MIMO case to select which stream is used as input to main spectrum
 
     void addChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex = 0);        //!< Add a channel sink (Rx)
     void removeChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex = 0);     //!< Remove a channel sink (Rx)
diff --git a/sdrbase/dsp/devicesamplemimo.h b/sdrbase/dsp/devicesamplemimo.h
index 5f84adf3d..54dcbc0ab 100644
--- a/sdrbase/dsp/devicesamplemimo.h
+++ b/sdrbase/dsp/devicesamplemimo.h
@@ -126,6 +126,11 @@ public:
     unsigned int getNbSinkFifos() const { return m_sampleSinkFifos.size(); }     //!< Get the number of Rx FIFOs
 	SampleSourceFifo* getSampleSourceFifo(unsigned int index); //!< Get Tx FIFO at index
     SampleSinkFifo* getSampleSinkFifo(unsigned int index);     //!< Get Rx FIFO at index
+    // Streams and FIFOs are in opposed source/sink type whick makes it confusing when stream direction is involved:
+    //   Rx: source stream -> sink FIFO    -> channel sinks
+    //   Tx: sink stream   <- source FIFO  <- channel sources
+    unsigned int getNbSourceStreams() const { return m_sampleSinkFifos.size(); } //!< Commodity function same as getNbSinkFifos (Rx or source streams)
+    unsigned int getNbSinkStreams() const { return m_sampleSourceFifos.size(); } //!< Commodity function same as getNbSourceFifos (Tx or sink streams)
 
 protected slots:
 	void handleInputMessages();
diff --git a/sdrbase/dsp/dspdevicemimoengine.cpp b/sdrbase/dsp/dspdevicemimoengine.cpp
index 4a8681b0e..225c382c8 100644
--- a/sdrbase/dsp/dspdevicemimoengine.cpp
+++ b/sdrbase/dsp/dspdevicemimoengine.cpp
@@ -38,12 +38,15 @@ MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::GetErrorMessage, Message)
 MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::GetMIMODeviceDescription, Message)
 MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::ConfigureCorrection, Message)
 MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SignalNotification, Message)
+MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SetSpectrumSinkInput, Message)
 
 DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) :
 	QThread(parent),
     m_uid(uid),
     m_state(StNotStarted),
-    m_deviceSampleMIMO(nullptr)
+    m_deviceSampleMIMO(nullptr),
+    m_spectrumInputSourceElseSink(true),
+    m_spectrumInputIndex(0)
 {
 	connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
 	connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection);
@@ -189,6 +192,15 @@ void DSPDeviceMIMOEngine::removeSpectrumSink(BasebandSampleSink* spectrumSink)
 	m_syncMessenger.sendWait(cmd);
 }
 
+void DSPDeviceMIMOEngine::setSpectrumSinkInput(bool sourceElseSink, int index)
+{
+	qDebug() << "DSPDeviceSinkEngine::setSpectrumSinkInput: "
+        << " sourceElseSink: " << sourceElseSink
+        << " index: " << index;
+    SetSpectrumSinkInput cmd(sourceElseSink, index);
+    m_syncMessenger.sendWait(cmd);
+}
+
 QString DSPDeviceMIMOEngine::errorMessage()
 {
 	qDebug() << "DSPDeviceMIMOEngine::errorMessage";
@@ -213,17 +225,13 @@ void DSPDeviceMIMOEngine::work(int nbWriteSamples)
 {
     (void) nbWriteSamples;
     // Sources
-    for (unsigned int isource = 0; isource < m_deviceSampleMIMO->getNbSourceFifos(); isource++)
+    for (unsigned int isource = 0; isource < m_deviceSampleMIMO->getNbSourceStreams(); isource++)
     {
-        if (isource >= m_sourceStreamSampleRates.size()) {
-            continue;
-        }
-
         SampleSinkFifo* sampleFifo = m_deviceSampleMIMO->getSampleSinkFifo(isource); // sink FIFO is for Rx
-	    std::size_t samplesDone = 0;
+	    int samplesDone = 0;
 	    bool positiveOnly = false;
 
-        while ((sampleFifo->fill() > 0) && (m_inputMessageQueue.size() == 0) && (samplesDone < m_sourceStreamSampleRates[isource]))
+        while ((sampleFifo->fill() > 0) && (m_inputMessageQueue.size() == 0) && (samplesDone < m_deviceSampleMIMO->getSourceSampleRate(isource)))
         {
             SampleVector::iterator part1begin;
             SampleVector::iterator part1end;
@@ -245,6 +253,11 @@ void DSPDeviceMIMOEngine::work(int nbWriteSamples)
                     }
                 }
 
+                // possibly feed data to spectrum sink
+                if ((m_spectrumSink) && (m_spectrumInputSourceElseSink) && (isource == m_spectrumInputIndex)) {
+                    m_spectrumSink->feed(part1begin, part1end, positiveOnly);
+                }
+
                 // feed data to threaded sinks
                 if (isource < m_threadedBasebandSampleSinks.size())
                 {
@@ -267,6 +280,11 @@ void DSPDeviceMIMOEngine::work(int nbWriteSamples)
                     }
                 }
 
+                // possibly feed data to spectrum sink
+                if ((m_spectrumSink) && (m_spectrumInputSourceElseSink) && (isource == m_spectrumInputIndex)) {
+                    m_spectrumSink->feed(part2begin, part2end, positiveOnly);
+                }
+
                 // feed data to threaded sinks
                 if (isource < m_threadedBasebandSampleSinks.size())
                 {
@@ -334,10 +352,6 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoIdle()
 	m_deviceSampleMIMO->stop();
 	m_deviceDescription.clear();
 
-    for (std::vector<uint32_t>::iterator it = m_sourceStreamSampleRates.begin(); it != m_sourceStreamSampleRates.end(); ++it) {
-        *it = 0;
-    }
-
 	return StIdle;
 }
 
@@ -370,7 +384,9 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoInit()
 	qDebug() << "DSPDeviceMIMOEngine::gotoInit: "
 	        << " m_deviceDescription: " << m_deviceDescription.toStdString().c_str();
 
-    for (unsigned int isource = 0; isource < m_deviceSampleMIMO->getNbSourceFifos(); isource++)
+    // Rx
+
+    for (unsigned int isource = 0; isource < m_deviceSampleMIMO->getNbSinkFifos(); isource++)
     {
         if (isource < m_sourcesCorrections.size())
         {
@@ -380,43 +396,42 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoInit()
             m_sourcesCorrections[isource].m_qRange = 1 << 16;
         }
 
-        if ((isource < m_sourceCenterFrequencies.size()) && (isource < m_sourceStreamSampleRates.size()))
+        quint64 sourceCenterFrequency = m_deviceSampleMIMO->getSourceCenterFrequency(isource);
+        int sourceStreamSampleRate = m_deviceSampleMIMO->getSourceSampleRate(isource);
+
+        qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceCenterFrequencies[%d] = %llu", isource,  sourceCenterFrequency);
+        qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceStreamSampleRates[%d] = %d", isource,  sourceStreamSampleRate);
+
+        DSPSignalNotification notif(sourceStreamSampleRate, sourceCenterFrequency);
+
+        if (isource < m_basebandSampleSinks.size())
         {
-            m_sourceCenterFrequencies[isource] = m_deviceSampleMIMO->getSourceCenterFrequency(isource);
-            m_sourceStreamSampleRates[isource] = m_deviceSampleMIMO->getSourceSampleRate(isource);
-
-            qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceCenterFrequencies[%d] = %llu", isource,  m_sourceCenterFrequencies[isource]);
-            qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceStreamSampleRates[%d] = %d", isource,  m_sourceStreamSampleRates[isource]);
-
-	        DSPSignalNotification notif(m_sourceStreamSampleRates[isource], m_sourceCenterFrequencies[isource]);
-
-            if (isource < m_basebandSampleSinks.size())
+            for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks[isource].begin(); it != m_basebandSampleSinks[isource].end(); ++it)
             {
-                for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks[isource].begin(); it != m_basebandSampleSinks[isource].end(); ++it)
-                {
-                    qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing " << (*it)->objectName().toStdString().c_str();
-                    (*it)->handleMessage(notif);
-                }
+                qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing " << (*it)->objectName().toStdString().c_str();
+                (*it)->handleMessage(notif);
             }
-
-            if (isource < m_threadedBasebandSampleSinks.size())
-            {
-                for (ThreadedBasebandSampleSinks::const_iterator it = m_threadedBasebandSampleSinks[isource].begin(); it != m_threadedBasebandSampleSinks[isource].end(); ++it)
-                {
-                    qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")";
-                    (*it)->handleSinkMessage(notif);
-                }
-            }
-
-            // pass data to listeners
-            // if (m_deviceSampleSource->getMessageQueueToGUI())
-            // {
-            //     DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy for the output queue
-            //     m_deviceSampleSource->getMessageQueueToGUI()->push(rep);
-            // }
         }
+
+        if (isource < m_threadedBasebandSampleSinks.size())
+        {
+            for (ThreadedBasebandSampleSinks::const_iterator it = m_threadedBasebandSampleSinks[isource].begin(); it != m_threadedBasebandSampleSinks[isource].end(); ++it)
+            {
+                qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing ThreadedSampleSink(" << (*it)->getSampleSinkObjectName().toStdString().c_str() << ")";
+                (*it)->handleSinkMessage(notif);
+            }
+        }
+
+        // pass data to listeners
+        // if (m_deviceSampleSource->getMessageQueueToGUI())
+        // {
+        //     DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy for the output queue
+        //     m_deviceSampleSource->getMessageQueueToGUI()->push(rep);
+        // }
     }
 
+    //TODO: Tx
+
 	return StReady;
 }
 
@@ -551,11 +566,13 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
 		BasebandSampleSink* sink = msg->getSampleSink();
         unsigned int isource = msg->getIndex();
 
-        if ((isource < m_basebandSampleSinks.size()) && (isource < m_sourceStreamSampleRates.size()) && (isource < m_sourceCenterFrequencies.size()))
+        if ((isource < m_basebandSampleSinks.size()) && (isource < m_deviceSampleMIMO->getNbSourceStreams()))
         {
             m_basebandSampleSinks[isource].push_back(sink);
             // initialize sample rate and center frequency in the sink:
-            DSPSignalNotification msg(m_sourceStreamSampleRates[isource], m_sourceCenterFrequencies[isource]);
+            int sourceStreamSampleRate = m_deviceSampleMIMO->getSourceSampleRate(isource);
+            quint64 sourceCenterFrequency = m_deviceSampleMIMO->getSourceCenterFrequency(isource);
+            DSPSignalNotification msg(sourceStreamSampleRate, sourceCenterFrequency);
             sink->handleMessage(msg);
             // start the sink:
             if(m_state == StRunning) {
@@ -584,11 +601,13 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
 		ThreadedBasebandSampleSink *threadedSink = msg->getThreadedSampleSink();
         unsigned int isource = msg->getIndex();
 
-        if ((isource < m_threadedBasebandSampleSinks.size()) && (isource < m_sourceStreamSampleRates.size()) && (isource < m_sourceCenterFrequencies.size()))
+        if ((isource < m_threadedBasebandSampleSinks.size()) && (isource < m_deviceSampleMIMO->getNbSourceStreams()))
         {
 		    m_threadedBasebandSampleSinks[isource].push_back(threadedSink);
             // initialize sample rate and center frequency in the sink:
-            DSPSignalNotification msg(m_sourceStreamSampleRates[isource], m_sourceCenterFrequencies[isource]);
+            int sourceStreamSampleRate = m_deviceSampleMIMO->getSourceSampleRate(isource);
+            quint64 sourceCenterFrequency = m_deviceSampleMIMO->getSourceCenterFrequency(isource);
+            DSPSignalNotification msg(sourceStreamSampleRate, sourceCenterFrequency);
             threadedSink->handleSinkMessage(msg);
             // start the sink:
             if(m_state == StRunning) {
@@ -614,11 +633,13 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
 		ThreadedBasebandSampleSource *threadedSource = msg->getThreadedSampleSource();
         unsigned int isink = msg->getIndex();
 
-        if ((isink < m_threadedBasebandSampleSources.size()) && (isink < m_sinkStreamSampleRates.size()) && (isink < m_sinkCenterFrequencies.size()))
+        if ((isink < m_threadedBasebandSampleSources.size()) && (isink < m_deviceSampleMIMO->getNbSinkStreams()))
         {
 		    m_threadedBasebandSampleSources[isink].push_back(threadedSource);
             // initialize sample rate and center frequency in the sink:
-            DSPSignalNotification msg(m_sourceStreamSampleRates[isink], m_sourceCenterFrequencies[isink]);
+            int sinkStreamSampleRate = m_deviceSampleMIMO->getSinkSampleRate(isink);
+            quint64 sinkCenterFrequency = m_deviceSampleMIMO->getSinkCenterFrequency(isink);
+            DSPSignalNotification msg(sinkStreamSampleRate, sinkCenterFrequency);
             threadedSource->handleSourceMessage(msg);
             // start the sink:
             if(m_state == StRunning) {
@@ -638,6 +659,63 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
             m_threadedBasebandSampleSources[isink].remove(threadedSource);
         }
 	}
+	else if (AddSpectrumSink::match(*message))
+	{
+		m_spectrumSink = ((AddSpectrumSink*) message)->getSampleSink();
+	}
+    else if (RemoveSpectrumSink::match(*message))
+    {
+        BasebandSampleSink* spectrumSink = ((DSPRemoveSpectrumSink*) message)->getSampleSink();
+        spectrumSink->stop();
+
+        if (!m_spectrumInputSourceElseSink && m_deviceSampleMIMO && (m_spectrumInputIndex <  m_deviceSampleMIMO->getNbSinkStreams()))
+        {
+            SampleSourceFifo *inputFIFO = m_deviceSampleMIMO->getSampleSourceFifo(m_spectrumInputIndex);
+            disconnect(inputFIFO, SIGNAL(dataRead(int)), this, SLOT(handleForwardToSpectrumSink(int)));
+        }
+
+        m_spectrumSink = nullptr;
+    }
+    else if (SetSpectrumSinkInput::match(*message))
+    {
+        const SetSpectrumSinkInput *msg = (SetSpectrumSinkInput *) message;
+        bool spectrumInputSourceElseSink = msg->getSourceElseSink();
+        unsigned int spectrumInputIndex = msg->getIndex();
+
+        if ((spectrumInputSourceElseSink != m_spectrumInputSourceElseSink) || (spectrumInputIndex != m_spectrumInputIndex))
+        {
+            if (!m_spectrumInputSourceElseSink) // remove the source listener
+            {
+                SampleSourceFifo *inputFIFO = m_deviceSampleMIMO->getSampleSourceFifo(m_spectrumInputIndex);
+                disconnect(inputFIFO, SIGNAL(dataRead(int)), this, SLOT(handleForwardToSpectrumSink(int)));
+            }
+
+            if ((!spectrumInputSourceElseSink) && (spectrumInputIndex <  m_deviceSampleMIMO->getNbSinkStreams())) // add the source listener
+            {
+                SampleSourceFifo *inputFIFO = m_deviceSampleMIMO->getSampleSourceFifo(spectrumInputIndex);
+                connect(inputFIFO, SIGNAL(dataRead(int)), this, SLOT(handleForwardToSpectrumSink(int)));
+
+                if (m_spectrumSink)
+                {
+                    DSPSignalNotification notif(
+                        m_deviceSampleMIMO->getSinkSampleRate(spectrumInputIndex),
+                        m_deviceSampleMIMO->getSinkCenterFrequency(spectrumInputIndex));
+                    m_spectrumSink->handleMessage(notif);
+                }
+            }
+
+            if (m_spectrumSink && (spectrumInputSourceElseSink) && (spectrumInputIndex <  m_deviceSampleMIMO->getNbSinkFifos()))
+            {
+                DSPSignalNotification notif(
+                    m_deviceSampleMIMO->getSourceSampleRate(spectrumInputIndex),
+                    m_deviceSampleMIMO->getSourceCenterFrequency(spectrumInputIndex));
+                m_spectrumSink->handleMessage(notif);
+            }
+
+            m_spectrumInputSourceElseSink = spectrumInputSourceElseSink;
+            m_spectrumInputIndex = spectrumInputIndex;
+        }
+    }
 
 	m_syncMessenger.done(m_state);
 }
@@ -692,24 +770,22 @@ void DSPDeviceMIMOEngine::handleInputMessages()
 
 			// update DSP values
 
-            bool sourceOrSink = notif->getSourceOrSink();
+            bool sourceElseSink = notif->getSourceOrSink();
             unsigned int istream = notif->getIndex();
 			int sampleRate = notif->getSampleRate();
 			qint64 centerFrequency = notif->getCenterFrequency();
 
 			qDebug() << "DeviceMIMOEngine::handleInputMessages: SignalNotification:"
-                << " sourceOrSink: " << sourceOrSink
+                << " sourceElseSink: " << sourceElseSink
                 << " istream: " << istream
 				<< " sampleRate: " << sampleRate
 				<< " centerFrequency: " << centerFrequency;
 
 
-            if (sourceOrSink)
+            if (sourceElseSink)
             {
-                if ((istream < m_sourceStreamSampleRates.size()) && (istream < m_sourceCenterFrequencies.size()))
+                if ((istream < m_deviceSampleMIMO->getNbSourceStreams()))
                 {
-                    m_sourceStreamSampleRates[istream] = sampleRate;
-                    m_sourceCenterFrequencies[istream] = centerFrequency;
                     DSPSignalNotification *message = new DSPSignalNotification(sampleRate, centerFrequency);
 
                     // forward source changes to ancillary sinks with immediate execution (no queuing)
@@ -732,24 +808,26 @@ void DSPDeviceMIMOEngine::handleInputMessages()
                         }
                     }
 
-                    // forward changes to source GUI input queue
-                    // MessageQueue *guiMessageQueue = m_deviceSampleSource->getMessageQueueToGUI();
-                    // qDebug("DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue);
+                    // forward changes to MIMO GUI input queue
+                    MessageQueue *guiMessageQueue = m_deviceSampleMIMO->getMessageQueueToGUI();
+                    qDebug("DeviceMIMOEngine::handleInputMessages: SignalNotification: guiMessageQueue: %p", guiMessageQueue);
 
-                    // if (guiMessageQueue) {
-                    //     DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy for the source GUI
-                    //     guiMessageQueue->push(rep);
-                    // }
+                    if (guiMessageQueue) {
+                        SignalNotification* rep = new SignalNotification(*notif); // make a copy for the MIMO GUI
+                        guiMessageQueue->push(rep);
+                    }
 
-                    delete message;
+                    if (m_spectrumSink && m_spectrumInputSourceElseSink && (m_spectrumInputIndex == istream))
+                    {
+                        DSPSignalNotification spectrumNotif(sampleRate, centerFrequency);
+                        m_spectrumSink->handleMessage(spectrumNotif);
+                    }
                 }
             }
             else
             {
-                if ((istream < m_sinkStreamSampleRates.size()) && (istream < m_sinkCenterFrequencies.size()))
+                if ((istream < m_deviceSampleMIMO->getNbSinkStreams()))
                 {
-                    m_sinkStreamSampleRates[istream] = sampleRate;
-                    m_sinkCenterFrequencies[istream] = centerFrequency;
                     DSPSignalNotification *message = new DSPSignalNotification(sampleRate, centerFrequency);
 
                     // forward source changes to channel sources with immediate execution (no queuing)
@@ -762,18 +840,24 @@ void DSPDeviceMIMOEngine::handleInputMessages()
                         }
                     }
 
-                    // forward changes to source GUI input queue
-                    // MessageQueue *guiMessageQueue = m_deviceSampleSource->getMessageQueueToGUI();
-                    // qDebug("DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue);
+                    // forward changes to MIMO GUI input queue
+                    MessageQueue *guiMessageQueue = m_deviceSampleMIMO->getMessageQueueToGUI();
+                    qDebug("DSPDeviceMIMOEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue);
 
-                    // if (guiMessageQueue) {
-                    //     DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy for the source GUI
-                    //     guiMessageQueue->push(rep);
-                    // }
+                    if (guiMessageQueue) {
+                        SignalNotification* rep = new SignalNotification(*notif); // make a copy for the source GUI
+                        guiMessageQueue->push(rep);
+                    }
+
+                    if (m_spectrumSink && !m_spectrumInputSourceElseSink && (m_spectrumInputIndex == istream))
+                    {
+                        DSPSignalNotification spectrumNotif(sampleRate, centerFrequency);
+                        m_spectrumSink->handleMessage(spectrumNotif);
+                    }
                 }
-
-			    delete message;
             }
+
+            delete message;
 		}
 	}
 }
@@ -784,3 +868,15 @@ void DSPDeviceMIMOEngine::configureCorrections(bool dcOffsetCorrection, bool iqI
 	ConfigureCorrection* cmd = new ConfigureCorrection(dcOffsetCorrection, iqImbalanceCorrection, isource);
 	m_inputMessageQueue.push(cmd);
 }
+
+// This is used for the Tx (sink streams) side
+void DSPDeviceMIMOEngine::handleForwardToSpectrumSink(int nbSamples)
+{
+	if ((m_spectrumSink) && (m_spectrumInputIndex < m_deviceSampleMIMO->getNbSinkStreams()))
+	{
+		SampleSourceFifo* sampleFifo = m_deviceSampleMIMO->getSampleSourceFifo(m_spectrumInputIndex);
+		SampleVector::iterator readUntil;
+		sampleFifo->getReadIterator(readUntil);
+		m_spectrumSink->feed(readUntil - nbSamples, readUntil, false);
+	}
+}
diff --git a/sdrbase/dsp/dspdevicemimoengine.h b/sdrbase/dsp/dspdevicemimoengine.h
index f7003c480..8b7a829cc 100644
--- a/sdrbase/dsp/dspdevicemimoengine.h
+++ b/sdrbase/dsp/dspdevicemimoengine.h
@@ -211,6 +211,20 @@ public:
         unsigned int m_index;
     };
 
+    class SetSpectrumSinkInput : public Message {
+        MESSAGE_CLASS_DECLARATION
+    public:
+        SetSpectrumSinkInput(bool sourceElseSink, int index) :
+            m_sourceElseSink(sourceElseSink),
+            m_index(index)
+        { }
+        bool getSourceElseSink() const { return m_sourceElseSink; }
+        int getIndex() const { return m_index; }
+    private:
+        bool m_sourceElseSink;
+        int m_index;
+    };
+
 	enum State {
 		StNotStarted,  //!< engine is before initialization
 		StIdle,        //!< engine is idle
@@ -246,6 +260,7 @@ public:
 
 	void addSpectrumSink(BasebandSampleSink* spectrumSink);    //!< Add a spectrum vis baseband sample sink
 	void removeSpectrumSink(BasebandSampleSink* spectrumSink); //!< Add a spectrum vis baseband sample sink
+    void setSpectrumSinkInput(bool sourceElseSink, int index);
 
 	State state() const { return m_state; } //!< Return DSP engine current state
 
@@ -306,13 +321,11 @@ private:
 	typedef std::list<ThreadedBasebandSampleSource*> ThreadedBasebandSampleSources;
 	std::vector<ThreadedBasebandSampleSources> m_threadedBasebandSampleSources; //!< channel sample sources on their own threads (per output stream)
 
-    std::vector<quint64> m_sourceCenterFrequencies;  //!< device sources streams (Rx) sample rates
-    std::vector<quint64> m_sinkCenterFrequencies;    //!< device sink streams (Tx) sample rates
-    std::vector<uint32_t> m_sourceStreamSampleRates; //!< device sources streams (Rx) sample rates
-    std::vector<uint32_t> m_sinkStreamSampleRates;   //!< device sink streams (Tx) sample rates
     std::vector<SourceCorrection> m_sourcesCorrections;
 
     BasebandSampleSink *m_spectrumSink; //!< The spectrum sink
+    bool m_spectrumInputSourceElseSink; //!< Source else sink stream to be used as spectrum sink input
+    unsigned int m_spectrumInputIndex;  //!< Index of the stream to be used as spectrum sink input
 
   	void run();
 	void work(int nbWriteSamples); //!< transfer samples if in running state
@@ -328,7 +341,7 @@ private slots:
 	void handleData();                 //!< Handle data when samples have to be processed
 	void handleSynchronousMessages();  //!< Handle synchronous messages with the thread
 	void handleInputMessages();        //!< Handle input message queue
-	//TODO: void handleForwardToSpectrumSink(int nbSamples);
+	void handleForwardToSpectrumSink(int nbSamples);
 };
 
 #endif // SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_
\ No newline at end of file