| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2015 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                  //
 | 
					
						
							| 
									
										
										
										
											2019-04-11 14:32:15 +02:00
										 |  |  | // (at your option) any later version.                                           //
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | #include "dspdevicesourceengine.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 22:29:04 +02:00
										 |  |  | #include <dsp/basebandsamplesink.h>
 | 
					
						
							| 
									
										
										
										
											2016-10-02 23:16:40 +02:00
										 |  |  | #include <dsp/devicesamplesource.h>
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <QDebug>
 | 
					
						
							|  |  |  | #include "dsp/dspcommands.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-04 10:49:13 +01:00
										 |  |  | #include "util/fixed.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-06 19:18:02 +02:00
										 |  |  | #include "samplesinkfifo.h"
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | DSPDeviceSourceEngine::DSPDeviceSourceEngine(uint uid, QObject* parent) : | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	QThread(parent), | 
					
						
							| 
									
										
										
										
											2017-05-25 20:13:34 +02:00
										 |  |  |     m_uid(uid), | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	m_state(StNotStarted), | 
					
						
							| 
									
										
										
										
											2019-05-18 11:59:56 +02:00
										 |  |  | 	m_deviceSampleSource(nullptr), | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	m_sampleSourceSequence(0), | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 	m_basebandSampleSinks(), | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	m_sampleRate(0), | 
					
						
							|  |  |  | 	m_centerFrequency(0), | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |     m_realElseComplex(false), | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	m_dcOffsetCorrection(false), | 
					
						
							|  |  |  | 	m_iqImbalanceCorrection(false), | 
					
						
							|  |  |  | 	m_iOffset(0), | 
					
						
							|  |  |  | 	m_qOffset(0), | 
					
						
							|  |  |  | 	m_iRange(1 << 16), | 
					
						
							|  |  |  | 	m_qRange(1 << 16), | 
					
						
							|  |  |  | 	m_imbalance(65536) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-10-21 02:32:21 +02:00
										 |  |  | 	connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); | 
					
						
							|  |  |  | 	connect(&m_syncMessenger, SIGNAL(messageSent()), this, SLOT(handleSynchronousMessages()), Qt::QueuedConnection); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	moveToThread(this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | DSPDeviceSourceEngine::~DSPDeviceSourceEngine() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-14 11:27:57 +01:00
										 |  |  |     stop(); | 
					
						
							|  |  |  |     wait(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | void DSPDeviceSourceEngine::setState(State state) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_state != state) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_state = state; | 
					
						
							|  |  |  |         emit stateChanged(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::run() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::run"; | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 	setState(StIdle); | 
					
						
							| 
									
										
										
										
											2018-02-14 17:33:08 +01:00
										 |  |  |     exec(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::start() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::start"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	QThread::start(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::stop() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::stop"; | 
					
						
							| 
									
										
										
										
											2017-10-04 00:50:42 +02:00
										 |  |  |     gotoIdle(); | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  |     setState(StNotStarted); | 
					
						
							| 
									
										
										
										
											2017-10-04 00:50:42 +02:00
										 |  |  | 	QThread::exit(); | 
					
						
							|  |  |  | //	DSPExit cmd;
 | 
					
						
							|  |  |  | //	m_syncMessenger.sendWait(cmd);
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | bool DSPDeviceSourceEngine::initAcquisition() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::initAcquisition"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	DSPAcquisitionInit cmd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m_syncMessenger.sendWait(cmd) == StReady; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | bool DSPDeviceSourceEngine::startAcquisition() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::startAcquisition"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	DSPAcquisitionStart cmd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m_syncMessenger.sendWait(cmd) == StRunning; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::stopAcquistion() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::stopAcquistion"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	DSPAcquisitionStop cmd; | 
					
						
							|  |  |  | 	m_syncMessenger.storeMessage(cmd); | 
					
						
							|  |  |  | 	handleSynchronousMessages(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(m_dcOffsetCorrection) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		qDebug("DC offset:%f,%f", m_iOffset, m_qOffset); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::setSource(DeviceSampleSource* source) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::setSource"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	DSPSetSource cmd(source); | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::setSourceSequence(int sequence) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug("DSPDeviceSourceEngine::setSourceSequence: seq: %d", sequence); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	m_sampleSourceSequence = sequence; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::addSink(BasebandSampleSink* sink) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::addSink: " << sink->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2018-01-02 01:04:49 +01:00
										 |  |  | 	DSPAddBasebandSampleSink cmd(sink); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::removeSink(BasebandSampleSink* sink) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::removeSink: " << sink->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2018-01-02 01:04:49 +01:00
										 |  |  | 	DSPRemoveBasebandSampleSink cmd(sink); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::configureCorrections"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	DSPConfigureCorrection* cmd = new DSPConfigureCorrection(dcOffsetCorrection, iqImbalanceCorrection); | 
					
						
							|  |  |  | 	m_inputMessageQueue.push(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | QString DSPDeviceSourceEngine::errorMessage() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::errorMessage"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	DSPGetErrorMessage cmd; | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | 	return cmd.getErrorMessage(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | QString DSPDeviceSourceEngine::sourceDeviceDescription() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::sourceDeviceDescription"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	DSPGetSourceDeviceDescription cmd; | 
					
						
							|  |  |  | 	m_syncMessenger.sendWait(cmd); | 
					
						
							|  |  |  | 	return cmd.getDeviceDescription(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 02:45:55 +01:00
										 |  |  | void DSPDeviceSourceEngine::iqCorrections(SampleVector::iterator begin, SampleVector::iterator end, bool imbalanceCorrection) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for(SampleVector::iterator it = begin; it < end; it++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_iBeta(it->real()); | 
					
						
							|  |  |  |         m_qBeta(it->imag()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (imbalanceCorrection) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-02-04 18:20:16 +01:00
										 |  |  | #if IMBALANCE_INT
 | 
					
						
							|  |  |  |             // acquisition
 | 
					
						
							|  |  |  |             int64_t xi = (it->m_real - (int32_t) m_iBeta) << 5; | 
					
						
							|  |  |  |             int64_t xq = (it->m_imag - (int32_t) m_qBeta) << 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // phase imbalance
 | 
					
						
							|  |  |  |             m_avgII((xi*xi)>>28); // <I", I">
 | 
					
						
							|  |  |  |             m_avgIQ((xi*xq)>>28); // <I", Q">
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((int64_t) m_avgII != 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 int64_t phi = (((int64_t) m_avgIQ)<<28) / (int64_t) m_avgII; | 
					
						
							|  |  |  |                 m_avgPhi(phi); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int64_t corrPhi = (((int64_t) 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_avgII2((yi*yi)>>28); // <I, I>
 | 
					
						
							|  |  |  |             m_avgQQ2((yq*yq)>>28); // <Q, Q>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if ((int64_t) m_avgQQ2 != 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 int64_t a = (((int64_t) m_avgII2)<<28) / (int64_t) 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_avgAmp(sqrtA.as_internal()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             int64_t zq = (((int64_t) m_avgAmp) * yq) >> 28; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it->m_real = yi >> 5; | 
					
						
							|  |  |  |             it->m_imag = zq >> 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2018-02-04 10:49:13 +01:00
										 |  |  |             // DC correction and conversion
 | 
					
						
							|  |  |  |             float xi = (it->m_real - (int32_t) m_iBeta) / SDR_RX_SCALEF; | 
					
						
							|  |  |  |             float xq = (it->m_imag - (int32_t) m_qBeta) / SDR_RX_SCALEF; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // phase imbalance
 | 
					
						
							|  |  |  |             m_avgII(xi*xi); // <I", I">
 | 
					
						
							|  |  |  |             m_avgIQ(xi*xq); // <I", Q">
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (m_avgII.asDouble() != 0) { | 
					
						
							|  |  |  |                 m_avgPhi(m_avgIQ.asDouble()/m_avgII.asDouble()); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 01:42:35 +01:00
										 |  |  |             float& yi = xi; // the in phase remains the reference
 | 
					
						
							|  |  |  |             float yq = xq - m_avgPhi.asDouble()*xi; | 
					
						
							| 
									
										
										
										
											2018-02-04 10:49:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // amplitude I/Q imbalance
 | 
					
						
							|  |  |  |             m_avgII2(yi*yi); // <I, I>
 | 
					
						
							|  |  |  |             m_avgQQ2(yq*yq); // <Q, Q>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (m_avgQQ2.asDouble() != 0) { | 
					
						
							|  |  |  |                 m_avgAmp(sqrt(m_avgII2.asDouble() / m_avgQQ2.asDouble())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // final correction
 | 
					
						
							| 
									
										
										
										
											2018-02-11 01:42:35 +01:00
										 |  |  |             float& zi = yi; // the in phase remains the reference
 | 
					
						
							| 
									
										
										
										
											2018-02-04 10:49:13 +01:00
										 |  |  |             float zq = m_avgAmp.asDouble() * yq; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // convert and store
 | 
					
						
							|  |  |  |             it->m_real = zi * SDR_RX_SCALEF; | 
					
						
							|  |  |  |             it->m_imag = zq * SDR_RX_SCALEF; | 
					
						
							| 
									
										
										
										
											2018-02-04 18:20:16 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-02-01 02:45:55 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-02-04 10:49:13 +01:00
										 |  |  |             // DC correction only
 | 
					
						
							| 
									
										
										
										
											2018-02-01 02:45:55 +01:00
										 |  |  |             it->m_real -= (int32_t) m_iBeta; | 
					
						
							|  |  |  |             it->m_imag -= (int32_t) m_qBeta; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::dcOffset(SampleVector::iterator begin, SampleVector::iterator end) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	// sum and correct in one pass
 | 
					
						
							|  |  |  | 	for(SampleVector::iterator it = begin; it < end; it++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-02-01 02:45:55 +01:00
										 |  |  | 	    m_iBeta(it->real()); | 
					
						
							|  |  |  | 	    m_qBeta(it->imag()); | 
					
						
							|  |  |  | 	    it->m_real -= (int32_t) m_iBeta; | 
					
						
							|  |  |  | 	    it->m_imag -= (int32_t) m_qBeta; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::imbalance(SampleVector::iterator begin, SampleVector::iterator end) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	int iMin = 0; | 
					
						
							|  |  |  | 	int iMax = 0; | 
					
						
							|  |  |  | 	int qMin = 0; | 
					
						
							|  |  |  | 	int qMax = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// find value ranges for both I and Q
 | 
					
						
							|  |  |  | 	// both intervals should be same same size (for a perfect circle)
 | 
					
						
							|  |  |  | 	for (SampleVector::iterator it = begin; it < end; it++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (it != begin) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (it->real() < iMin) { | 
					
						
							|  |  |  | 				iMin = it->real(); | 
					
						
							|  |  |  | 			} else if (it->real() > iMax) { | 
					
						
							|  |  |  | 				iMax = it->real(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (it->imag() < qMin) { | 
					
						
							|  |  |  | 				qMin = it->imag(); | 
					
						
							|  |  |  | 			} else if (it->imag() > qMax) { | 
					
						
							|  |  |  | 				qMax = it->imag(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			iMin = it->real(); | 
					
						
							|  |  |  | 			iMax = it->real(); | 
					
						
							|  |  |  | 			qMin = it->imag(); | 
					
						
							|  |  |  | 			qMax = it->imag(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// sliding average (el cheapo again)
 | 
					
						
							|  |  |  | 	m_iRange = (m_iRange * 15 + (iMax - iMin)) >> 4; | 
					
						
							|  |  |  | 	m_qRange = (m_qRange * 15 + (qMax - qMin)) >> 4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 00:48:11 +01:00
										 |  |  | 	// calculate imbalance on 32 bit full scale
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	if(m_qRange != 0) { | 
					
						
							| 
									
										
										
										
											2018-01-25 00:48:11 +01:00
										 |  |  | 		m_imbalance = ((uint)m_iRange << (32-SDR_RX_SAMP_SZ)) / (uint)m_qRange; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 00:48:11 +01:00
										 |  |  | 	// correct imbalance and convert back to sample size
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	for(SampleVector::iterator it = begin; it < end; it++) { | 
					
						
							| 
									
										
										
										
											2018-01-25 00:48:11 +01:00
										 |  |  | 		it->m_imag = (it->m_imag * m_imbalance) >> (32-SDR_RX_SAMP_SZ); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::work() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-06 19:18:02 +02:00
										 |  |  | 	SampleSinkFifo* sampleFifo = m_deviceSampleSource->getSampleFifo(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	std::size_t samplesDone = 0; | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  | 	bool positiveOnly = m_realElseComplex; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while ((sampleFifo->fill() > 0) && (m_inputMessageQueue.size() == 0) && (samplesDone < m_sampleRate)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		SampleVector::iterator part1begin; | 
					
						
							|  |  |  | 		SampleVector::iterator part1end; | 
					
						
							|  |  |  | 		SampleVector::iterator part2begin; | 
					
						
							|  |  |  | 		SampleVector::iterator part2end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		std::size_t count = sampleFifo->readBegin(sampleFifo->fill(), &part1begin, &part1end, &part2begin, &part2end); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// first part of FIFO data
 | 
					
						
							|  |  |  | 		if (part1begin != part1end) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// correct stuff
 | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |             if (m_dcOffsetCorrection) { | 
					
						
							| 
									
										
										
										
											2018-02-04 10:49:13 +01:00
										 |  |  |                 iqCorrections(part1begin, part1end, m_iqImbalanceCorrection); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 			// feed data to direct sinks
 | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  | 			for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); ++it) { | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 				(*it)->feed(part1begin, part1end, positiveOnly); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// second part of FIFO data (used when block wraps around)
 | 
					
						
							|  |  |  | 		if(part2begin != part2end) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// correct stuff
 | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |             if (m_dcOffsetCorrection) { | 
					
						
							| 
									
										
										
										
											2018-02-04 10:49:13 +01:00
										 |  |  |                 iqCorrections(part2begin, part2end, m_iqImbalanceCorrection); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 			// feed data to direct sinks
 | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  | 			for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); it++) { | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 				(*it)->feed(part2begin, part2end, positiveOnly); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// adjust FIFO pointers
 | 
					
						
							|  |  |  | 		sampleFifo->readCommit((unsigned int) count); | 
					
						
							|  |  |  | 		samplesDone += count; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // notStarted -> idle -> init -> running -+
 | 
					
						
							|  |  |  | //                ^                       |
 | 
					
						
							|  |  |  | //                +-----------------------+
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoIdle() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::gotoIdle"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch(m_state) { | 
					
						
							|  |  |  | 		case StNotStarted: | 
					
						
							|  |  |  | 			return StNotStarted; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StIdle: | 
					
						
							|  |  |  | 		case StError: | 
					
						
							|  |  |  | 			return StIdle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StReady: | 
					
						
							|  |  |  | 		case StRunning: | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  | 	if (!m_deviceSampleSource) { | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 		return StIdle; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// stop everything
 | 
					
						
							| 
									
										
										
										
											2019-10-06 09:54:07 +02:00
										 |  |  | 	m_deviceSampleSource->stop(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 	for(BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); it++) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		(*it)->stop(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_deviceDescription.clear(); | 
					
						
							|  |  |  | 	m_sampleRate = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return StIdle; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoInit() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	switch(m_state) { | 
					
						
							|  |  |  | 		case StNotStarted: | 
					
						
							|  |  |  | 			return StNotStarted; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StRunning: // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
 | 
					
						
							|  |  |  | 			return StRunning; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StReady: | 
					
						
							|  |  |  | 			return StReady; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StIdle: | 
					
						
							|  |  |  | 		case StError: | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  | 	if (!m_deviceSampleSource) { | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 		return gotoError("No sample source configured"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// init: pass sample rate and center frequency to all sample rate and/or center frequency dependent sinks and wait for completion
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_iOffset = 0; | 
					
						
							|  |  |  | 	m_qOffset = 0; | 
					
						
							|  |  |  | 	m_iRange = 1 << 16; | 
					
						
							|  |  |  | 	m_qRange = 1 << 16; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 	m_deviceDescription = m_deviceSampleSource->getDeviceDescription(); | 
					
						
							|  |  |  | 	m_centerFrequency = m_deviceSampleSource->getCenterFrequency(); | 
					
						
							|  |  |  | 	m_sampleRate = m_deviceSampleSource->getSampleRate(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-25 09:10:19 +01:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::gotoInit: " | 
					
						
							|  |  |  | 	        << " m_deviceDescription: " << m_deviceDescription.toStdString().c_str() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 			<< " sampleRate: " << m_sampleRate | 
					
						
							|  |  |  | 			<< " centerFrequency: " << m_centerFrequency; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 	for (BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); ++it) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  | 		DSPSignalNotification *notif = new DSPSignalNotification(m_sampleRate, m_centerFrequency); | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  | 		qDebug() << "DSPDeviceSourceEngine::gotoInit: initializing " << (*it)->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  | 		(*it)->pushMessage(notif); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// pass data to listeners
 | 
					
						
							| 
									
										
										
										
											2017-09-17 17:35:03 +02:00
										 |  |  | 	if (m_deviceSampleSource->getMessageQueueToGUI()) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |         DSPSignalNotification* rep = new DSPSignalNotification(m_sampleRate, m_centerFrequency); | 
					
						
							| 
									
										
										
										
											2017-09-17 17:35:03 +02:00
										 |  |  |         m_deviceSampleSource->getMessageQueueToGUI()->push(rep); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return StReady; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoRunning() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::gotoRunning"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch(m_state) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 		case StNotStarted: | 
					
						
							|  |  |  | 			return StNotStarted; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StIdle: | 
					
						
							|  |  |  | 			return StIdle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StRunning: | 
					
						
							|  |  |  | 			return StRunning; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case StReady: | 
					
						
							|  |  |  | 		case StError: | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  | 	if (!m_deviceSampleSource) { | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 		return gotoError("DSPDeviceSourceEngine::gotoRunning: No sample source configured"); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::gotoRunning: " << m_deviceDescription.toStdString().c_str() << " started"; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Start everything
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  | 	if (!m_deviceSampleSource->start()) { | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 		return gotoError("Could not start sample source"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 	for(BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); it++) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  |         qDebug() << "DSPDeviceSourceEngine::gotoRunning: starting " << (*it)->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 		(*it)->start(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::gotoRunning:input message queue pending: " << m_inputMessageQueue.size(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return StRunning; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | DSPDeviceSourceEngine::State DSPDeviceSourceEngine::gotoError(const QString& errorMessage) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-11-16 02:38:21 +01:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::gotoError: " << errorMessage; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m_errorMessage = errorMessage; | 
					
						
							|  |  |  | 	m_deviceDescription.clear(); | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 	setState(StError); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	return StError; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::handleSetSource(DeviceSampleSource* source) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	gotoIdle(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 00:49:55 +02:00
										 |  |  | //	if(m_sampleSource != 0)
 | 
					
						
							|  |  |  | //	{
 | 
					
						
							|  |  |  | //		disconnect(m_sampleSource->getSampleFifo(), SIGNAL(dataReady()), this, SLOT(handleData()));
 | 
					
						
							|  |  |  | //	}
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 	m_deviceSampleSource = source; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  | 	if (m_deviceSampleSource) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 		qDebug("DSPDeviceSourceEngine::handleSetSource: set %s", qPrintable(source->getDeviceDescription())); | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 		connect(m_deviceSampleSource->getSampleFifo(), SIGNAL(dataReady()), this, SLOT(handleData()), Qt::QueuedConnection); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 		qDebug("DSPDeviceSourceEngine::handleSetSource: set none"); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::handleData() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	if(m_state == StRunning) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		work(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::handleSynchronousMessages() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     Message *message = m_syncMessenger.getMessage(); | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 	qDebug() << "DSPDeviceSourceEngine::handleSynchronousMessages: " << message->getIdentifier(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 17:33:08 +01:00
										 |  |  | 	if (DSPAcquisitionInit::match(*message)) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 		setState(gotoIdle()); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(m_state == StIdle) { | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 			setState(gotoInit()); // State goes ready if init is performed
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPAcquisitionStart::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(m_state == StReady) { | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 			setState(gotoRunning()); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPAcquisitionStop::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-08-27 10:18:17 +01:00
										 |  |  | 		setState(gotoIdle()); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPGetSourceDeviceDescription::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		((DSPGetSourceDeviceDescription*) message)->setDeviceDescription(m_deviceDescription); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPGetErrorMessage::match(*message)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		((DSPGetErrorMessage*) message)->setErrorMessage(m_errorMessage); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (DSPSetSource::match(*message)) { | 
					
						
							|  |  |  | 		handleSetSource(((DSPSetSource*) message)->getSampleSource()); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-02 01:04:49 +01:00
										 |  |  | 	else if (DSPAddBasebandSampleSink::match(*message)) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-01-02 01:04:49 +01:00
										 |  |  | 		BasebandSampleSink* sink = ((DSPAddBasebandSampleSink*) message)->getSampleSink(); | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 		m_basebandSampleSinks.push_back(sink); | 
					
						
							| 
									
										
										
										
											2018-01-02 16:25:34 +01:00
										 |  |  |         // initialize sample rate and center frequency in the sink:
 | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  |         DSPSignalNotification *msg = new DSPSignalNotification(m_sampleRate, m_centerFrequency); | 
					
						
							|  |  |  |         sink->pushMessage(msg); | 
					
						
							| 
									
										
										
										
											2018-01-02 16:25:34 +01:00
										 |  |  |         // start the sink:
 | 
					
						
							|  |  |  |         if(m_state == StRunning) { | 
					
						
							|  |  |  |             sink->start(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-02 01:04:49 +01:00
										 |  |  | 	else if (DSPRemoveBasebandSampleSink::match(*message)) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-01-02 01:04:49 +01:00
										 |  |  | 		BasebandSampleSink* sink = ((DSPRemoveBasebandSampleSink*) message)->getSampleSink(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(m_state == StRunning) { | 
					
						
							|  |  |  | 			sink->stop(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 		m_basebandSampleSinks.remove(sink); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_syncMessenger.done(m_state); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 18:29:05 +02:00
										 |  |  | void DSPDeviceSourceEngine::handleInputMessages() | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	Message* message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while ((message = m_inputMessageQueue.pop()) != 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2016-10-08 10:35:07 +02:00
										 |  |  | 		qDebug("DSPDeviceSourceEngine::handleInputMessages: message: %s", message->getIdentifier()); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (DSPConfigureCorrection::match(*message)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			DSPConfigureCorrection* conf = (DSPConfigureCorrection*) message; | 
					
						
							|  |  |  | 			m_iqImbalanceCorrection = conf->getIQImbalanceCorrection(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(m_dcOffsetCorrection != conf->getDCOffsetCorrection()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				m_dcOffsetCorrection = conf->getDCOffsetCorrection(); | 
					
						
							|  |  |  | 				m_iOffset = 0; | 
					
						
							|  |  |  | 				m_qOffset = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(m_iqImbalanceCorrection != conf->getIQImbalanceCorrection()) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				m_iqImbalanceCorrection = conf->getIQImbalanceCorrection(); | 
					
						
							|  |  |  | 				m_iRange = 1 << 16; | 
					
						
							|  |  |  | 				m_qRange = 1 << 16; | 
					
						
							|  |  |  | 				m_imbalance = 65536; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-16 01:23:49 +01:00
										 |  |  | 			m_avgAmp.reset(); | 
					
						
							|  |  |  | 			m_avgII.reset(); | 
					
						
							|  |  |  | 			m_avgII2.reset(); | 
					
						
							|  |  |  | 			m_avgIQ.reset(); | 
					
						
							|  |  |  | 			m_avgPhi.reset(); | 
					
						
							|  |  |  | 			m_avgQQ2.reset(); | 
					
						
							|  |  |  | 			m_iBeta.reset(); | 
					
						
							|  |  |  | 			m_qBeta.reset(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 			delete message; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (DSPSignalNotification::match(*message)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			DSPSignalNotification *notif = (DSPSignalNotification *) message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// update DSP values
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			m_sampleRate = notif->getSampleRate(); | 
					
						
							|  |  |  | 			m_centerFrequency = notif->getCenterFrequency(); | 
					
						
							| 
									
										
										
										
											2023-06-18 00:44:20 +02:00
										 |  |  |             m_realElseComplex = notif->getRealElseComplex(); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-04 10:49:47 +01:00
										 |  |  | 			qDebug() << "DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification:" | 
					
						
							|  |  |  | 				<< " m_sampleRate: " << m_sampleRate | 
					
						
							|  |  |  | 				<< " m_centerFrequency: " << m_centerFrequency; | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-17 00:06:09 +02:00
										 |  |  | 			// forward source changes to channel sinks with immediate execution (no queuing)
 | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 01:49:28 +02:00
										 |  |  | 			for(BasebandSampleSinks::const_iterator it = m_basebandSampleSinks.begin(); it != m_basebandSampleSinks.end(); it++) | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  | 				DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy
 | 
					
						
							| 
									
										
										
										
											2022-02-13 00:57:33 +01:00
										 |  |  | 				qDebug() << "DSPDeviceSourceEngine::handleInputMessages: forward message to " << (*it)->getSinkName().toStdString().c_str(); | 
					
						
							| 
									
										
										
										
											2022-02-12 21:41:20 +01:00
										 |  |  | 				(*it)->pushMessage(rep); | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-17 00:06:09 +02:00
										 |  |  | 			// forward changes to source GUI input queue
 | 
					
						
							| 
									
										
										
										
											2022-12-28 18:55:06 +01:00
										 |  |  |             if (m_deviceSampleSource) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 MessageQueue *guiMessageQueue = m_deviceSampleSource->getMessageQueueToGUI(); | 
					
						
							|  |  |  |                 qDebug("DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p", guiMessageQueue); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (guiMessageQueue) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     DSPSignalNotification* rep = new DSPSignalNotification(*notif); // make a copy for the source GUI
 | 
					
						
							|  |  |  |                     guiMessageQueue->push(rep); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-10-15 04:05:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			delete message; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |