diff --git a/sdrbase/device/deviceapi.cpp b/sdrbase/device/deviceapi.cpp index 8f7fb49f3..35e8e8f72 100644 --- a/sdrbase/device/deviceapi.cpp +++ b/sdrbase/device/deviceapi.cpp @@ -109,23 +109,19 @@ void DeviceAPI::removeChannelSink(ThreadedBasebandSampleSink* sink, int streamIn void DeviceAPI::addChannelSource(BasebandSampleSource* source, int streamIndex) { - (void) streamIndex; - if (m_deviceSinkEngine) { m_deviceSinkEngine->addChannelSource(source); } else if (m_deviceMIMOEngine) { - m_deviceMIMOEngine->addChannelSource(source); + m_deviceMIMOEngine->addChannelSource(source, streamIndex); } } void DeviceAPI::removeChannelSource(BasebandSampleSource* source, int streamIndex) { - (void) streamIndex; - if (m_deviceSinkEngine) { m_deviceSinkEngine->removeChannelSource(source); } else if (m_deviceMIMOEngine) { - m_deviceMIMOEngine->removeChannelSource(source); + m_deviceMIMOEngine->removeChannelSource(source, streamIndex); } } diff --git a/sdrbase/dsp/basebandsamplesink.h b/sdrbase/dsp/basebandsamplesink.h index 49252ef8a..4af29a591 100644 --- a/sdrbase/dsp/basebandsamplesink.h +++ b/sdrbase/dsp/basebandsamplesink.h @@ -60,7 +60,7 @@ public: virtual bool handleMessage(const Message& cmd) = 0; //!< Processing of a message. Returns true if message has actually been processed MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication - virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; } + void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; } MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; } protected: diff --git a/sdrbase/dsp/dspdevicemimoengine.cpp b/sdrbase/dsp/dspdevicemimoengine.cpp index d849f44f5..9ee2b16ab 100644 --- a/sdrbase/dsp/dspdevicemimoengine.cpp +++ b/sdrbase/dsp/dspdevicemimoengine.cpp @@ -439,66 +439,67 @@ void DSPDeviceMIMOEngine::workSamplesSource(SampleVector& data, unsigned int iBe unsigned int nbSamples = iEnd - iBegin; SampleVector::iterator begin = data.begin() + iBegin; - m_sourceZeroBuffers[streamIndex].allocate(nbSamples, Sample{16384,0}); - std::copy( - m_sourceZeroBuffers[streamIndex].m_vector.begin(), - m_sourceZeroBuffers[streamIndex].m_vector.begin() + nbSamples, - begin - ); - - m_spectrumSink->feed(begin, begin + nbSamples, false); - qDebug("DSPDeviceMIMOEngine::workSamplesSource: nbSamples: %u streamIndex: %u", nbSamples, streamIndex); - - return; - - if (m_basebandSampleSources[streamIndex].size() == 0) - { - m_sourceZeroBuffers[streamIndex].allocate(nbSamples, Sample{0,0}); - std::copy( - m_sourceZeroBuffers[streamIndex].m_vector.begin(), - m_sourceZeroBuffers[streamIndex].m_vector.begin() + nbSamples, - begin - ); - } - else if (m_basebandSampleSources[streamIndex].size() == 1) - { - BasebandSampleSource *sampleSource = m_basebandSampleSources[streamIndex].front(); - sampleSource->pull(begin, nbSamples); - } - else - { - m_sourceSampleBuffers[streamIndex].allocate(nbSamples); - BasebandSampleSources::const_iterator srcIt = m_basebandSampleSources[streamIndex].begin(); - BasebandSampleSource *sampleSource = *srcIt; - sampleSource->pull(begin, nbSamples); - ++srcIt; - - for (; srcIt != m_basebandSampleSources[streamIndex].end(); ++srcIt) - { - sampleSource = *srcIt; - SampleVector::iterator aBegin = m_sourceSampleBuffers[streamIndex].m_vector.begin(); - sampleSource->pull(aBegin, nbSamples); - std::transform( - aBegin, - aBegin + nbSamples, - begin, - begin, - [](Sample& a, const Sample& b) -> Sample { // TODO: scale by number of sources - return Sample{a.real()+b.real(), a.imag()+b.imag()}; - } - ); - } - - begin = m_sourceSampleBuffers[streamIndex].m_vector.begin(); - } - // pull data from MIMO channels + for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) { - //qDebug("DSPDeviceMIMOEngine::workSamplesSource: nbSamples: %u stream: %u", nbSamples, streamIndex); + qDebug("DSPDeviceMIMOEngine::workSamplesSource: %s: nbSamples: %u stream: %u", + qPrintable((*it)->objectName()), nbSamples, streamIndex); (*it)->pull(begin, nbSamples, streamIndex); } + if (m_mimoChannels.size() == 0) // Process single stream channels only if there are no MIMO channels + { + if (m_basebandSampleSources[streamIndex].size() == 0) + { + m_sourceZeroBuffers[streamIndex].allocate(nbSamples, Sample{0,0}); + std::copy( + m_sourceZeroBuffers[streamIndex].m_vector.begin(), + m_sourceZeroBuffers[streamIndex].m_vector.begin() + nbSamples, + begin + ); + } + else if (m_basebandSampleSources[streamIndex].size() == 1) + { + BasebandSampleSource *sampleSource = m_basebandSampleSources[streamIndex].front(); + qDebug("DSPDeviceMIMOEngine::workSamplesSource: %s: nbSamples: %u stream: %u", + qPrintable(sampleSource->objectName()), nbSamples, streamIndex); + sampleSource->pull(begin, nbSamples); + } + else + { + m_sourceSampleBuffers[streamIndex].allocate(nbSamples); + BasebandSampleSources::const_iterator srcIt = m_basebandSampleSources[streamIndex].begin(); + BasebandSampleSource *sampleSource = *srcIt; + sampleSource->pull(begin, nbSamples); + ++srcIt; + m_sumIndex = 1; + + for (; srcIt != m_basebandSampleSources[streamIndex].end(); ++srcIt, m_sumIndex++) + { + sampleSource = *srcIt; + SampleVector::iterator aBegin = m_sourceSampleBuffers[streamIndex].m_vector.begin(); + sampleSource->pull(aBegin, nbSamples); + std::transform( + aBegin, + aBegin + nbSamples, + begin, + begin, + [this](Sample& a, const Sample& b) -> Sample { + int den = m_sumIndex + 1; // at each stage scale sum by n/n+1 and input by 1/n+1 + int nom = m_sumIndex; // so that final sum is scaled by N (number of channels) + return Sample{ + a.real()/den + nom*(b.real()/den), + a.imag()/den + nom*(b.imag()/den) + }; + } + ); + } + + begin = m_sourceSampleBuffers[streamIndex].m_vector.begin(); + } + } + // possibly feed data to spectrum sink if ((m_spectrumSink) && (!m_spectrumInputSourceElseSink) && (streamIndex == m_spectrumInputIndex)) { m_spectrumSink->feed(begin, begin + nbSamples, false); @@ -903,7 +904,7 @@ void DSPDeviceMIMOEngine::handleSetMIMO(DeviceSampleMIMO* mimo) ); QObject::connect( m_deviceSampleMIMO->getSampleMOFifo(), - &SampleMOFifo::dataSyncRead, + &SampleMOFifo::dataReadSync, this, &DSPDeviceMIMOEngine::handleDataTxSync, Qt::QueuedConnection @@ -924,7 +925,7 @@ void DSPDeviceMIMOEngine::handleSetMIMO(DeviceSampleMIMO* mimo) ); QObject::connect( m_deviceSampleMIMO->getSampleMOFifo(), - &SampleMOFifo::dataAsyncRead, + &SampleMOFifo::dataReadAsync, this, &DSPDeviceMIMOEngine::handleDataTxAsync, Qt::QueuedConnection diff --git a/sdrbase/dsp/dspdevicemimoengine.h b/sdrbase/dsp/dspdevicemimoengine.h index a8ede42df..71275088d 100644 --- a/sdrbase/dsp/dspdevicemimoengine.h +++ b/sdrbase/dsp/dspdevicemimoengine.h @@ -364,6 +364,7 @@ private: std::vector m_basebandSampleSources; //!< channel sample sources (per output stream) std::vector> m_sourceSampleBuffers; std::vector> m_sourceZeroBuffers; + unsigned int m_sumIndex; //!< channel index when summing channels typedef std::list MIMOChannels; MIMOChannels m_mimoChannels; //!< MIMO channels @@ -374,7 +375,7 @@ private: 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 workSampleSinkFifos(); //!< transfer samples of all sink streams (sync mode) void workSampleSinkFifo(unsigned int streamIndex); //!< transfer samples of one sink stream (async mode) void workSamplesSink(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int streamIndex); diff --git a/sdrbase/dsp/dspdevicesinkengine.cpp b/sdrbase/dsp/dspdevicesinkengine.cpp index ae87f184d..9430646cb 100644 --- a/sdrbase/dsp/dspdevicesinkengine.cpp +++ b/sdrbase/dsp/dspdevicesinkengine.cpp @@ -37,8 +37,7 @@ DSPDeviceSinkEngine::DSPDeviceSinkEngine(uint32_t uid, QObject* parent) : m_basebandSampleSources(), m_spectrumSink(nullptr), m_sampleRate(0), - m_centerFrequency(0), - m_multipleSourcesDivisionFactor(1) + m_centerFrequency(0) { connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection); diff --git a/sdrbase/dsp/dspdevicesinkengine.h b/sdrbase/dsp/dspdevicesinkengine.h index d7044eb47..05ec4d32b 100644 --- a/sdrbase/dsp/dspdevicesinkengine.h +++ b/sdrbase/dsp/dspdevicesinkengine.h @@ -103,7 +103,6 @@ private: uint32_t m_sampleRate; quint64 m_centerFrequency; - uint32_t m_multipleSourcesDivisionFactor; unsigned int m_sumIndex; //!< channel index when summing channels void run();