From 7186182d71b2a0a93cd81c3d70a34c6bb404991a Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 19 May 2019 10:23:18 +0200 Subject: [PATCH] MIMO: use proper functions to get the number of source and stream sinks from the MIMO device --- Readme.md | 4 + plugins/samplemimo/testmi/testmi.cpp | 5 +- plugins/samplemimo/testmi/testmigui.cpp | 8 +- sdrbase/device/deviceapi.cpp | 7 + sdrbase/device/deviceapi.h | 1 + sdrbase/dsp/devicesamplemimo.h | 5 + sdrbase/dsp/dspdevicemimoengine.cpp | 248 ++++++++++++++++-------- sdrbase/dsp/dspdevicemimoengine.h | 23 ++- 8 files changed, 216 insertions(+), 85 deletions(-) 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. +

Note on udev rules

+ +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. +

Software build on Linux

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<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::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 ThreadedBasebandSampleSources; std::vector m_threadedBasebandSampleSources; //!< channel sample sources on their own threads (per output stream) - std::vector m_sourceCenterFrequencies; //!< device sources streams (Rx) sample rates - std::vector m_sinkCenterFrequencies; //!< device sink streams (Tx) sample rates - std::vector m_sourceStreamSampleRates; //!< device sources streams (Rx) sample rates - std::vector m_sinkStreamSampleRates; //!< device sink streams (Tx) sample rates std::vector 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