MIMO: use proper functions to get the number of source and stream sinks from the MIMO device

This commit is contained in:
f4exb 2019-05-19 10:23:18 +02:00
parent 490d384ecf
commit 7186182d71
8 changed files with 216 additions and 85 deletions

View File

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

View File

@ -29,6 +29,7 @@
#include "device/deviceapi.h" #include "device/deviceapi.h"
#include "dsp/dspcommands.h" #include "dsp/dspcommands.h"
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "dsp/dspdevicemimoengine.h"
#include "dsp/devicesamplesource.h" #include "dsp/devicesamplesource.h"
#include "dsp/filerecord.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); int sampleRate = settings.m_sampleRate/(1<<settings.m_log2Decim);
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_centerFrequency); DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_centerFrequency);
m_fileSink->handleMessage(*notif); // forward to file sink 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) if ((m_settings.m_modulationTone != settings.m_modulationTone) || force)

View File

@ -30,6 +30,7 @@
#include "gui/crightclickenabler.h" #include "gui/crightclickenabler.h"
#include "gui/basicdevicesettingsdialog.h" #include "gui/basicdevicesettingsdialog.h"
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "dsp/dspdevicemimoengine.h"
#include "dsp/dspcommands.h" #include "dsp/dspcommands.h"
#include "util/db.h" #include "util/db.h"
@ -489,12 +490,13 @@ void TestMIGui::handleInputMessages()
while ((message = m_inputMessageQueue.pop()) != 0) 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_deviceSampleRate = notif->getSampleRate();
m_deviceCenterFrequency = notif->getCenterFrequency(); 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->getSampleRate(),
notif->getCenterFrequency()); notif->getCenterFrequency());
updateSampleRateAndFrequency(); updateSampleRateAndFrequency();

View File

@ -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 DeviceAPI::addChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex)
{ {
(void) streamIndex; (void) streamIndex;

View File

@ -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 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 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 addChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex = 0); //!< Add a channel sink (Rx)
void removeChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex = 0); //!< Remove a channel sink (Rx) void removeChannelSink(ThreadedBasebandSampleSink* sink, int streamIndex = 0); //!< Remove a channel sink (Rx)

View File

@ -126,6 +126,11 @@ public:
unsigned int getNbSinkFifos() const { return m_sampleSinkFifos.size(); } //!< Get the number of Rx FIFOs unsigned int getNbSinkFifos() const { return m_sampleSinkFifos.size(); } //!< Get the number of Rx FIFOs
SampleSourceFifo* getSampleSourceFifo(unsigned int index); //!< Get Tx FIFO at index SampleSourceFifo* getSampleSourceFifo(unsigned int index); //!< Get Tx FIFO at index
SampleSinkFifo* getSampleSinkFifo(unsigned int index); //!< Get Rx 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: protected slots:
void handleInputMessages(); void handleInputMessages();

View File

@ -38,12 +38,15 @@ MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::GetErrorMessage, Message)
MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::GetMIMODeviceDescription, Message) MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::GetMIMODeviceDescription, Message)
MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::ConfigureCorrection, Message) MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::ConfigureCorrection, Message)
MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SignalNotification, Message) MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SignalNotification, Message)
MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SetSpectrumSinkInput, Message)
DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) : DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) :
QThread(parent), QThread(parent),
m_uid(uid), m_uid(uid),
m_state(StNotStarted), 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_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), 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); 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() QString DSPDeviceMIMOEngine::errorMessage()
{ {
qDebug() << "DSPDeviceMIMOEngine::errorMessage"; qDebug() << "DSPDeviceMIMOEngine::errorMessage";
@ -213,17 +225,13 @@ void DSPDeviceMIMOEngine::work(int nbWriteSamples)
{ {
(void) nbWriteSamples; (void) nbWriteSamples;
// Sources // 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 SampleSinkFifo* sampleFifo = m_deviceSampleMIMO->getSampleSinkFifo(isource); // sink FIFO is for Rx
std::size_t samplesDone = 0; int samplesDone = 0;
bool positiveOnly = false; 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 part1begin;
SampleVector::iterator part1end; 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 // feed data to threaded sinks
if (isource < m_threadedBasebandSampleSinks.size()) 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 // feed data to threaded sinks
if (isource < m_threadedBasebandSampleSinks.size()) if (isource < m_threadedBasebandSampleSinks.size())
{ {
@ -334,10 +352,6 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoIdle()
m_deviceSampleMIMO->stop(); m_deviceSampleMIMO->stop();
m_deviceDescription.clear(); m_deviceDescription.clear();
for (std::vector<uint32_t>::iterator it = m_sourceStreamSampleRates.begin(); it != m_sourceStreamSampleRates.end(); ++it) {
*it = 0;
}
return StIdle; return StIdle;
} }
@ -370,7 +384,9 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoInit()
qDebug() << "DSPDeviceMIMOEngine::gotoInit: " qDebug() << "DSPDeviceMIMOEngine::gotoInit: "
<< " m_deviceDescription: " << m_deviceDescription.toStdString().c_str(); << " 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()) if (isource < m_sourcesCorrections.size())
{ {
@ -380,15 +396,13 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoInit()
m_sourcesCorrections[isource].m_qRange = 1 << 16; 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);
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_sourceCenterFrequencies[%d] = %llu", isource, sourceCenterFrequency);
qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceStreamSampleRates[%d] = %d", isource, m_sourceStreamSampleRates[isource]); qDebug("DSPDeviceMIMOEngine::gotoInit: m_sourceStreamSampleRates[%d] = %d", isource, sourceStreamSampleRate);
DSPSignalNotification notif(m_sourceStreamSampleRates[isource], m_sourceCenterFrequencies[isource]); DSPSignalNotification notif(sourceStreamSampleRate, sourceCenterFrequency);
if (isource < m_basebandSampleSinks.size()) if (isource < m_basebandSampleSinks.size())
{ {
@ -415,7 +429,8 @@ DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoInit()
// m_deviceSampleSource->getMessageQueueToGUI()->push(rep); // m_deviceSampleSource->getMessageQueueToGUI()->push(rep);
// } // }
} }
}
//TODO: Tx
return StReady; return StReady;
} }
@ -551,11 +566,13 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
BasebandSampleSink* sink = msg->getSampleSink(); BasebandSampleSink* sink = msg->getSampleSink();
unsigned int isource = msg->getIndex(); 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); m_basebandSampleSinks[isource].push_back(sink);
// initialize sample rate and center frequency in the 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); sink->handleMessage(msg);
// start the sink: // start the sink:
if(m_state == StRunning) { if(m_state == StRunning) {
@ -584,11 +601,13 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
ThreadedBasebandSampleSink *threadedSink = msg->getThreadedSampleSink(); ThreadedBasebandSampleSink *threadedSink = msg->getThreadedSampleSink();
unsigned int isource = msg->getIndex(); 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); m_threadedBasebandSampleSinks[isource].push_back(threadedSink);
// initialize sample rate and center frequency in the 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);
threadedSink->handleSinkMessage(msg); threadedSink->handleSinkMessage(msg);
// start the sink: // start the sink:
if(m_state == StRunning) { if(m_state == StRunning) {
@ -614,11 +633,13 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
ThreadedBasebandSampleSource *threadedSource = msg->getThreadedSampleSource(); ThreadedBasebandSampleSource *threadedSource = msg->getThreadedSampleSource();
unsigned int isink = msg->getIndex(); 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); m_threadedBasebandSampleSources[isink].push_back(threadedSource);
// initialize sample rate and center frequency in the sink: // 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); threadedSource->handleSourceMessage(msg);
// start the sink: // start the sink:
if(m_state == StRunning) { if(m_state == StRunning) {
@ -637,6 +658,63 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages()
threadedSource->stop(); threadedSource->stop();
m_threadedBasebandSampleSources[isink].remove(threadedSource); 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); m_syncMessenger.done(m_state);
@ -692,24 +770,22 @@ void DSPDeviceMIMOEngine::handleInputMessages()
// update DSP values // update DSP values
bool sourceOrSink = notif->getSourceOrSink(); bool sourceElseSink = notif->getSourceOrSink();
unsigned int istream = notif->getIndex(); unsigned int istream = notif->getIndex();
int sampleRate = notif->getSampleRate(); int sampleRate = notif->getSampleRate();
qint64 centerFrequency = notif->getCenterFrequency(); qint64 centerFrequency = notif->getCenterFrequency();
qDebug() << "DeviceMIMOEngine::handleInputMessages: SignalNotification:" qDebug() << "DeviceMIMOEngine::handleInputMessages: SignalNotification:"
<< " sourceOrSink: " << sourceOrSink << " sourceElseSink: " << sourceElseSink
<< " istream: " << istream << " istream: " << istream
<< " sampleRate: " << sampleRate << " sampleRate: " << sampleRate
<< " centerFrequency: " << centerFrequency; << " 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); DSPSignalNotification *message = new DSPSignalNotification(sampleRate, centerFrequency);
// forward source changes to ancillary sinks with immediate execution (no queuing) // 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 // forward changes to MIMO GUI input queue
// MessageQueue *guiMessageQueue = m_deviceSampleSource->getMessageQueueToGUI(); MessageQueue *guiMessageQueue = m_deviceSampleMIMO->getMessageQueueToGUI();
// qDebug("DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue); qDebug("DeviceMIMOEngine::handleInputMessages: SignalNotification: guiMessageQueue: %p", guiMessageQueue);
// if (guiMessageQueue) { if (guiMessageQueue) {
// DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy for the source GUI SignalNotification* rep = new SignalNotification(*notif); // make a copy for the MIMO GUI
// guiMessageQueue->push(rep); guiMessageQueue->push(rep);
// } }
delete message; if (m_spectrumSink && m_spectrumInputSourceElseSink && (m_spectrumInputIndex == istream))
{
DSPSignalNotification spectrumNotif(sampleRate, centerFrequency);
m_spectrumSink->handleMessage(spectrumNotif);
}
} }
} }
else 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); DSPSignalNotification *message = new DSPSignalNotification(sampleRate, centerFrequency);
// forward source changes to channel sources with immediate execution (no queuing) // forward source changes to channel sources with immediate execution (no queuing)
@ -762,20 +840,26 @@ void DSPDeviceMIMOEngine::handleInputMessages()
} }
} }
// forward changes to source GUI input queue // forward changes to MIMO GUI input queue
// MessageQueue *guiMessageQueue = m_deviceSampleSource->getMessageQueueToGUI(); MessageQueue *guiMessageQueue = m_deviceSampleMIMO->getMessageQueueToGUI();
// qDebug("DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue); qDebug("DSPDeviceMIMOEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue);
// if (guiMessageQueue) { if (guiMessageQueue) {
// DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy for the source GUI SignalNotification* rep = new SignalNotification(*notif); // make a copy for the source GUI
// guiMessageQueue->push(rep); guiMessageQueue->push(rep);
// } }
if (m_spectrumSink && !m_spectrumInputSourceElseSink && (m_spectrumInputIndex == istream))
{
DSPSignalNotification spectrumNotif(sampleRate, centerFrequency);
m_spectrumSink->handleMessage(spectrumNotif);
}
}
} }
delete message; delete message;
} }
} }
}
} }
void DSPDeviceMIMOEngine::configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int isource) void DSPDeviceMIMOEngine::configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int isource)
@ -784,3 +868,15 @@ void DSPDeviceMIMOEngine::configureCorrections(bool dcOffsetCorrection, bool iqI
ConfigureCorrection* cmd = new ConfigureCorrection(dcOffsetCorrection, iqImbalanceCorrection, isource); ConfigureCorrection* cmd = new ConfigureCorrection(dcOffsetCorrection, iqImbalanceCorrection, isource);
m_inputMessageQueue.push(cmd); 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);
}
}

View File

@ -211,6 +211,20 @@ public:
unsigned int m_index; 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 { enum State {
StNotStarted, //!< engine is before initialization StNotStarted, //!< engine is before initialization
StIdle, //!< engine is idle StIdle, //!< engine is idle
@ -246,6 +260,7 @@ public:
void addSpectrumSink(BasebandSampleSink* spectrumSink); //!< Add a spectrum vis baseband sample sink void addSpectrumSink(BasebandSampleSink* spectrumSink); //!< Add a spectrum vis baseband sample sink
void removeSpectrumSink(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 State state() const { return m_state; } //!< Return DSP engine current state
@ -306,13 +321,11 @@ private:
typedef std::list<ThreadedBasebandSampleSource*> ThreadedBasebandSampleSources; typedef std::list<ThreadedBasebandSampleSource*> ThreadedBasebandSampleSources;
std::vector<ThreadedBasebandSampleSources> m_threadedBasebandSampleSources; //!< channel sample sources on their own threads (per output stream) 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; std::vector<SourceCorrection> m_sourcesCorrections;
BasebandSampleSink *m_spectrumSink; //!< The spectrum sink 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 run();
void work(int nbWriteSamples); //!< transfer samples if in running state 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 handleData(); //!< Handle data when samples have to be processed
void handleSynchronousMessages(); //!< Handle synchronous messages with the thread void handleSynchronousMessages(); //!< Handle synchronous messages with the thread
void handleInputMessages(); //!< Handle input message queue void handleInputMessages(); //!< Handle input message queue
//TODO: void handleForwardToSpectrumSink(int nbSamples); void handleForwardToSpectrumSink(int nbSamples);
}; };
#endif // SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_ #endif // SDRBASE_DSP_DSPDEVICEMIMOENGINE_H_