| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2019 F4EXB                                                      //
 | 
					
						
							|  |  |  | // written by Edouard Griffiths                                                  //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							|  |  |  | // (at your option) any later version.                                           //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful,               //
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | 
					
						
							|  |  |  | // GNU General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  | #include "dspcommands.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-13 00:34:27 +01:00
										 |  |  | #include "basebandsamplesink.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | #include "basebandsamplesource.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | #include "devicesamplemimo.h"
 | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  | #include "mimochannel.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "dspdevicemimoengine.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SetSampleMIMO, Message) | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::AddBasebandSampleSource, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::RemoveBasebandSampleSource, Message) | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::AddMIMOChannel, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::RemoveMIMOChannel, Message) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::AddBasebandSampleSink, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::RemoveBasebandSampleSink, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::AddSpectrumSink, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::RemoveSpectrumSink, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::GetErrorMessage, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::GetMIMODeviceDescription, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::ConfigureCorrection, Message) | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(DSPDeviceMIMOEngine::SetSpectrumSinkInput, Message) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | DSPDeviceMIMOEngine::DSPDeviceMIMOEngine(uint32_t uid, QObject* parent) : | 
					
						
							|  |  |  | 	QThread(parent), | 
					
						
							|  |  |  |     m_uid(uid), | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     m_stateRx(StNotStarted), | 
					
						
							|  |  |  |     m_stateTx(StNotStarted), | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |     m_deviceSampleMIMO(nullptr), | 
					
						
							|  |  |  |     m_spectrumInputSourceElseSink(true), | 
					
						
							|  |  |  |     m_spectrumInputIndex(0) | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); | 
					
						
							|  |  |  | 	connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	moveToThread(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DSPDeviceMIMOEngine::~DSPDeviceMIMOEngine() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     stop(); | 
					
						
							|  |  |  | 	wait(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | void DSPDeviceMIMOEngine::setStateRx(State state) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_stateRx != state) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_stateRx = state; | 
					
						
							|  |  |  |         emit stateChanged(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::setStateTx(State state) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_stateTx != state) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_stateTx = state; | 
					
						
							|  |  |  |         emit stateChanged(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | void DSPDeviceMIMOEngine::run() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::run"; | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 	setStateRx(StIdle); | 
					
						
							|  |  |  | 	setStateTx(StIdle); | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	exec(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::start() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::start"; | 
					
						
							|  |  |  | 	QThread::start(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::stop() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::stop"; | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     gotoIdle(0); // Rx
 | 
					
						
							|  |  |  |     gotoIdle(1); // Tx
 | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  |     setStateRx(StNotStarted); | 
					
						
							|  |  |  |     setStateTx(StNotStarted); | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  |     QThread::exit(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | bool DSPDeviceMIMOEngine::initProcess(int subsystemIndex) | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::initProcess: subsystemIndex: " << subsystemIndex; | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     if (subsystemIndex == 0) // Rx side
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPAcquisitionInit cmd; | 
					
						
							|  |  |  |         return m_syncMessenger.sendWait(cmd) == StReady; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (subsystemIndex == 1) // Tx side
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPGenerationInit cmd; | 
					
						
							|  |  |  |         return m_syncMessenger.sendWait(cmd) == StReady; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-24 22:18:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | bool DSPDeviceMIMOEngine::startProcess(int subsystemIndex) | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::startProcess: subsystemIndex: " << subsystemIndex; | 
					
						
							|  |  |  |     if (subsystemIndex == 0) // Rx side
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPAcquisitionStart cmd; | 
					
						
							|  |  |  |         return m_syncMessenger.sendWait(cmd) == StRunning; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (subsystemIndex == 1) // Tx side
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	    DSPGenerationStart cmd; | 
					
						
							|  |  |  | 	    return m_syncMessenger.sendWait(cmd) == StRunning; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-24 22:18:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | void DSPDeviceMIMOEngine::stopProcess(int subsystemIndex) | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::stopProcess: subsystemIndex: " << subsystemIndex; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (subsystemIndex == 0) // Rx side
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPAcquisitionStop cmd; | 
					
						
							| 
									
										
										
										
											2019-11-01 06:32:18 +01:00
										 |  |  |         m_syncMessenger.sendWait(cmd); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (subsystemIndex == 1) // Tx side
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         DSPGenerationStop cmd; | 
					
						
							| 
									
										
										
										
											2019-11-01 06:32:18 +01:00
										 |  |  |         m_syncMessenger.sendWait(cmd); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::setMIMO(DeviceSampleMIMO* mimo) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-18 11:59:56 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::setMIMO"; | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	SetSampleMIMO cmd(mimo); | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::setMIMOSequence(int sequence) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug("DSPDeviceMIMOEngine::setSinkSequence: seq: %d", sequence); | 
					
						
							|  |  |  | 	m_sampleMIMOSequence = sequence; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | void DSPDeviceMIMOEngine::addChannelSource(BasebandSampleSource* source, int index) | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::addChannelSource: " | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |         << source->getSourceName().toStdString().c_str() | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  |         << " at: " | 
					
						
							|  |  |  |         << index; | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 	AddBasebandSampleSource cmd(source, index); | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | void DSPDeviceMIMOEngine::removeChannelSource(BasebandSampleSource* source, int index) | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::removeChannelSource: " | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |         << source->getSourceName().toStdString().c_str() | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  |         << " at: " | 
					
						
							|  |  |  |         << index; | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 	RemoveBasebandSampleSource cmd(source, index); | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-23 07:39:57 +01:00
										 |  |  | void DSPDeviceMIMOEngine::addChannelSink(BasebandSampleSink* sink, int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::addChannelSink: " | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |         << sink->getSinkName().toStdString().c_str() | 
					
						
							| 
									
										
										
										
											2019-11-23 07:39:57 +01:00
										 |  |  |         << " at: " | 
					
						
							|  |  |  |         << index; | 
					
						
							|  |  |  | 	AddBasebandSampleSink cmd(sink, index); | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::removeChannelSink(BasebandSampleSink* sink, int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::removeChannelSink: " | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |         << sink->getSinkName().toStdString().c_str() | 
					
						
							| 
									
										
										
										
											2019-11-23 07:39:57 +01:00
										 |  |  |         << " at: " | 
					
						
							|  |  |  |         << index; | 
					
						
							|  |  |  | 	RemoveBasebandSampleSink cmd(sink, index); | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  | void DSPDeviceMIMOEngine::addMIMOChannel(MIMOChannel *channel) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::addMIMOChannel: " | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |         << channel->getMIMOName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |     AddMIMOChannel cmd(channel); | 
					
						
							|  |  |  |     m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::removeMIMOChannel(MIMOChannel *channel) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::removeMIMOChannel: " | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |         << channel->getMIMOName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |     RemoveMIMOChannel cmd(channel); | 
					
						
							|  |  |  |     m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | void DSPDeviceMIMOEngine::addSpectrumSink(BasebandSampleSink* spectrumSink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::addSpectrumSink: " << spectrumSink->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	AddSpectrumSink cmd(spectrumSink); | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::removeSpectrumSink(BasebandSampleSink* spectrumSink) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  | 	qDebug() << "DSPDeviceSinkEngine::removeSpectrumSink: " << spectrumSink->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	DSPRemoveSpectrumSink cmd(spectrumSink); | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  | void DSPDeviceMIMOEngine::setSpectrumSinkInput(bool sourceElseSink, int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceSinkEngine::setSpectrumSinkInput: " | 
					
						
							|  |  |  |         << " sourceElseSink: " << sourceElseSink | 
					
						
							|  |  |  |         << " index: " << index; | 
					
						
							|  |  |  |     SetSpectrumSinkInput cmd(sourceElseSink, index); | 
					
						
							|  |  |  |     m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | QString DSPDeviceMIMOEngine::errorMessage(int subsystemIndex) | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::errorMessage: subsystemIndex:" << subsystemIndex; | 
					
						
							|  |  |  | 	GetErrorMessage cmd(subsystemIndex); | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | 	return cmd.getErrorMessage(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString DSPDeviceMIMOEngine::deviceDescription() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::deviceDescription"; | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	GetMIMODeviceDescription cmd; | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | 	return cmd.getDeviceDescription(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  | void DSPDeviceMIMOEngine::workSampleSinkFifos() | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |     SampleMIFifo* sampleFifo = m_deviceSampleMIMO->getSampleMIFifo(); | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!sampleFifo) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-03 01:19:43 +02:00
										 |  |  |     unsigned int iPart1Begin; | 
					
						
							|  |  |  |     unsigned int iPart1End; | 
					
						
							|  |  |  |     unsigned int iPart2Begin; | 
					
						
							|  |  |  |     unsigned int iPart2End; | 
					
						
							|  |  |  |     const std::vector<SampleVector>& data = sampleFifo->getData(); | 
					
						
							|  |  |  |     //unsigned int samplesDone = 0;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while ((sampleFifo->fillSync() > 0) && (m_inputMessageQueue.size() == 0)) | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-03 01:19:43 +02:00
										 |  |  |         //unsigned int count = sampleFifo->readSync(sampleFifo->fillSync(), iPart1Begin, iPart1End, iPart2Begin, iPart2End);
 | 
					
						
							|  |  |  |         sampleFifo->readSync(iPart1Begin, iPart1End, iPart2Begin, iPart2End); | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-03 01:19:43 +02:00
										 |  |  |         if (iPart1Begin != iPart1End) | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-10-03 01:19:43 +02:00
										 |  |  |             for (unsigned int stream = 0; stream < data.size(); stream++) { | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |                 workSamplesSink(data[stream].begin() + iPart1Begin, data[stream].begin() + iPart1End, stream); | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-10-03 01:19:43 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-03 01:19:43 +02:00
										 |  |  |         if (iPart2Begin != iPart2End) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for (unsigned int stream = 0; stream < data.size(); stream++) { | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |                 workSamplesSink(data[stream].begin() + iPart2Begin, data[stream].begin() + iPart2End, stream); | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | void DSPDeviceMIMOEngine::workSampleSourceFifos() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SampleMOFifo* sampleFifo = m_deviceSampleMIMO->getSampleMOFifo(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!sampleFifo) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-24 18:29:45 +02:00
										 |  |  |     std::vector<SampleVector::iterator> vbegin; | 
					
						
							| 
									
										
										
										
											2019-11-17 03:54:37 +01:00
										 |  |  |     std::vector<SampleVector>& data = sampleFifo->getData(); | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |     unsigned int iPart1Begin, iPart1End, iPart2Begin, iPart2End; | 
					
						
							| 
									
										
										
										
											2019-10-31 03:49:15 +01:00
										 |  |  |     unsigned int remainder = sampleFifo->remainderSync(); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 03:49:15 +01:00
										 |  |  |     while ((remainder > 0) && (m_inputMessageQueue.size() == 0)) | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         sampleFifo->writeSync(remainder, iPart1Begin, iPart1End, iPart2Begin, iPart2End); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 03:49:15 +01:00
										 |  |  |         // pull samples from the sources by stream
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (iPart1Begin != iPart1End) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for (unsigned int streamIndex = 0; streamIndex < sampleFifo->getNbStreams(); streamIndex++) { | 
					
						
							|  |  |  |                 workSamplesSource(data[streamIndex], iPart1Begin, iPart1End, streamIndex); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (iPart2Begin != iPart2End) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for (unsigned int streamIndex = 0; streamIndex < sampleFifo->getNbStreams(); streamIndex++) { | 
					
						
							|  |  |  |                 workSamplesSource(data[streamIndex], iPart2Begin, iPart2End, streamIndex); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 03:49:15 +01:00
										 |  |  |         // get new remainder
 | 
					
						
							|  |  |  |         remainder = sampleFifo->remainderSync(); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::workSampleSinkFifo(unsigned int streamIndex) | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |     SampleMIFifo* sampleFifo = m_deviceSampleMIMO->getSampleMIFifo(); | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!sampleFifo) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |     SampleVector::const_iterator part1begin; | 
					
						
							|  |  |  |     SampleVector::const_iterator part1end; | 
					
						
							|  |  |  |     SampleVector::const_iterator part2begin; | 
					
						
							|  |  |  |     SampleVector::const_iterator part2end; | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |     while ((sampleFifo->fillAsync(streamIndex) > 0) && (m_inputMessageQueue.size() == 0)) | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-03 01:19:43 +02:00
										 |  |  |         //unsigned int count = sampleFifo->readAsync(sampleFifo->fillAsync(stream), &part1begin, &part1end, &part2begin, &part2end, stream);
 | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |         sampleFifo->readAsync(&part1begin, &part1end, &part2begin, &part2end, streamIndex); | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (part1begin != part1end) { // first part of FIFO data
 | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |             workSamplesSink(part1begin, part1end, streamIndex); | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (part2begin != part2end) { // second part of FIFO data (used when block wraps around)
 | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |             workSamplesSink(part2begin, part2end, streamIndex); | 
					
						
							| 
									
										
										
										
											2019-09-10 18:44:43 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::workSampleSourceFifo(unsigned int streamIndex) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SampleMOFifo* sampleFifo = m_deviceSampleMIMO->getSampleMOFifo(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!sampleFifo) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |     SampleVector& data = sampleFifo->getData(streamIndex); | 
					
						
							|  |  |  |     unsigned int iPart1Begin, iPart1End, iPart2Begin, iPart2End; | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     unsigned int amount = sampleFifo->remainderAsync(streamIndex); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     while ((amount > 0) && (m_inputMessageQueue.size() == 0)) | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         sampleFifo->writeAsync(amount, iPart1Begin, iPart1End, iPart2Begin, iPart2End, streamIndex); | 
					
						
							|  |  |  |         // part1
 | 
					
						
							|  |  |  |         if (iPart1Begin != iPart1End) { | 
					
						
							|  |  |  |             workSamplesSource(data, iPart1Begin, iPart1End, streamIndex); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // part2
 | 
					
						
							|  |  |  |         if (iPart2Begin != iPart2End) { | 
					
						
							|  |  |  |             workSamplesSource(data, iPart2Begin, iPart2End, streamIndex); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         // get new amount
 | 
					
						
							|  |  |  |         amount = sampleFifo->remainderAsync(streamIndex); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-13 01:55:12 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Routes samples from device source FIFO to sink channels that are registered for the FIFO | 
					
						
							|  |  |  |  * Routes samples from source channels registered for the FIFO to the device sink FIFO | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-10-22 18:38:02 +02:00
										 |  |  | void DSPDeviceMIMOEngine::workSamplesSink(const SampleVector::const_iterator& vbegin, const SampleVector::const_iterator& vend, unsigned int streamIndex) | 
					
						
							| 
									
										
										
										
											2019-05-27 02:52:33 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |     std::map<int, bool>::const_iterator rcIt = m_rxRealElseComplex.find(streamIndex); | 
					
						
							|  |  |  | 	bool positiveOnly = (rcIt == m_rxRealElseComplex.end() ? false : rcIt->second); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-25 00:45:36 +02:00
										 |  |  |     // DC and IQ corrections
 | 
					
						
							| 
									
										
										
										
											2019-10-22 18:38:02 +02:00
										 |  |  |     // if (m_sourcesCorrections[streamIndex].m_dcOffsetCorrection) {
 | 
					
						
							|  |  |  |     //     iqCorrections(vbegin, vend, streamIndex, m_sourcesCorrections[streamIndex].m_iqImbalanceCorrection);
 | 
					
						
							| 
									
										
										
										
											2019-10-02 02:05:33 +02:00
										 |  |  |     // }
 | 
					
						
							| 
									
										
										
										
											2019-05-27 02:52:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-25 00:45:36 +02:00
										 |  |  |     // feed data to direct sinks
 | 
					
						
							| 
									
										
										
										
											2019-10-22 18:38:02 +02:00
										 |  |  |     if (streamIndex < m_basebandSampleSinks.size()) | 
					
						
							| 
									
										
										
										
											2019-08-25 00:45:36 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-22 18:38:02 +02:00
										 |  |  |         for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks[streamIndex].begin(); it != m_basebandSampleSinks[streamIndex].end(); ++it) { | 
					
						
							| 
									
										
										
										
											2019-08-25 00:45:36 +02:00
										 |  |  |             (*it)->feed(vbegin, vend, positiveOnly); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 02:52:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-25 00:45:36 +02:00
										 |  |  |     // possibly feed data to spectrum sink
 | 
					
						
							| 
									
										
										
										
											2019-10-22 18:38:02 +02:00
										 |  |  |     if ((m_spectrumSink) && (m_spectrumInputSourceElseSink) && (streamIndex == m_spectrumInputIndex)) { | 
					
						
							| 
									
										
										
										
											2019-08-25 00:45:36 +02:00
										 |  |  |         m_spectrumSink->feed(vbegin, vend, positiveOnly); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 02:52:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |     // feed data to MIMO channels
 | 
					
						
							|  |  |  |     for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) { | 
					
						
							| 
									
										
										
										
											2019-10-22 18:38:02 +02:00
										 |  |  |         (*it)->feed(vbegin, vend, streamIndex); | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-27 02:52:33 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | void DSPDeviceMIMOEngine::workSamplesSource(SampleVector& data, unsigned int iBegin, unsigned int iEnd, unsigned int streamIndex) | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |     unsigned int nbSamples = iEnd - iBegin; | 
					
						
							|  |  |  |     SampleVector::iterator begin = data.begin() + iBegin; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |     // pull data from MIMO channels
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-17 03:54:37 +01:00
										 |  |  |     for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) { | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |         (*it)->pull(begin, nbSamples, streamIndex); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |     if (m_mimoChannels.size() == 0) // Process single stream channels only if there are no MIMO channels
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (m_basebandSampleSources[streamIndex].size() == 0) | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |             m_sourceZeroBuffers[streamIndex].allocate(nbSamples, Sample{0,0}); | 
					
						
							|  |  |  |             std::copy( | 
					
						
							|  |  |  |                 m_sourceZeroBuffers[streamIndex].m_vector.begin(), | 
					
						
							|  |  |  |                 m_sourceZeroBuffers[streamIndex].m_vector.begin() + nbSamples, | 
					
						
							|  |  |  |                 begin | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |         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; | 
					
						
							|  |  |  |             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 { | 
					
						
							| 
									
										
										
										
											2020-11-24 00:02:44 +01:00
										 |  |  |                         FixReal den = m_sumIndex + 1; // at each stage scale sum by n/n+1 and input by 1/n+1
 | 
					
						
							|  |  |  |                         FixReal nom = m_sumIndex;     // so that final sum is scaled by N (number of channels)
 | 
					
						
							|  |  |  |                         FixReal x = a.real()/den + nom*(b.real()/den); | 
					
						
							|  |  |  |                         FixReal y = a.imag()/den + nom*(b.imag()/den); | 
					
						
							|  |  |  |                         return Sample{x, y}; | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-22 18:38:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 00:58:15 +02:00
										 |  |  |     // possibly feed data to spectrum sink
 | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |     std::map<int, bool>::const_iterator rcIt = m_txRealElseComplex.find(streamIndex); | 
					
						
							|  |  |  | 	bool positiveOnly = (rcIt == m_txRealElseComplex.end() ? false : rcIt->second); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 00:58:15 +02:00
										 |  |  |     if ((m_spectrumSink) && (!m_spectrumInputSourceElseSink) && (streamIndex == m_spectrumInputIndex)) { | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |         m_spectrumSink->feed(begin, begin + nbSamples, positiveOnly); | 
					
						
							| 
									
										
										
										
											2019-10-21 00:58:15 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | // notStarted -> idle -> init -> running -+
 | 
					
						
							|  |  |  | //                ^                       |
 | 
					
						
							|  |  |  | //                +-----------------------+
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoIdle(int subsystemIndex) | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::gotoIdle: subsystemIndex:" << subsystemIndex; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-18 11:59:56 +02:00
										 |  |  | 	if (!m_deviceSampleMIMO) { | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 		return StIdle; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     if (subsystemIndex == 0) // Rx
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch (m_stateRx) { | 
					
						
							|  |  |  |             case StNotStarted: | 
					
						
							|  |  |  |                 return StNotStarted; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StIdle: | 
					
						
							|  |  |  |             case StError: | 
					
						
							|  |  |  |                 return StIdle; | 
					
						
							| 
									
										
										
										
											2019-10-06 09:54:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StReady: | 
					
						
							|  |  |  |             case StRunning: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         m_deviceSampleMIMO->stopRx(); // stop everything
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         std::vector<BasebandSampleSinks>::const_iterator vbit = m_basebandSampleSinks.begin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (; vbit != m_basebandSampleSinks.end(); ++vbit) | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             for (BasebandSampleSinks::const_iterator it = vbit->begin(); it != vbit->end(); ++it) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |                 qDebug() << "DSPDeviceMIMOEngine::gotoIdle: stopping BasebandSampleSink: " << (*it)->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 (*it)->stop(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |             qDebug() << "DSPDeviceMIMOEngine::gotoIdle: stopping MIMOChannel sinks: " << (*it)->getMIMOName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             (*it)->stopSinks(); | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     else if (subsystemIndex == 1) // Tx
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch (m_stateTx) { | 
					
						
							|  |  |  |             case StNotStarted: | 
					
						
							|  |  |  |                 return StNotStarted; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StIdle: | 
					
						
							|  |  |  |             case StError: | 
					
						
							|  |  |  |                 return StIdle; | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StReady: | 
					
						
							|  |  |  |             case StRunning: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_deviceSampleMIMO->stopTx(); // stop everything
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         std::vector<BasebandSampleSources>::const_iterator vSourceIt = m_basebandSampleSources.begin(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         for (; vSourceIt != m_basebandSampleSources.end(); vSourceIt++) | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |             for (BasebandSampleSources::const_iterator it = vSourceIt->begin(); it != vSourceIt->end(); ++it) | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |                 qDebug() << "DSPDeviceMIMOEngine::gotoIdle: stopping BasebandSampleSource(" << (*it)->getSourceName().toStdString().c_str() << ")"; | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 (*it)->stop(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |             qDebug() << "DSPDeviceMIMOEngine::gotoIdle: stopping MIMOChannel sources: " << (*it)->getMIMOName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             (*it)->stopSources(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         return StIdle; | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 	m_deviceDescription.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return StIdle; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoInit(int subsystemIndex) | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-18 11:59:56 +02:00
										 |  |  | 	if (!m_deviceSampleMIMO) { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 		return gotoError(subsystemIndex, "No sample MIMO configured"); | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_deviceDescription = m_deviceSampleMIMO->getDeviceDescription(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::gotoInit:" | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             << "subsystemIndex: " << subsystemIndex | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  | 	        << "m_deviceDescription: " << m_deviceDescription.toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     if (subsystemIndex == 0) // Rx
 | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         switch(m_stateRx) { | 
					
						
							|  |  |  |             case StNotStarted: | 
					
						
							|  |  |  |                 return StNotStarted; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StRunning: // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
 | 
					
						
							|  |  |  |                 return StRunning; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StReady: | 
					
						
							|  |  |  |                 return StReady; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StIdle: | 
					
						
							|  |  |  |             case StError: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	    // init: pass sample rate and center frequency to all sample rate and/or center frequency dependent sinks and wait for completion
 | 
					
						
							|  |  |  |         for (unsigned int isource = 0; isource < m_deviceSampleMIMO->getNbSourceStreams(); isource++) | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             if (isource < m_sourcesCorrections.size()) | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 m_sourcesCorrections[isource].m_iOffset = 0; | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_qOffset = 0; | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_iRange = 1 << 16; | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_qRange = 1 << 16; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             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()) | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks[isource].begin(); it != m_basebandSampleSinks[isource].end(); ++it) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |                     qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing " << (*it)->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |                     (*it)->pushMessage(new DSPSignalNotification(notif)); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (subsystemIndex == 1) // Tx
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch(m_stateTx) { | 
					
						
							|  |  |  |             case StNotStarted: | 
					
						
							|  |  |  |                 return StNotStarted; | 
					
						
							| 
									
										
										
										
											2019-05-19 12:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StRunning: // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
 | 
					
						
							|  |  |  |                 return StRunning; | 
					
						
							| 
									
										
										
										
											2019-05-19 12:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StReady: | 
					
						
							|  |  |  |                 return StReady; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StIdle: | 
					
						
							|  |  |  |             case StError: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         for (unsigned int isink = 0; isink < m_deviceSampleMIMO->getNbSinkStreams(); isink++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             quint64 sinkCenterFrequency = m_deviceSampleMIMO->getSinkCenterFrequency(isink); | 
					
						
							|  |  |  |             int sinkStreamSampleRate = m_deviceSampleMIMO->getSinkSampleRate(isink); | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             qDebug("DSPDeviceMIMOEngine::gotoInit: m_sinkCenterFrequencies[%d] = %llu", isink,  sinkCenterFrequency); | 
					
						
							|  |  |  |             qDebug("DSPDeviceMIMOEngine::gotoInit: m_sinkStreamSampleRates[%d] = %d", isink,  sinkStreamSampleRate); | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             DSPSignalNotification notif(sinkStreamSampleRate, sinkCenterFrequency); | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |             if (isink < m_basebandSampleSources.size()) | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |                 for (BasebandSampleSources::const_iterator it = m_basebandSampleSources[isink].begin(); it != m_basebandSampleSources[isink].end(); ++it) | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |                     qDebug() << "DSPDeviceMIMOEngine::gotoInit: initializing BasebandSampleSource(" << (*it)->getSourceName().toStdString().c_str() << ")"; | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |                     (*it)->pushMessage(new DSPSignalNotification(notif)); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	return StReady; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoRunning(int subsystemIndex) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::gotoRunning: subsystemIndex:" << subsystemIndex; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!m_deviceSampleMIMO) { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 		return gotoError(subsystemIndex, "DSPDeviceMIMOEngine::gotoRunning: No sample source configured"); | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::gotoRunning:" << m_deviceDescription.toStdString().c_str() << "started"; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     if (subsystemIndex == 0) // Rx
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         switch (m_stateRx) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             case StNotStarted: | 
					
						
							|  |  |  |                 return StNotStarted; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StIdle: | 
					
						
							|  |  |  |                 return StIdle; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StRunning: | 
					
						
							|  |  |  |                 return StRunning; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             case StReady: | 
					
						
							|  |  |  |             case StError: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!m_deviceSampleMIMO->startRx()) { // Start everything
 | 
					
						
							|  |  |  |             return gotoError(0, "Could not start sample source"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         std::vector<BasebandSampleSinks>::const_iterator vbit = m_basebandSampleSinks.begin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (; vbit != m_basebandSampleSinks.end(); ++vbit) | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             for (BasebandSampleSinks::const_iterator it = vbit->begin(); it != vbit->end(); ++it) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |                 qDebug() << "DSPDeviceMIMOEngine::gotoRunning: starting BasebandSampleSink: " << (*it)->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 (*it)->start(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |             qDebug() << "DSPDeviceMIMOEngine::gotoRunning: starting MIMOChannel sinks: " << (*it)->getMIMOName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             (*it)->startSinks(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (subsystemIndex == 1) // Tx
 | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         switch (m_stateTx) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             case StNotStarted: | 
					
						
							|  |  |  |                 return StNotStarted; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case StIdle: | 
					
						
							|  |  |  |                 return StIdle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case StRunning: | 
					
						
							|  |  |  |                 return StRunning; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case StReady: | 
					
						
							|  |  |  |             case StError: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!m_deviceSampleMIMO->startTx()) { // Start everything
 | 
					
						
							|  |  |  |             return gotoError(1, "Could not start sample sink"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         std::vector<BasebandSampleSources>::const_iterator vSourceIt = m_basebandSampleSources.begin(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (; vSourceIt != m_basebandSampleSources.end(); vSourceIt++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for (BasebandSampleSources::const_iterator it = vSourceIt->begin(); it != vSourceIt->end(); ++it) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |                 qDebug() << "DSPDeviceMIMOEngine::gotoRunning: starting BasebandSampleSource(" << (*it)->getSourceName().toStdString().c_str() << ")"; | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |                 (*it)->start(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |             qDebug() << "DSPDeviceMIMOEngine::gotoRunning: starting MIMOChannel sources: " << (*it)->getMIMOName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             (*it)->startSources(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-09-07 10:44:40 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::gotoRunning:input message queue pending: " << m_inputMessageQueue.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return StRunning; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | DSPDeviceMIMOEngine::State DSPDeviceMIMOEngine::gotoError(int subsystemIndex, const QString& errorMessage) | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	qDebug() << "DSPDeviceMIMOEngine::gotoError: " | 
					
						
							|  |  |  |         << " subsystemIndex: " << subsystemIndex | 
					
						
							|  |  |  |         <<  " errorMessage: " << errorMessage; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (subsystemIndex == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     	m_errorMessageRx = errorMessage; | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 	    setStateRx(StError); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (subsystemIndex == 1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     	m_errorMessageTx = errorMessage; | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 	    setStateTx(StError); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return StError; | 
					
						
							| 
									
										
										
										
											2019-05-15 08:33:13 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  | void DSPDeviceMIMOEngine::handleDataRxSync() | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	if (m_stateRx == StRunning) { | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |         workSampleSinkFifos(); | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | void DSPDeviceMIMOEngine::handleDataRxAsync(int streamIndex) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	if (m_stateRx == StRunning) { | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | 		workSampleSinkFifo(streamIndex); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::handleDataTxSync() | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	if (m_stateTx == StRunning) { | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |         workSampleSourceFifos(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::handleDataTxAsync(int streamIndex) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	if (m_stateTx == StRunning) { | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  | 		workSampleSourceFifo(streamIndex); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::handleSetMIMO(DeviceSampleMIMO* mimo) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-18 11:59:56 +02:00
										 |  |  |     m_deviceSampleMIMO = mimo; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |     if (!mimo) { // Early leave
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 22:08:06 +01:00
										 |  |  |     for (unsigned int i = 0; i < m_deviceSampleMIMO->getNbSinkFifos(); i++) | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         m_basebandSampleSinks.push_back(BasebandSampleSinks()); | 
					
						
							|  |  |  |         m_sourcesCorrections.push_back(SourceCorrection()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 22:08:06 +01:00
										 |  |  |     for (unsigned int i = 0; i < m_deviceSampleMIMO->getNbSourceFifos(); i++) | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         m_basebandSampleSources.push_back(BasebandSampleSources()); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |         m_sourceSampleBuffers.push_back(IncrementalVector<Sample>()); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         m_sourceZeroBuffers.push_back(IncrementalVector<Sample>()); | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_deviceSampleMIMO->getMIMOType() == DeviceSampleMIMO::MIMOHalfSynchronous) // synchronous FIFOs on Rx and not with Tx
 | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |         qDebug("DSPDeviceMIMOEngine::handleSetMIMO: synchronous sources set %s", qPrintable(mimo->getDeviceDescription())); | 
					
						
							|  |  |  |         // connect(m_deviceSampleMIMO->getSampleSinkFifo(m_sampleSinkConnectionIndexes[0]), SIGNAL(dataReady()), this, SLOT(handleData()), Qt::QueuedConnection);
 | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |         QObject::connect( | 
					
						
							|  |  |  |             m_deviceSampleMIMO->getSampleMIFifo(), | 
					
						
							|  |  |  |             &SampleMIFifo::dataSyncReady, | 
					
						
							|  |  |  |             this, | 
					
						
							|  |  |  |             &DSPDeviceMIMOEngine::handleDataRxSync, | 
					
						
							|  |  |  |             Qt::QueuedConnection | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |         QObject::connect( | 
					
						
							|  |  |  |             m_deviceSampleMIMO->getSampleMOFifo(), | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |             &SampleMOFifo::dataReadSync, | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |             this, | 
					
						
							|  |  |  |             &DSPDeviceMIMOEngine::handleDataTxSync, | 
					
						
							|  |  |  |             Qt::QueuedConnection | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (m_deviceSampleMIMO->getMIMOType() == DeviceSampleMIMO::MIMOAsynchronous) // asynchronous FIFOs
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |         for (unsigned int stream = 0; stream < m_deviceSampleMIMO->getNbSourceStreams(); stream++) | 
					
						
							| 
									
										
										
										
											2019-05-27 02:52:33 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |             qDebug("DSPDeviceMIMOEngine::handleSetMIMO: asynchronous sources set %s channel %u", | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |                 qPrintable(mimo->getDeviceDescription()), stream); | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |             QObject::connect( | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |                 m_deviceSampleMIMO->getSampleMIFifo(), | 
					
						
							|  |  |  |                 &SampleMIFifo::dataAsyncReady, | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |                 this, | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |                 &DSPDeviceMIMOEngine::handleDataRxAsync, | 
					
						
							| 
									
										
										
										
											2019-08-14 02:56:15 +02:00
										 |  |  |                 Qt::QueuedConnection | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |             QObject::connect( | 
					
						
							|  |  |  |                 m_deviceSampleMIMO->getSampleMOFifo(), | 
					
						
							| 
									
										
										
										
											2019-11-17 01:56:54 +01:00
										 |  |  |                 &SampleMOFifo::dataReadAsync, | 
					
						
							| 
									
										
										
										
											2019-10-19 05:07:24 +02:00
										 |  |  |                 this, | 
					
						
							|  |  |  |                 &DSPDeviceMIMOEngine::handleDataTxAsync, | 
					
						
							|  |  |  |                 Qt::QueuedConnection | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2019-09-25 18:39:17 +02:00
										 |  |  |             // QObject::connect(
 | 
					
						
							|  |  |  |             //     m_deviceSampleMIMO->getSampleSinkFifo(stream),
 | 
					
						
							|  |  |  |             //     &SampleSinkFifo::dataReady,
 | 
					
						
							|  |  |  |             //     this,
 | 
					
						
							|  |  |  |             //     [=](){ this->handleDataRxAsync(stream); },
 | 
					
						
							|  |  |  |             //     Qt::QueuedConnection
 | 
					
						
							|  |  |  |             // );
 | 
					
						
							| 
									
										
										
										
											2019-05-27 02:52:33 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::handleSynchronousMessages() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Message *message = m_syncMessenger.getMessage(); | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::handleSynchronousMessages: " << message->getIdentifier(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     State returnState = StNotStarted; | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	if (DSPAcquisitionInit::match(*message)) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 		setStateRx(gotoIdle(0)); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (m_stateRx == StIdle) { | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 			setStateRx(gotoInit(0)); // State goes ready if init is performed
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         returnState = m_stateRx; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPAcquisitionStart::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (m_stateRx == StReady) { | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 			setStateRx(gotoRunning(0)); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         returnState = m_stateRx; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPAcquisitionStop::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 		setStateRx(gotoIdle(0)); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         returnState = m_stateRx; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     else if (DSPGenerationInit::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 		setStateTx(gotoIdle(1)); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (m_stateTx == StIdle) { | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 			setStateTx(gotoInit(1)); // State goes ready if init is performed
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         returnState = m_stateTx; | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPGenerationStart::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 		if (m_stateTx == StReady) { | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 			setStateTx(gotoRunning(1)); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         returnState = m_stateTx; | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPGenerationStop::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 		setStateTx(gotoIdle(1)); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         returnState = m_stateTx; | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else if (GetMIMODeviceDescription::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		((GetMIMODeviceDescription*) message)->setDeviceDescription(m_deviceDescription); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  | 	else if (GetErrorMessage::match(*message)) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         GetErrorMessage *cmd = (GetErrorMessage *) message; | 
					
						
							|  |  |  |         int subsystemIndex = cmd->getSubsystemIndex(); | 
					
						
							|  |  |  |         if (subsystemIndex == 0) { | 
					
						
							|  |  |  |             cmd->setErrorMessage(m_errorMessageRx); | 
					
						
							|  |  |  |         } else if (subsystemIndex == 1) { | 
					
						
							|  |  |  |             cmd->setErrorMessage(m_errorMessageTx); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             cmd->setErrorMessage("Not implemented"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else if (SetSampleMIMO::match(*message)) { | 
					
						
							|  |  |  | 		handleSetMIMO(((SetSampleMIMO*) message)->getSampleMIMO()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (AddBasebandSampleSink::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  |         const AddBasebandSampleSink *msg = (AddBasebandSampleSink *) message; | 
					
						
							|  |  |  | 		BasebandSampleSink* sink = msg->getSampleSink(); | 
					
						
							| 
									
										
										
										
											2019-05-16 00:43:15 +02:00
										 |  |  |         unsigned int isource = msg->getIndex(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 12:54:22 +02:00
										 |  |  |         if (isource < m_basebandSampleSinks.size()) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             m_basebandSampleSinks[isource].push_back(sink); | 
					
						
							|  |  |  |             // initialize sample rate and center frequency in the sink:
 | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |             int sourceStreamSampleRate = m_deviceSampleMIMO->getSourceSampleRate(isource); | 
					
						
							|  |  |  |             quint64 sourceCenterFrequency = m_deviceSampleMIMO->getSourceCenterFrequency(isource); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |             DSPSignalNotification *msg = new DSPSignalNotification(sourceStreamSampleRate, sourceCenterFrequency); | 
					
						
							|  |  |  |             sink->pushMessage(msg); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |             // start the sink:
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             if (m_stateRx == StRunning) { | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                 sink->start(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (RemoveBasebandSampleSink::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  |         const RemoveBasebandSampleSink *msg = (RemoveBasebandSampleSink *) message; | 
					
						
							|  |  |  | 		BasebandSampleSink* sink = ((DSPRemoveBasebandSampleSink*) message)->getSampleSink(); | 
					
						
							| 
									
										
										
										
											2019-05-16 00:43:15 +02:00
										 |  |  |         unsigned int isource = msg->getIndex(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (isource < m_basebandSampleSinks.size()) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             if (m_stateRx == StRunning) { | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                 sink->stop(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		    m_basebandSampleSinks[isource].remove(sink); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 	else if (AddBasebandSampleSource::match(*message)) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         const AddBasebandSampleSource *msg = (AddBasebandSampleSource *) message; | 
					
						
							|  |  |  | 		BasebandSampleSource *sampleSource = msg->getSampleSource(); | 
					
						
							| 
									
										
										
										
											2019-05-16 00:43:15 +02:00
										 |  |  |         unsigned int isink = msg->getIndex(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         if (isink < m_basebandSampleSources.size()) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 		    m_basebandSampleSources[isink].push_back(sampleSource); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |             // initialize sample rate and center frequency in the sink:
 | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |             int sinkStreamSampleRate = m_deviceSampleMIMO->getSinkSampleRate(isink); | 
					
						
							|  |  |  |             quint64 sinkCenterFrequency = m_deviceSampleMIMO->getSinkCenterFrequency(isink); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |             DSPSignalNotification *msg = new DSPSignalNotification(sinkStreamSampleRate, sinkCenterFrequency); | 
					
						
							|  |  |  |             sampleSource->pushMessage(msg); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |             // start the sink:
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |             if (m_stateTx == StRunning) { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |                 sampleSource->start(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  | 	else if (RemoveBasebandSampleSource::match(*message)) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         const RemoveBasebandSampleSource *msg = (RemoveBasebandSampleSource *) message; | 
					
						
							|  |  |  | 		BasebandSampleSource* sampleSource = msg->getSampleSource(); | 
					
						
							| 
									
										
										
										
											2019-05-16 00:43:15 +02:00
										 |  |  |         unsigned int isink = msg->getIndex(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |         if (isink < m_basebandSampleSources.size()) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2019-11-15 01:04:24 +01:00
										 |  |  |             sampleSource->stop(); | 
					
						
							|  |  |  |             m_basebandSampleSources[isink].remove(sampleSource); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |     else if (AddMIMOChannel::match(*message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const AddMIMOChannel *msg = (AddMIMOChannel *) message; | 
					
						
							|  |  |  |         MIMOChannel *channel = msg->getChannel(); | 
					
						
							|  |  |  |         m_mimoChannels.push_back(channel); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 22:08:06 +01:00
										 |  |  |         for (unsigned int isource = 0; isource < m_deviceSampleMIMO->getNbSourceStreams(); isource++) | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |             DSPMIMOSignalNotification *notif = new DSPMIMOSignalNotification( | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |                 m_deviceSampleMIMO->getSourceSampleRate(isource), | 
					
						
							|  |  |  |                 m_deviceSampleMIMO->getSourceCenterFrequency(isource), | 
					
						
							|  |  |  |                 true, | 
					
						
							|  |  |  |                 isource | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |             channel->pushMessage(notif); | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-14 22:08:06 +01:00
										 |  |  |         for (unsigned int isink = 0; isink < m_deviceSampleMIMO->getNbSinkStreams(); isink++) | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |             DSPMIMOSignalNotification *notif = new DSPMIMOSignalNotification( | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |                 m_deviceSampleMIMO->getSinkSampleRate(isink), | 
					
						
							|  |  |  |                 m_deviceSampleMIMO->getSinkCenterFrequency(isink), | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |                 false, | 
					
						
							|  |  |  |                 isink | 
					
						
							|  |  |  |             ); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |             channel->pushMessage(notif); | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         if (m_stateRx == StRunning) { | 
					
						
							|  |  |  |             channel->startSinks(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_stateTx == StRunning) { | 
					
						
							|  |  |  |             channel->startSources(); | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (RemoveMIMOChannel::match(*message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         const RemoveMIMOChannel *msg = (RemoveMIMOChannel *) message; | 
					
						
							|  |  |  |         MIMOChannel *channel = msg->getChannel(); | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |         channel->stopSinks(); | 
					
						
							|  |  |  |         channel->stopSources(); | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |         m_mimoChannels.remove(channel); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  | 	else if (AddSpectrumSink::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		m_spectrumSink = ((AddSpectrumSink*) message)->getSampleSink(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     else if (RemoveSpectrumSink::match(*message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BasebandSampleSink* spectrumSink = ((DSPRemoveSpectrumSink*) message)->getSampleSink(); | 
					
						
							|  |  |  |         spectrumSink->stop(); | 
					
						
							|  |  |  |         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 ((!spectrumInputSourceElseSink) && (spectrumInputIndex <  m_deviceSampleMIMO->getNbSinkStreams())) // add the source listener
 | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (m_spectrumSink) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |                     DSPSignalNotification *notif = new DSPSignalNotification( | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |                         m_deviceSampleMIMO->getSinkSampleRate(spectrumInputIndex), | 
					
						
							|  |  |  |                         m_deviceSampleMIMO->getSinkCenterFrequency(spectrumInputIndex)); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |                     m_spectrumSink->pushMessage(notif); | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (m_spectrumSink && (spectrumInputSourceElseSink) && (spectrumInputIndex <  m_deviceSampleMIMO->getNbSinkFifos())) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |                 DSPSignalNotification *notif = new DSPSignalNotification( | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |                     m_deviceSampleMIMO->getSourceSampleRate(spectrumInputIndex), | 
					
						
							|  |  |  |                     m_deviceSampleMIMO->getSourceCenterFrequency(spectrumInputIndex)); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |                 m_spectrumSink->pushMessage(notif); | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             m_spectrumInputSourceElseSink = spectrumInputSourceElseSink; | 
					
						
							|  |  |  |             m_spectrumInputIndex = spectrumInputIndex; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-20 20:05:01 +02:00
										 |  |  |     m_syncMessenger.done(returnState); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::handleInputMessages() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Message* message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((message = m_inputMessageQueue.pop()) != 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		qDebug("DSPDeviceMIMOEngine::handleInputMessages: message: %s", message->getIdentifier()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ConfigureCorrection::match(*message)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			ConfigureCorrection* conf = (ConfigureCorrection*) message; | 
					
						
							| 
									
										
										
										
											2019-05-16 00:43:15 +02:00
										 |  |  |             unsigned int isource = conf->getIndex(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (isource < m_sourcesCorrections.size()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_iqImbalanceCorrection = conf->getIQImbalanceCorrection(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (m_sourcesCorrections[isource].m_dcOffsetCorrection != conf->getDCOffsetCorrection()) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     m_sourcesCorrections[isource].m_dcOffsetCorrection = conf->getDCOffsetCorrection(); | 
					
						
							|  |  |  |                     m_sourcesCorrections[isource].m_iOffset = 0; | 
					
						
							|  |  |  |                     m_sourcesCorrections[isource].m_qOffset = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (m_sourcesCorrections[isource].m_iqImbalanceCorrection != conf->getIQImbalanceCorrection()) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         m_sourcesCorrections[isource].m_iqImbalanceCorrection = conf->getIQImbalanceCorrection(); | 
					
						
							|  |  |  |                         m_sourcesCorrections[isource].m_iRange = 1 << 16; | 
					
						
							|  |  |  |                         m_sourcesCorrections[isource].m_qRange = 1 << 16; | 
					
						
							|  |  |  |                         m_sourcesCorrections[isource].m_imbalance = 65536; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-05-19 12:54:22 +02:00
										 |  |  |                 m_sourcesCorrections[isource].m_iBeta.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_qBeta.reset(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                 m_sourcesCorrections[isource].m_avgAmp.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgII.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgII2.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgIQ.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgPhi.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgQQ2.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_iBeta.reset(); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_qBeta.reset(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			delete message; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-06-04 16:57:27 +02:00
										 |  |  | 		else if (DSPMIMOSignalNotification::match(*message)) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2019-06-04 16:57:27 +02:00
										 |  |  | 			DSPMIMOSignalNotification *notif = (DSPMIMOSignalNotification *) message; | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// update DSP values
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |             bool sourceElseSink = notif->getSourceOrSink(); | 
					
						
							| 
									
										
										
										
											2019-05-16 00:43:15 +02:00
										 |  |  |             unsigned int istream = notif->getIndex(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 			int sampleRate = notif->getSampleRate(); | 
					
						
							|  |  |  | 			qint64 centerFrequency = notif->getCenterFrequency(); | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |             bool realElseComplex = notif->getRealElseComplex(); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-04 16:57:27 +02:00
										 |  |  | 			qDebug() << "DeviceMIMOEngine::handleInputMessages: DSPMIMOSignalNotification:" | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |                 << " sourceElseSink: " << sourceElseSink | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                 << " istream: " << istream | 
					
						
							|  |  |  | 				<< " sampleRate: " << sampleRate | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  | 				<< " centerFrequency: " << centerFrequency | 
					
						
							|  |  |  |                 << " realElseComplex" << realElseComplex; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (sourceElseSink) { | 
					
						
							|  |  |  |                 m_rxRealElseComplex[istream] = realElseComplex; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 m_txRealElseComplex[istream] = realElseComplex; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |             for (MIMOChannels::const_iterator it = m_mimoChannels.begin(); it != m_mimoChannels.end(); ++it) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 DSPMIMOSignalNotification *message = new DSPMIMOSignalNotification(*notif); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |                 (*it)->pushMessage(message); | 
					
						
							| 
									
										
										
										
											2019-09-04 05:00:22 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |             if (m_deviceSampleMIMO) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                 if (sourceElseSink) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                     if ((istream < m_deviceSampleMIMO->getNbSourceStreams())) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         // forward source changes to ancillary sinks
 | 
					
						
							|  |  |  |                         if (istream < m_basebandSampleSinks.size()) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                             for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks[istream].begin(); it != m_basebandSampleSinks[istream].end(); ++it) | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 DSPSignalNotification *message = new DSPSignalNotification(sampleRate, centerFrequency); | 
					
						
							|  |  |  |                                 qDebug() << "DSPDeviceMIMOEngine::handleInputMessages: starting " << (*it)->getSinkName().toStdString().c_str(); | 
					
						
							|  |  |  |                                 (*it)->pushMessage(message); | 
					
						
							|  |  |  |                             } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                         // forward changes to MIMO GUI input queue
 | 
					
						
							|  |  |  |                         MessageQueue *guiMessageQueue = m_deviceSampleMIMO->getMessageQueueToGUI(); | 
					
						
							|  |  |  |                         qDebug("DeviceMIMOEngine::handleInputMessages: DSPMIMOSignalNotification: guiMessageQueue: %p", guiMessageQueue); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                         if (guiMessageQueue) { | 
					
						
							|  |  |  |                             DSPMIMOSignalNotification* rep = new DSPMIMOSignalNotification(*notif); // make a copy for the MIMO GUI
 | 
					
						
							|  |  |  |                             guiMessageQueue->push(rep); | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                         // forward changes to spectrum sink if currently active
 | 
					
						
							|  |  |  |                         if (m_spectrumSink && m_spectrumInputSourceElseSink && (m_spectrumInputIndex == istream)) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             DSPSignalNotification *spectrumNotif = new DSPSignalNotification(sampleRate, centerFrequency); | 
					
						
							|  |  |  |                             m_spectrumSink->pushMessage(spectrumNotif); | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                 else | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                     if ((istream < m_deviceSampleMIMO->getNbSinkStreams())) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         // forward source changes to channel sources with immediate execution (no queuing)
 | 
					
						
							|  |  |  |                         if (istream < m_basebandSampleSources.size()) | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                             for (BasebandSampleSources::const_iterator it = m_basebandSampleSources[istream].begin(); it != m_basebandSampleSources[istream].end(); ++it) | 
					
						
							|  |  |  |                             { | 
					
						
							|  |  |  |                                 DSPSignalNotification *message = new DSPSignalNotification(sampleRate, centerFrequency); | 
					
						
							|  |  |  |                                 qDebug() << "DSPDeviceMIMOEngine::handleSinkMessages: forward message to BasebandSampleSource(" << (*it)->getSourceName().toStdString().c_str() << ")"; | 
					
						
							|  |  |  |                                 (*it)->pushMessage(message); | 
					
						
							|  |  |  |                             } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                         // forward changes to MIMO GUI input queue
 | 
					
						
							|  |  |  |                         MessageQueue *guiMessageQueue = m_deviceSampleMIMO->getMessageQueueToGUI(); | 
					
						
							|  |  |  |                         qDebug("DSPDeviceMIMOEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue); | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                         if (guiMessageQueue) { | 
					
						
							|  |  |  |                             DSPMIMOSignalNotification* rep = new DSPMIMOSignalNotification(*notif); // make a copy for the source GUI
 | 
					
						
							|  |  |  |                             guiMessageQueue->push(rep); | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |                         // forward changes to spectrum sink if currently active
 | 
					
						
							|  |  |  |                         if (m_spectrumSink && !m_spectrumInputSourceElseSink && (m_spectrumInputIndex == istream)) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             DSPSignalNotification *spectrumNotif = new DSPSignalNotification(sampleRate, centerFrequency); | 
					
						
							|  |  |  |                             m_spectrumSink->pushMessage(spectrumNotif); | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             delete message; | 
					
						
							| 
									
										
										
										
											2019-05-15 18:51:10 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-18 06:30:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void DSPDeviceMIMOEngine::configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int isource) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qDebug() << "DSPDeviceMIMOEngine::configureCorrections"; | 
					
						
							|  |  |  | 	ConfigureCorrection* cmd = new ConfigureCorrection(dcOffsetCorrection, iqImbalanceCorrection, isource); | 
					
						
							|  |  |  | 	m_inputMessageQueue.push(cmd); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-05-19 10:23:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 22:09:19 +02:00
										 |  |  | void DSPDeviceMIMOEngine::iqCorrections(SampleVector::iterator begin, SampleVector::iterator end, int isource, bool imbalanceCorrection) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for(SampleVector::iterator it = begin; it < end; it++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_sourcesCorrections[isource].m_iBeta(it->real()); | 
					
						
							|  |  |  |         m_sourcesCorrections[isource].m_qBeta(it->imag()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (imbalanceCorrection) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  | #if IMBALANCE_INT
 | 
					
						
							|  |  |  |             // acquisition
 | 
					
						
							|  |  |  |             int64_t xi = (it->m_real - (int32_t) m_sourcesCorrections[isource].m_iBeta) << 5; | 
					
						
							|  |  |  |             int64_t xq = (it->m_imag - (int32_t) m_sourcesCorrections[isource].m_qBeta) << 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // phase imbalance
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgII((xi*xi)>>28); // <I", I">
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgIQ((xi*xq)>>28); // <I", Q">
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((int64_t) m_sourcesCorrections[isource].m_avgII != 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 int64_t phi = (((int64_t) m_sourcesCorrections[isource].m_avgIQ)<<28) / (int64_t) m_sourcesCorrections[isource].m_avgII; | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgPhi(phi); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int64_t corrPhi = (((int64_t) m_sourcesCorrections[isource].m_avgPhi) * xq) >> 28;  //(m_avgPhi.asDouble()/16777216.0) * ((double) xq);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int64_t yi = xi - corrPhi; | 
					
						
							|  |  |  |             int64_t yq = xq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // amplitude I/Q imbalance
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgII2((yi*yi)>>28); // <I, I>
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgQQ2((yq*yq)>>28); // <Q, Q>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((int64_t) m_sourcesCorrections[isource].m_avgQQ2 != 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 int64_t a = (((int64_t) m_sourcesCorrections[isource].m_avgII2)<<28) / (int64_t) m_sourcesCorrections[isource].m_avgQQ2; | 
					
						
							|  |  |  |                 Fixed<int64_t, 28> fA(Fixed<int64_t, 28>::internal(), a); | 
					
						
							|  |  |  |                 Fixed<int64_t, 28> sqrtA = sqrt((Fixed<int64_t, 28>) fA); | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgAmp(sqrtA.as_internal()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int64_t zq = (((int64_t) m_sourcesCorrections[isource].m_avgAmp) * yq) >> 28; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it->m_real = yi >> 5; | 
					
						
							|  |  |  |             it->m_imag = zq >> 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |             // DC correction and conversion
 | 
					
						
							|  |  |  |             float xi = (it->m_real - (int32_t) m_sourcesCorrections[isource].m_iBeta) / SDR_RX_SCALEF; | 
					
						
							|  |  |  |             float xq = (it->m_imag - (int32_t) m_sourcesCorrections[isource].m_qBeta) / SDR_RX_SCALEF; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // phase imbalance
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgII(xi*xi); // <I", I">
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgIQ(xi*xq); // <I", Q">
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (m_sourcesCorrections[isource].m_avgII.asDouble() != 0) { | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgPhi(m_sourcesCorrections[isource].m_avgIQ.asDouble()/m_sourcesCorrections[isource].m_avgII.asDouble()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             float& yi = xi; // the in phase remains the reference
 | 
					
						
							|  |  |  |             float yq = xq - m_sourcesCorrections[isource].m_avgPhi.asDouble()*xi; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // amplitude I/Q imbalance
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgII2(yi*yi); // <I, I>
 | 
					
						
							|  |  |  |             m_sourcesCorrections[isource].m_avgQQ2(yq*yq); // <Q, Q>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (m_sourcesCorrections[isource].m_avgQQ2.asDouble() != 0) { | 
					
						
							|  |  |  |                 m_sourcesCorrections[isource].m_avgAmp(sqrt(m_sourcesCorrections[isource].m_avgII2.asDouble() / m_sourcesCorrections[isource].m_avgQQ2.asDouble())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // final correction
 | 
					
						
							|  |  |  |             float& zi = yi; // the in phase remains the reference
 | 
					
						
							|  |  |  |             float zq = m_sourcesCorrections[isource].m_avgAmp.asDouble() * yq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // convert and store
 | 
					
						
							|  |  |  |             it->m_real = zi * SDR_RX_SCALEF; | 
					
						
							|  |  |  |             it->m_imag = zq * SDR_RX_SCALEF; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // DC correction only
 | 
					
						
							|  |  |  |             it->m_real -= (int32_t) m_sourcesCorrections[isource].m_iBeta; | 
					
						
							|  |  |  |             it->m_imag -= (int32_t) m_sourcesCorrections[isource].m_qBeta; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |