mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-27 11:00:31 -04:00 
			
		
		
		
	MIMO: use proper functions to get the number of source and stream sinks from the MIMO device
This commit is contained in:
		
							parent
							
								
									490d384ecf
								
							
						
					
					
						commit
						7186182d71
					
				| @ -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. | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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(); | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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)
 | ||||||
|  | |||||||
| @ -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(); | ||||||
|  | |||||||
| @ -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,43 +396,42 @@ 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); | ||||||
|  | 
 | ||||||
|  |         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); |             for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks[isource].begin(); it != m_basebandSampleSinks[isource].end(); ++it) | ||||||
|             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) |                 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; | 	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) { | ||||||
| @ -638,6 +659,63 @@ void DSPDeviceMIMOEngine::handleSynchronousMessages() | |||||||
|             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,18 +840,24 @@ 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; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -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); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -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_
 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user